I have a product catalog page. When you click on the "Add Product" button, page with a cart shows up. This page has a table with an ItemTemplate inside it. Is there any way to get the value from the textBox located inside that ItemTemplate and change the value in the column Total cost in the table by clicking the button? The main problem is that I cannot access the textBox since it's in the . Thank you.
Catalog page:
Cart page:
CartView.aspx
MasterPageFile="~/Page/Store.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="bodyContent" runat="server">
<div id="content" style="margin-left: 7%;">
<style>
#import url("/css/tableCart.css");
#import url("/css/ButtonsCart.css");
</style>
<h2 style="padding: 14px; color:Highlight;">Ваша корзина</h2>
<h3 style="padding: 14px; color:Highlight;">Товары, которые вы добавили в корзину, представлены здесь</h3>
<table id="Table1" V class ="simple-little-table">
<thead>
<tr>
<th></th>
<th>Название</th>
<th>Цвет</th>
<th>Глубина</th>
<th>Ширина</th>
<th>Цена</th>
<th>Количество</th>
<th>Итого</th>
<th></th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="Repeater1" ItemType="Line.Models.CartLine"
SelectMethod="GetCartLines" runat="server" EnableViewState="false">
<ItemTemplate>
<tr>
<td><asp:Image ID="Image1" runat="server" style="height:45px; " ImageUrl=<%# Item.Product.Img %> /></td>
<td> <%# Item.Product.NameProduct %> <%# Item.Product.TypeProducts %></td>
<td><%# Item.Product.Colors %></td>
<td>
Qty: <asp:TextBox ID="txtQty" runat="server" Width="130px" />
<asp:Button ID="cmdUpdate" OnClick="cmdUpdate_Click1" runat="server" Text="Update" CommandName="MyUpdate" CommandArgument = '<%# Container.ItemIndex %>'/>
</td>
<td><%# Item.Size.Depth%></td>
<td><%# Item.Product.Price%></td>
</td>
<td>
<td>
<asp:Label ID="Label2" runat="server" Text="<%# ((Item.Quantity *
Item.Product.Price))%>"></asp:Label>
</td>
<td>
<asp:Label ID="txtAmount" runat="server" Text=""></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
<tfoot>
<tr>
<td colspan="3">Итого:</td>
<td colspan="2" ><%= CartTotal.ToString("c") %></td>
</tr>
</tfoot>
</table>
</div>
</asp:Content>
CartView.aspx.cs
using Line.Helpers;
using Line.Models;
using Line.Models.Repository;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Line.Page
{
public partial class CartView : System.Web.UI.Page
{
protected void Page_Load(object sender, RepeaterCommandEventArgs e)
{
}
public IEnumerable<CartLine> GetCartLines()
{
return SessionHelper.GetCart(Session).Lines;
}
public decimal CartTotal
{
get
{
return SessionHelper.GetCart(Session).ComputeTotalValue();
}
}
public string CheckoutUrl
{
get
{
return RouteTable.Routes.GetVirtualPath(null, "checkout",
null).VirtualPath;
}
}
public string ReturnUrl
{
get
{
return SessionHelper.Get<string>(Session, SessionKey.RETURN_URL);
}
}
protected void cmdUpdate_Click1(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "MyUpdate")
{
RepeaterItem rRow = Repeater1.Items[Convert.ToInt32(e.CommandArgument)];
TextBox tQty = (TextBox)rRow.FindControl("txtQty");
Label tAmount = (Label)rRow.FindControl("txtAmount");
tAmount.Text = tQty.Text;
}
}
}
}
Ok, so you can set the index of the button, and pick this up in the Repeater "item command"
So, for your button, you can/want say this:
I have qty, price, and amount in the repeater. and button.
So, the markup can look like this:
Qty: <asp:TextBox ID="txtQty" runat="server" Width="130px" />
<br />
Price: <asp:TextBox ID="txtPrice" runat="server" Width="130px" />
<br />
Amount: <asp:TextBox ID="txtAmount" runat="server" Width="130px" />
<br />
<asp:Button ID="cmdUpdate" runat="server" Text="Update"
CommandName="MyUpdate"
CommandArgument = '<%# Container.ItemIndex %>'/>
So, you are now free to enter Qty, amount in any of the repeated items.
I have this:
Now, my repeater is going accross - and I think you should be using a listview since that better supports a grid + columnar layout - but it really don't mater (listview, gridview, repeater - they all work the same).
So, note how in our button we have both command Name, and command argument. In command argument I pass the row of the repeater.
So, the code looks like this:
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
// update button in repeater clicked
// update amount based on qty, and price
if (e.CommandName == "MyUpdate")
{
RepeaterItem rRow = Repeater1.Items(e.CommandArgument);
TextBox tQty = rRow.FindControl("txtQty");
TextBox tPrice = rRow.FindControl("txtPrice");
TextBox tAmount = rRow.FindControl("txtAmount");
tAmount.Text = tQty.Text * tPrice.Text;
}
}
So, just pass the "index" of the repeater row as per above. We used this expression as command argument:
<asp:Button ID="cmdUpdate" runat="server" Text="Update"
CommandName="MyUpdate"
CommandArgument = '<%# Container.ItemIndex %>'/>
So, once you have the Item Index (row index), then you can run code against the one row and change that row as per above.
Edit:
So the full markup I have is this:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div style="border-style:solid;color:black;width:250px;float:left">
<div style="padding:5px;text-align:right">
Hotel Name: <asp:TextBox ID="txtHotelName" runat="server" Text ='<%# Eval("HotelName") %>' Width="130px" />
<br />
First Name: <asp:TextBox ID="txtFirst" runat="server" Text ='<%# Eval("FirstName") %>' Width="130px" />
<br />
Last Name: <asp:TextBox ID="txtLast" runat="server" Text ='<%# Eval("LastName") %>' Width="130px" />
<br />
Qty: <asp:TextBox ID="txtQty" runat="server" Width="130px" />
<br />
Price: <asp:TextBox ID="txtPrice" runat="server" Width="130px" />
<br />
Amount: <asp:TextBox ID="txtAmount" runat="server" Width="130px" />
<br />
<asp:Button ID="cmdUpdate" runat="server" Text="Update" CommandName="MyUpdate" CommandArgument = '<%# Container.ItemIndex %>' />
<div>
City : <asp:DropDownList ID="cboCity" runat="server" DataTextField="City"
DataValueField="City" Width="110px">
</asp:DropDownList>
<div style="float:right;text-align:center;margin-left:4px;">
<asp:Button ID="cmdAddCity" runat="server" Text="+" OnClick="cmdAddCity_Click" Height="16px" Width="12px" Font-Size="XX-Small" cssclass="btnPad" OnClientClick="AddCity();return false"/>
</div>
</div>
Active: <asp:CheckBox ID="chkActive" runat="server" Checked = '<%# Eval("Active") %>'/>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
The code to load up this repeater is this:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
LoadGrid();
}
public void LoadGrid()
{
cmdSQL.Connection.Open();
strSQL = "SELECT ID, FirstName, LastName, HotelName, City, Active from tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
rstTable.Load(cmdSQL.ExecuteReader);
Repeater1.DataSource = rstTable;
Repeater1.DataBind();
}
}
so the above fills out the repeater - as noted, for a grid like layout, I would use a listview. Drag a list view into a web page.
use the wizards to connect to the database. Now blow out all the templates, only leave the itemtemplate.
Your code to load up the grid - same as above.
now, in place of the repeater as per previous screen shots?
You get this:
So your multiple lines that your building? They should be based on and around a listview. And each row can thus be grabbed, and addressed just as I did per above.
Do a google for listview examples - there is a like a billion examples.
Once you have this setup, then each row is a "thing" that repeats for you automatic based on the data from the table.
The markup for the list view - it again quite much follows the same ideas and concepts as a repeator. the listview for above looks like this:
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID">
<ItemTemplate>
<tr style="">
<td><asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' /></td>
<td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
<td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:CheckBox ID="ActiveCheckBox" runat="server" Checked='<%# Eval("Active") %>' Enabled="false" /></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table runat="server">
<tr runat="server">
<td runat="server">
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server">ID</th>
<th runat="server">FirstName</th>
<th runat="server">LastName</th>
<th runat="server">HotelName</th>
<th runat="server">City</th>
<th runat="server">Active</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</td>
</tr>
<tr runat="server">
<td runat="server" style=""></td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
Related
In past, i worked on ListViews (.net 2.0) using a custom Template field but what i am trying to achieve here is the following
I am now working on .net 4.6
So basically a list which shows items like above and on mouse-hover few options show up as shown in the following screenshot
I also have to trigger those option to do different things -
How can I do that in asp.net, may I please have some code references.
Cheers
P.S.
This is a rough example of how i am creating the List Item Template (as requested)
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1">
<AlternatingItemTemplate>
<table >
<tr>
<td ><asp:Image ID="image1" ImageUrl='<%# Bind("url") %>' runat="server" Width="98px" /> </td>
<td><h2><asp:Label ID="_label" runat="server" Text ='<%# Bind("title") %>'></asp:Label></h2><asp:Label ID="Label1" runat="server" Text ='<%# Bind("description") %>'></asp:Label></td>
</tr>
</table>
</AlternatingItemTemplate>
<EmptyDataTemplate>
No data was returned.
</EmptyDataTemplate>
<ItemSeparatorTemplate>
<br />
</ItemSeparatorTemplate>
<ItemTemplate>
<table >
<tr>
<td ><asp:Image ID="image1" ImageUrl='<%# Bind("url") %>' runat="server" Width="98px" /> </td>
<td><h2><asp:Label ID="_label" runat="server" Text ='<%# Bind("title") %>'></asp:Label></h2><asp:Label ID="Label1" runat="server" Text ='<%# Bind("description") %>'></asp:Label></td>
</tr>
</table>
</ItemTemplate>
<LayoutTemplate>
<ul id="itemPlaceholderContainer" runat="server" style="">
<li runat="server" id="itemPlaceholder" />
</ul>
<div style="">
</div>
</LayoutTemplate>
</asp:ListView>
I can add any html formatting to this template e,g i can add ASP:button etc but i don't know how to trigger those to perform certain tasks.
One easy way to achieve your requirement is to keep those buttons there but invisible and show them up when the parent container is hovered. following as a quick sample
aspx
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<tr class="row-data">
<td>
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' />
</td>
<td>
<asp:Label ID="PositionLabel" runat="server" Text='<%# Eval("Position") %>' />
</td>
<td>
<div class="btn-area">
<asp:Button runat="server" Text="Button1" />
<asp:Button runat="server" Text="Button2" />
</div>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server">
Name
</th>
<th runat="server">
Position
</th>
<th>
</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
css
.btn-area
{
display: none;
}
.row-data:hover .btn-area
{
display: block;
}
code-behind
protected void Page_Load(object sender, EventArgs e)
{
ListView1.DataSource = new List<dynamic>() {
new { Name = "Andy", Position = "PG"},
new { Name = "Bill", Position = "SD"},
new { Name = "Caroline", Position = "Manager"}
};
ListView1.DataBind();
}
UPDATE
ListView ItemCommand can capture the postback by button pressed and CommandName makes you able to recognize which button fired it.
<asp:Button runat="server" Text="Button1" CommandName="c1" />
<asp:Button runat="server" Text="Button2" CommandName="c2" />
code-behind
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "c1")
{
// do something when button1 pressed
}
else if (e.CommandName == "c1")
{
// do something when button2 pressed
}
}
I have a database which is shown below in the image :
Image of database
Here is the image of the form :
Image of the Form
In this form i want to show up the image in image control of which image path is stored up in database and according to subcategory value from the drop down list when user selects it how can i do it please help ... Thank You
Guys here is the source code of my form i have added sqldatasource and bind the dropdown list with sqldatasource .........
<form method="post" enctype="multipart/form-data">
<table border="0" width="450px" height="500px" align="center" class="tableshadow">
<tr>
<td colspan="2" class="toptd" style="color: white; font-size: 24px; text-align: center;
height: 40px; background-color: #60b2e7">
Update Subcategory
</td>
</tr>
<tr>
<td class="lefttxt">
<asp:Label ID="Label1" runat="server" Text="Select Subcategory:"></asp:Label>
</td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server" Height="35px" Width="134px" DataSourceID="SqlDataSource1"
DataTextField="subcatname" DataValueField="subcatid">
<asp:ListItem Text="Select category" Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnshow" runat="server" OnClick="btnshow_Click" Text="Show" Width="94px" />
</td>
</tr>
<tr>
<td class="lefttxt">
<asp:Label ID="Label2" runat="server" Text="Subcategory Name:"></asp:Label>
<br />
</td>
<td>
<asp:TextBox ID="txtsubcategoryname" runat="server"></asp:TextBox>
<br />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtsubcategoryname"
ErrorMessage="*Please Enter the Subcategory Name" Font-Bold="True" Font-Italic="True"
Font-Size="X-Small" ForeColor="Red"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td class="lefttxt">
<asp:Label ID="Label3" runat="server" Text="Select Category:"></asp:Label>
</td>
<td>
<asp:DropDownList ID="DLCategory" runat="server" Height="35px" Width="146px" DataSourceID="SqlDataSource1"
DataTextField="categoryname" DataValueField="categoryname">
<asp:ListItem Text="Select category" Value="0"></asp:ListItem>
</asp:DropDownList>
<tr>
<td class="lefttxt">
<asp:Label ID="Label6" runat="server" Text="Category Name:"></asp:Label>
<br />
</td>
<td>
<asp:TextBox ID="txtcategoryname" runat="server"></asp:TextBox>
<br />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtcategoryname"
ErrorMessage="*Please Enter the Category Name" Font-Bold="True" Font-Italic="True"
Font-Size="X-Small" ForeColor="Red"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td class="lefttxt">
<asp:Label ID="Label4" runat="server" Text="Old Pic:"></asp:Label>
</td>
<td>
<input type="hidden" name="h1" value="" /><asp:Image ID="Image1" runat="server" />
</td>
</tr>
<tr>
<td class="lefttxt">
<asp:Label ID="Label5" runat="server" Text="Upload New Pic:"></asp:Label>
</td>
<td>
<asp:FileUpload ID="FileUpload1" runat="server" Width="225px" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="btnupdate" runat="server" Text="Update" OnClick="btnupdate_Click" />
</td>
</tr>
</table>
</form>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ToursandTravelsConnectionString %>"
SelectCommand="SELECT [subcatid], [subcatname], [categoryname], [pic] FROM [subcategory]">
</asp:SqlDataSource>
Providing the 'pic' column in database holds links to the images are absolute, it also depends on how you have set the drop down list up.
You will need an OnSelectedIndexChanged for the drop down which does the following:
Selects the pic url from the database where subcategory = dropdown value or text. (this depends on how you set the drop-down list up).
With that obtained value set the pic to the one you have obtained.
You need the following, providing code would make it easier.
In you ASP file add the following to the dropdown:
OnSelectedIndexChanged="drp_SelectedIndexChanged" AutoPostBack="True"
Within code behind you need:
protected void drp_SelectedIndexChanged(object sender, EventArgs e) {
//SQL To obtain url for image based on drop down selection
//providing code makes this easier
//with return url:
Image1.ImageUrl = //returned url
}
Are you having issue in showing image in image control ? Can you right click on that container and check path in properties ?
You can use AutoPostBack as True and "OnSelectedIndexChanged" to call server function and update image control based on result.
Or you can use JQuery to show images in Div tag.
jQuery(document).ready(function(){
$("#dropdownID").change(function() {
$.ajax({
url: "SericeFunction name",
success: function(msg){
.....<bind img tag >
}
});
});
});
Thank You All of you guys especially #John for your syntax you provided thanks alot.. Below is the code :
protected void btnshow_Click(object sender, EventArgs e)
{
using (var cn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=D:\PROJECT SEM6\Online Tours and Travels\App_Data\ToursandTravels.mdf;Integrated Security=True;User Instance=True"))
using (var cmd = cn.CreateCommand())
{
cn.Open();
cmd.CommandText = "select pic from subcategory where subcatid = '"+DropDownList1.Text+"'";
cmd.Parameters.AddWithValue("#subcatid",DropDownList1.Text);
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
var filePath = reader.GetString(0);
// For this to work images must be stored inside the web application.
// filePath must be a relative location inside the virtual directory
// hosting the application. Depending on your environment some
// transformations might be necessary on filePath before assigning it
// to the image url.
Image1.ImageUrl =("~/"+filePath);
}
}
}
I recently switched a ComboBox in my repeater to a SuggestComboBox (found: here) because it is a contains search rather than a starts-with search. Previously, I was using NamingContainer of that ComboBox to find nearby elements. My new SuggestComboBox does not have this value but in my research on this problem, it looks like all children of a repeater should have this already?
"the NamingContainer property is available in code to any instance of that class or of a derived class." (found: here)
What am I missing?
Here's my repeater:
<asp:Repeater ID="repHW" runat="server" OnItemCommand="rep_ItemCommand">
<HeaderTemplate>
<table style="width:100%; padding-bottom:10px" id="HWtable">
<tr style="font-weight: bold"><td>Product</td><td>Part Number</td><td>Cost</td><td>Unit Price</td><td>Quantity</td><td>Price</td><td>Delete</td></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<asp:HiddenField ID="Category" Value="Hardware" runat="server"/>
<td><asp:Label ID="Product" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Product.Name") %>' /></td> <!--TODO: make this clickable to edit -->
<td><asp:Label ID="PartNumber" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Product.PartNumber") %>' /></td>
<td><asp:Label ID="PartCost" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Product.Cost") %>' /></td>
<td><asp:Label ID="UnitPrice" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Product.Price") %>' /></td>
<td><asp:Label ID="Quantity" runat="server" Text='<%# Eval("Quantity") %>' /></td>
<td><asp:Label ID="Price" runat="server" Text='<%# Eval("Total") %>' /></td>
<td><asp:Button class="btn btn-danger" ID="DeleteHardware" runat="server" Text="Delete" CommandName="Delete" CommandArgument='<%# Container.ItemIndex %>'/></td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr>
<asp:HiddenField ID="AddCategory" Value="Hardware" runat="server"/>
<td><SuggestComboBox runat="server" ID="AddProduct" AutoCompleteMode="SuggestAppend" AutoPostBack="true" OnSelectedIndexChanged="ProductSelected" OnDataBinding="LoadHardwareProducts"/></td>
<td><asp:TextBox runat="server" ID="AddPartNumber" ClientIDMode="static"/></td>
<td><asp:TextBox runat="server" ID="AddPartCost" ClientIDMode="static"/></td>
<td><asp:TextBox runat="server" ID="AddUnitPrice" ClientIDMode="static"/></td>
<td><asp:TextBox runat="server" ID="AddQuantity" ClientIDMode="static"/></td>
<td><asp:Button class="btn btn-success" ID="AddHardware" runat="server" Text="Add" CommandName="Add" CommandArgument='<%# Container.ItemIndex %>' onClientClick="return EmptyFieldCheck('Hardware');"/></td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
and here's my function I am trying to access the other elements in:
protected void ProductSelected(Object source, EventArgs e)
{
SuggestComboBox temp = (SuggestComboBox)source;
List<Product> results = session.Query<Product>()
.Where(x => x.Name == temp.Text)
.ToList();
if(results.Count > 0)
{
Product p = results[0];
var repParent = temp.NamingContainer; //this broke
TextBox partNum = (TextBox)repParent.FindControl("AddPartNumber");
TextBox partCost = (TextBox)repParent.FindControl("AddPartCost");
TextBox unitPrice = (TextBox)repParent.FindControl("AddUnitPrice");
TextBox quantity = (TextBox)repParent.FindControl("AddQuantity");
partNum.Text = p.PartNumber;
partCost.Text = p.Cost.ToString();
unitPrice.Text = p.Price.ToString();
quantity.Text = p.DefaultQuantity.ToString();
}
}
It seems I have had a lot of questions today.
What i want to do is save the text for each image.
I'm getting the right text for each picture into the textboxes at the moment.
The code behind:
var car = GarageBLL.LoadCar(Convert.ToInt32(CarId),
Convert.ToInt32(_memberId)); ImageRepeater.DataSource = car.Images;
ImageRepeater.DataBind();
protected void FinalizeNewCar(object sender, EventArgs e) {
Response.Redirect("/amcargarasjen"); }
**Code here for saving each edit into the right ImageId.**
ASP:
<asp:Repeater runat="server" ID="ImageRepeater">
<ItemTemplate>
<table>
<tr>
<td>
<a class="deleteLink" href="#" rel="<%#Eval("ImageId")%>" title="">
<asp:Image runat="server" ImageUrl="/Content/Images/Garage/DeleteButton.png" /></a>
<asp:Image Width="60" Height="45" ID="ImgCar" ImageUrl='<%# String.Format("/garageimages/{0}/{1}.{2}", CarId, Eval("ImageId"), Eval("Extension")) %>' runat="server" />
<asp:TextBox runat="server" Text='<%# Eval("Description") %>' ID="txtText"></asp:TextBox>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Button ID="Button1" runat="server" Text="Fullfør" OnClick="FinalizeNewCar" />
Anyone got any ideas on how to do that?
Modify your Repeater HTML markup like below. Note the addition of a Hidden field to keep the reference of the current image ID.
<asp:Repeater runat="server" ID="ImageRepeater">
<ItemTemplate>
<table>
<tr>
<td>
<a class="deleteLink" href="#" rel="<%#Eval("ImageId")%>" title="">
<asp:Image runat="server" ImageUrl="/Content/Images/Garage/DeleteButton.png" /></a>
<asp:Image Width="60" Height="45" ID="ImgCar" ImageUrl='<%# String.Format("/garageimages/{0}/{1}.{2}", CarId, Eval("ImageId"), Eval("Extension")) %>' runat="server" />
<asp:TextBox runat="server" Text='<%# Eval("Description") %>' ID="txtText"></asp:TextBox>
<asp:HiddenField runat="server" Value='<%# Eval("ImageId") %>' ID="txtImageId"></asp:TextBox>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Button ID="Button1" runat="server" Text="Fullfør" OnClick="FinalizeNewCar" />
CODE FinalizeNewCar Event Handler
protected void FinalizeNewCar(object sender, EventArgs e)
{
foreach (RepeaterItem item in ImageRepeater.Items)
{
Int32 imageId = Convert.ToInt32(((HiddenField) item.FindControl("txtImageId")).Value);
string description = ((TextBox)item.FindControl("txtText")).Text;
//You will get the imageId description here.
//Write your code to update the datatbase.
}
}
I am using listview to display a list of items and a nested listview to show list of features to each item. Both parent and child listview need to able Insert,Edit and delete operation. It works fine for parent listview. But when I try to edit an child item, The edit button does not take it into Edit mode. Can you please suggest me what I am missing in my code?
<asp:ListView ID="lvParent" runat="server"
OnItemDataBound="lvParent_ItemDataBound"
onitemcanceling="lvParent_ItemCanceling" onitemcommand="lvParent_ItemCommand"
DataKeyNames="ItemID" onitemdeleting="lvParent_ItemDeleting"
oniteminserting="lvParent_ItemInserting" >
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
<div align="right">
<asp:Button ID="btnInsert" runat="server" Text="ADD Item" onclick="btnInsert_Click"/>
</div>
</LayoutTemplate>
<ItemTemplate>
<table runat="server" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td>
<div id="dvDetail">
<span >Description</span>
<asp:TextBox ID="txtDescription" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Description") %>' TextMode="MultiLine" ></asp:TextBox>
</div>
<div id="dvFeature" >
<span>Feature List</span>
<asp:ListView ID="lvChild" runat="server"
InsertItemPosition="LastItem"
DataKeyNames="FeatureID" OnItemCommand="lvChild_ItemCommand"
OnItemCanceling="lvChild_ItemCanceling" OnItemDeleting="lvChild_ItemDeleting"
OnItemEditing="lvChild_ItemEditing" OnItemInserting="lvChild_ItemInserting" OnItemUpdating="lvChild_ItemUpdating"
DataSource='<%# DataBinder.Eval(Container.DataItem, "FeatureList") %>' >
<LayoutTemplate>
<ul >
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" ></asp:PlaceHolder>
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<span class="dvList"><%# DataBinder.Eval(Container.DataItem, "FeatureTitle")%></span>
<div class="dvButton" >
<asp:ImageButton ID="btnEdit" runat="server" ImageUrl="/Images/edit_16x16.gif" AlternateText= "Edit" CommandName="Edit" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" />
<asp:ImageButton ID="btnDelete" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Delete" CommandName="Delete" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" />
</div>
</li>
</ItemTemplate>
<EditItemTemplate>
<li>
<asp:TextBox ID="txtFeature" Text='<%# DataBinder.Eval(Container.DataItem, "FeatureTitle")%>' runat="server"></asp:TextBox>
<div class="dvButton">
<asp:ImageButton ID="btnUpdate" runat="server" ImageUrl="/Images/ok_16x16.gif" AlternateText= "Update" CommandName="Update" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" />
<asp:ImageButton ID="btnCancel" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Cancel" CommandName="Cancel" Width="12" Height="12" CausesValidation="false" />
</div>
</li>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtFeature" runat="server"></asp:TextBox>
<div class="dvButton">
<asp:ImageButton ID="btnInsert" runat="server" ImageUrl="/Images/ok_16x16.gif" AlternateText= "Insert" CommandName="Insert" Width="12" Height="12" />
<asp:ImageButton ID="btnCancel" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Cancel" CommandName="Cancel" Width="12" Height="12" CausesValidation="false" />
</div>
</InsertItemTemplate>
</asp:ListView>
</div>
</td>
</tr>
<tr>
<td align="right">
<div id="dvButton" >
<asp:Button ID="btnSave" runat="server" Text="Save"
CommandName="Save"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "ItemID") %>' />
<asp:Button ID="btnDelete" runat="server" Text="Delete" CssClass="Cancel"
CommandName="Delete"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "ItemID") %>' />
</div>
</td>
</tr>
</table>
</ItemTemplate>
</asp:ListView>
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == false)
{
BindData();
}
}
private void BindData()
{
MyDataContext data = new MyDataContext();
var result = from itm in data.ItemLists
where itm.ItemID == iItemID
select new
{
itm.ItemID,
itm.Description,
FeatureList = itm.Features
};
lvParent.DataSource = result;
lvParent.DataBind();
}
protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView lvChild = sender as ListView;
lvChild.EditIndex = e.NewEditIndex;
lvChild.DataBind();
}
Edit:
protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView lvChild = sender as ListView;
lvChild.EditIndex = e.NewEditIndex;
lvChild.DataBind();
}
If I use "lvChild.DataBind()" in 'ItemEditing' event, the total list of child items goes away if I click 'edit'
protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView lvChild = sender as ListView;
lvChild.EditIndex = e.NewEditIndex;
}
if I get rid of 'lvChild.Databind' in ItemEditing event, it goes to Edit mode after clicking the 'edit' button twice . And though it shows textbox control of EditItemTemplate, it appears as a blank textbox (does not bind existing value to edit).
This is an interesting problem. Almost certainly a databinding issue. In order to enter edit mode you must do two things:
1) Set the EditIndex
2) Call DataBind()
In the case of nested repeaters though... when does Render get called? I suspect you will have to call DataBind() on the PARENT in order to render everything correctly. That being the case you may have to then set the EditIndex AGAIN, since you are rebinding the parent.
EDIT:
OK... I just tried this with a nested GridView and I did NOT have to DataBind() the parent to get the sub grid to enter edit mode. Now I have to downvote my own answer. :|
hope that will serve someone, somewhere.
Here is my code to get that to work:
1) I have a Listview wich hold a user control when editing. This User cotnrol has itself a listview inside
<asp:ListView runat=server ID=C_LV_MyObjects DataKeyNames="Id"
OnItemDataBound=DataBoundMyObjects OnItemEditing=ItemEditing
>
<LayoutTemplate>
<table runat=server id="itemPlaceholderContainer">
<tr>
<th>
Description
</th>
</tr>
<tr runat="server" id="itemPlaceholder">
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
text...
</td>
<td>
<asp:LinkButton runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
</td>
<td>
<asp:LinkButton runat="server" CommandName="Delete" Text="Delete"></asp:LinkButton>
</td>
</ItemTemplate>
<EditItemTemplate>
<tr>
<td colspan=3>
<MyTag:MyUC ID=C_UC_MyUserControl runat=server
OnEditing=MyObjectEditing
/>
</td>
</tr>
</EditItemTemplate>
<EmptyDataTemplate>
No results found!
</EmptyDataTemplate>
</asp:ListView>
The code c# for this listview is as follows :
public int EditIndexComposition;
protected void ItemEditing(object sender, ListViewEditEventArgs e)
{
C_LV_MyObjects.EditIndex = e.NewEditIndex;
C_LV_MyObjects.DataBind();
}
protected void MyObjectEditing(object sender, EventArgs e)
{
ListViewEditEventArgs MyEvent = (ListViewEditEventArgs)e;
if (MyEvent != null)
EditIndexComposition= MyEvent.NewEditIndex;
C_LV_MyObjects.DataBind();
}
protected void DataBoundMyObjects(object sender, ListViewItemEventArgs e)
{
MyUC uc = (MyUC)e.Item.FindControl("C_UC_MyUserControl");
if (uc!=null)
{
uc.EditIndex = EditIndexComposition;
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
MyObject obj= (MyObject)dataItem.DataItem;
uc.DataSource=Myservice.GetDatasource(obj.Id);
uc.DataBind();
}
}
and the code of my Usercontrol is as follows :
<asp:PlaceHolder runat="server" ID="C_PH_ObjComposition">
<asp:ListView runat="server" ID="C_LV_AppaltatoreComposizione" DataSource="<% # DataSource %>"
DataKeyNames="Id" OnItemEditing="ItemEditing">
etc...
<ItemTemplate>
<tr>
<td>
<asp:LinkButton runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr>
<td>
Edit Mode
</td>
</tr>
</EditItemTemplate>
</asp:ListView>
</asp:PlaceHolder>
with the following code c# :
public int EditIndex
{
get {return C_LV_ObjComposition.EditIndex;}
set { C_LV_ObjComposition.EditIndex=value;}
}
public event EventHandler Editing;
protected void ItemEditing(object sender, ListViewEditEventArgs e)
{
C_LV_ObjComposition.EditIndex = e.NewEditIndex;
if (Editing != null)
Editing(this, e);
}
When clicking on the edit button of the innerlistview, we store the index that was clicked and we trigger a function in the first container user control. This function is going to store in a global value the index cliked and triggers a databind of the outter list. Doing so we get the onitemdatabound, that will recreate our usercontrol with the proper values, we can then before the databinding of the usercontrol assign the index of the editing row.
That's all if you have any questions , please feel free to answer..
ciao!