Ben Parsell
Ben Parsell

Reputation: 75

Populating a Dropdown list, uniquely, within a repeater

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

Answers (2)

VDWWD
VDWWD

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

Joel Coehoorn
Joel Coehoorn

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

Related Questions