Reputation: 2227
I have the below code
namespace WebApplication3
{
public partial class WebForm2 : System.Web.UI.Page
{
class Customer
{
public Customer(int id, string fName)
{
ID = id;
FirstName = fName;
}
public int ID { get; set; }
public string FirstName { get; set; }
}
private List<Customer> GetCustomerNames()
{
// Add Customers to list - this is essentially coming from a database
List<Customer> Names = new List<Customer>();
Names.Add(new Customer(1, "Name 1"));
Names.Add(new Customer(2, "Name 2"));
Names.Add(new Customer(3, "Name 3"));
Names.Add(new Customer(4, "Name 4"));
return Names;
}
private void DropdownNames()
{
// Set the dropdown
ddlName.DataSource = GetCustomerNames();
ddlName.DataTextField = "FirstName";
ddlName.DataValueField = "ID";
ddlName.DataBind();
}
private void SetNameHTML(List<Customer> Names)
{
// The below code would set the literal control with the values coming from the list along with custom span so the design would be correct
Int32 Count = 0;
lit1.Text = string.Empty;
foreach (Customer c in Names)
{
if (Count == 0)
{
// IF first element then set active class so correct style is applied
lit1.Text += string.Format("<span class='square active' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", c.FirstName, c.ID);
spName.InnerText = c.FirstName;
}
else
{
// Other non selected items - Note no active listed in the class
lit1.Text += string.Format("<span class='square' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", c.FirstName, c.ID);
}
Count += 1;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DropdownNames();
SetNameHTML(GetCustomerNames());
}
}
protected void ddlName_SelectedIndexChanged(object sender, EventArgs e)
{
// Get customer names again as the list would be empty if the SetNameHTML is removed
var CustomerNames = GetCustomerNames();
SetNameHTML(CustomerNames);
// Get a single customer to set the correct class (square active)
var CustName = CustomerNames.Where(cid => cid.ID == Convert.ToInt32(ddlName.SelectedValue)).FirstOrDefault();
spName.InnerText = ddlName.SelectedItem.Text;
// += on lit1.Text so that the span list is not empty.
// If i remove the lin SetNameHTML(CustomerNames); above then the list is empty
lit1.Text = string.Format("<span class='square active' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", CustName.FirstName, CustName.ID);
}
}
}
ASPX code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<span class="info" runat="server" id="spName"></span>
<asp:DropDownList ID="ddlName" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlName_SelectedIndexChanged"></asp:DropDownList>
<br />
<div class="squares">
<asp:Literal ID="lit1" runat="server"></asp:Literal>
</div>
</div>
</form>
</body>
</html>
I'm using the literal control so i can add the relevant span depending on the number of names found. Please note ive stripped out majority of the CSS JS which is why it may look plain.
When i select an item from the dropdown it adds the item again (if you run the above code you will know what i mean)
Note my comments and why i have done what i have.
Heres the view source of when the page loads and then once i select an item
Load
<div class="squares">
<span class='square active' ID='spName' runat='server' data-value='Name 1'>1</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 2'>2</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 3'>3</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 4'>4</span> <br />
</div>
First item selected
<div class="squares">
<span class='square active' ID='spName' runat='server' data-value='Name 1'>1</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 2'>2</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 3'>3</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 4'>4</span> <br />
<span class='square active' ID='spName' runat='server' data-value='Name 2'>2</span> <br />
</div>
I know why this is happening but im not sure how to go about this. What i want to do is not add the selected item to the list again but since im using a literal control i dont know how to remove it or if there is a better way to go about this?
Upvotes: 0
Views: 640
Reputation: 73721
You can replace the Literal control by a PlaceHolder:
<asp:PlaceHolder ID="ph1" runat="server" />
And add ASP.NET Label controls in it, which are rendered as span
elements in the HTML output, or ASP.NET Panel controls, which are rendered as div
elements.
That way, you will work with controls instead of inserting raw HTML code in a Literal, which is more difficult to manage.
UPDATE
The new Labels must be added to the PlaceHolder on each postback, not inside an if (!IsPostBack)
conditional block. Each ID must also be unique (or you can leave the ID property empty). I mention it because I see several span
elements with the ID spname
in your markup sample.
In a simple case, it would look like this:
private int labelSuffix = 0;
protected void Page_Load(object sender, EventArgs e)
{
Label lbl = new Label();
lbl.ID = string.Format("span_{0}", labelSuffix++);
lbl.Attributes.Add("data-value", "Name 1");
lbl.CssClass = "square";
lbl.Text = "1";
ph1.Controls.Add(lbl);
...
}
The Label can then be retrieved in another event handler:
protected void btnPostBack_Click(object sender, EventArgs e)
{
// By the ID of the control
Label lbl = ph1.FindControl("MyLabel") as Label;
lbl.Text = "With some new text";
// Or by looping on the controls collection
foreach (Label lbl in ph1.Controls)
{
lbl.Text = "And another text";
}
}
Upvotes: 1
Reputation: 3800
Before adding value (or on change event) check if it doesn't exist like
if (!ddlName.Items.Contains("ValueToAdd"))
{//add value in dropdown list}
Hope this helps
Upvotes: 0