Reputation: 75
I'm building a catalog page for a shopping cart setup, and on that page I'm using a repeater to display each product and its data. I'd like to use a Dropdown to display from 0, up to the Product's Quantity on hand, which would make each DDL unique to the product it is associated with on the page.
I cannot seem to figure out a way to Bind the DDL in a way to do this, only have seen how to bind all of them within the repeater's ItemDataBound method.
Edit:
My Web Form
<asp:Repeater ID="rptProducts" runat="server" OnItemDataBound="rptProducts_ItemDataBound">
<ItemTemplate>
<div class="col-md-8 col-md-offset-2 product">
<img src="<%# Eval("ImageFile") %>" class="col-xs-12" alt="<%# Eval("Name") %> Product Image" />
<h3><%# Eval("Name") %></h3>
<p><%# Eval("ShortDescription") %></p>
<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
</div>
</ItemTemplate>
</asp:Repeater>
My ItemDataBound (found from another thread, here)
protected void rptProducts_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DropDownList ddl = (DropDownList)e.Item.FindControl("DropDownList1");
foreach(var prod in ProductsList)
{
ddl.Items.Add(new ListItem(prod.QuantOnHand.ToString(), prod.QuantOnHand.ToString()));
}
}
I'm obviously not using the ItemDataBound correctly (haven't ever used it, actually), because this binding is just adding every quantity to every dropdown list.
Upvotes: 1
Views: 159
Reputation: 35514
This is the easiest way to fill a DropDownList in the ItemDataBound method. In this snippet productQuantity
comes from the Repeater source data. But you can execute a database call to get the correct quantity also. Then you need an ID which you can get like this: productQuantity = Convert.ToInt32(item["ID"]);
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DropDownList ddl = (DropDownList)e.Item.FindControl("DropDownList1");
//the product quantity variable
int productQuantity = 0;
//cast the repeater item back to a datarowview
DataRowView item = e.Item.DataItem as DataRowView;
//or if a List<objects> is bound, cast it back to it's class
//MyClass item = e.Item.DataItem as MyClass
//get the quantity from the repeater source item to fill the ddl
productQuantity = Convert.ToInt32(item["quantity"]);
//add the items to the ddl
for (int i = 0; i < productQuantity; i++)
{
ddl.Items.Add(new ListItem() { Text = i.ToString(), Value = i.ToString() });
}
//add a listitem to the ddl at position 0
ddl.Items.Insert(0, new ListItem() { Text = "Select Quantity", Value = "" });
}
Upvotes: 1
Reputation: 415735
This sounds like a job for a Custom Control to me, where you have an int
property named Quantity
, and use that in the the Render()
method to write out the html option elements.
Here is a simplified version. Your final code will want to handle (at least) name
and ID
values:
[ToolboxData("<{0}:QuantityDropDown runat=\"server\"></{0}:QuantityDropDown >")]
public class QuantityDropDown : Control
{
public int Quantity {
get { return (int)(ViewState["Quantity"] ?? default(int)); }
set {ViewState["Quantity"] = value;}
}
protected override void Render (HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Select);
for (int i=0; i < Quantity; i++)
{
writer.AddAttribute("value", i);
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write(i.ToString());
writer.RenderEndTag();
}
writer.RenderEndTag();
writer.WriteLine();
}
}
Then you can include an instance of this control as part of your Repeater markup.
<asp:Repeater ID="Repeater1" runat="server" ... >
<ItemTemplate>
<div class="col-md-8 col-md-offset-2 product">
<img src="<%# Eval("ImageFile") %>" class="col-xs-12" alt="<%# Eval("Name") %> Product Image"/>
<h3><%# Eval("Name") %></h3>
<p><%# Eval("ShortDescription") %></p>
<cc:QuantityDropDown ID="ItemQuantity" runat="server" Quantity='<%# Eval("Quantity")' />
</div>
</ItemTemplate>
</asp:Repeater>
Upvotes: 1