ASP, Use duplicate values in DropDownList

EE,

I need to have some duplicate Values in my dropdownlist (for look up purposes).  I expected the control to operate on the Index, however it appears to be operating on Value instead???  If this is how dropdownlists work how do I accomplish this functionality??

Thank You
Sam

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ddlDupValues.aspx.cs" Inherits="WebApplication1.Debug.ddlDupValues" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="ddl" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ddl_SelectedIndexChanged"></asp:DropDownList>
        <br/>Selected Index:<asp:Label ID="lblIndex" runat="server" Text="zls"></asp:Label>
        <br/>Selected Value:<asp:Label ID="lblValue" runat="server" Text="zls"></asp:Label>
        <br/>Selected Text:<asp:Label ID="lblText" runat="server" Text="zls"></asp:Label>
    </div>
    </form>
</body>
</html>

Open in new window


using System;
using System.Web.UI.WebControls;

namespace WebApplication1.Debug
{
    public partial class ddlDupValues : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ddl.Items.Insert(0, new ListItem("0_text", "0_value"));
                ddl.Items.Insert(1, new ListItem("1_text", "1_value"));
                ddl.Items.Insert(2, new ListItem("2_text", "2_value"));
                ddl.Items.Insert(3, new ListItem("3_text", "2_value"));
                ddl.Items.Insert(4, new ListItem("4_text", "3_value"));
                ddl.Items.Insert(5, new ListItem("5_text", "3_value"));
                ddl.Items.Insert(6, new ListItem("6_text", "3_value"));
                ddl.Items.Insert(7, new ListItem("7_text", "4_value"));
            }
        }
        protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
        {
            lblIndex.Text = ddl.SelectedIndex.ToString();
            lblValue.Text = ddl.SelectedValue;
            lblText.Text = ddl.SelectedItem.Text;
        }
    }
}

Open in new window

SamCashAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
This might be a very silly question but how does a user know which is the 'correct' one to select when two or more options are identical to the user ?  (= ****BAD**** design)
Alexandre SimõesManager / Technology SpecialistCommented:
First thing is to remember that ASP.net dropdown lists render <select> controls client side.
So knowing this, your select will be something like:
<select>
    <option value="1">Item 1</option>
    <option value="2">Item 2</option>
    <option value="3">Item 3</option>
    <option value="3">Item 4</option>
    <option value="3">Item 5</option>
    <option value="2">Item 6</option>
    <option value="2">Item 7</option>
</select>

Open in new window

And <select> controls use the value attribute to... eh... set the value, it's not by index.
So in fact, you can have duplicate value sin the list, it doesn't matter, it will always take the value associated with the selected <option>.

So, what's your problem exactly?
From here, everything looks good.
SamCashAuthor Commented:
Andy,
Alexandre,

Thanks for the comments.

I showed the "Index" field in my sample to facilitate this discussion and highlight the problem.

Andy, I believe the webpage renders "Text" field not the "Value" Field, there are no duplicates in the "Text" field (the duplicates are in the "Value" field, so no confusion to the user.

Alexandre,  Yes that is what the code behind generates.  The problem is...

click ------- index ----- value ----- returns ---- index ------ value ------- selected text
0_text ---- 0 ------------0_value -- returns ----- 0 ------------ 0_value --- 0_text --- as expected
1_text ---- 1 ------------1_value -- returns ----- 1 ------------ 1_value --- 1_text --- as expected
2_text ---- 2 ------------2_value -- returns ----- 2 ------------ 2_value --- 2_text --- as expected
3_text ---- 3 ------------2_value -- returns ----- 2 ------------ 2_value --- 2_text --- error
4_text ---- 4 ------------3_value -- returns ----- 4 ------------ 3_value --- 4_text --- as expected
5_text ---- 5 ------------3_value -- returns ----- 4 ------------ 3_value --- 4_text --- error
6_text ---- 6 ------------3_value -- returns ----- 4 ------------ 3_value --- 4_text --- error
7_text ---- 7 ------------7_value -- returns ----- 7 ------------ 7_value --- 7_text --- as expected

row 3 error, the value is correct, but the index and text are wrong, s/b 3 and 3_text
row 5 error, the value is correct, but the index and text are wrong, s/b 5 and 5_text
row 6 error, the value is correct, but the index and text are wrong, s/b 6 and 6_text

I believe the only reason the values are correct is because the values are duplicate.  It appears the value is used as the key instead of the index.  It always sends the first value when there are duplicate values along with it's associated index and text, which is not correct.  You can see this behavior in the sample.  If you click 3_text it will return row 2 (index 2, value 2_value, and 2_text).

If you look at the EventArgs e you will see the code behind is getting the wrong index and text, so I can't see how the code behind could know which row was actually clicked.  I realize a work around is to make the value and text fields the same and then look up he correct values in a table. I am hoping there is a property I can set to make the dropdown use index as its key instead of the value field or something else, or see what I am missing.

A practical example, text and value field pairs where duplicate values would exist.
TV Dinners
Turkey, 3.59
Chicken, 3.59
Steak, 4.99

Timezones
CST, -6:00
Canada Central Time, -6:00
Central Standard Time(Mexico), -6:00

These all return the correct value to the code behind but when re-rendered the wrong text is selected.

Thanks again for your assistance on this issue.
Sam
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

AndyAinscowFreelance programmer / ConsultantCommented:
re duplicates, OK that isn't so bad from a design point of view if the user is presented with distinct choices.  (I'm just puzzled what the duplicate - hidden - value with a unique text is?  It must make sense to you.)
SamCashAuthor Commented:
Andy,

Right now I have a dropdown list with timezonenames mined from a pc and mac (more to come).  The TimezoneNames make sense to the most users but the TimezoneOffset (-08:00 etc) may not.  Microsofts TimeZoneInfo enumerates many TimezoneNames for the same TimezoneOffset.  The Mac does the same.

I want the user to click on the familiar TimezoneName (Pacific Standard Time, PC or PST, Mac) and have the CORRECT (the one the user clicked) TimezoneName and TimezoneOffset returned to the codebehind.

I hope this helps.  I have wanted to do this elsewhere, but found a different ways to accomplish the functionally without using dropdowns.  I t would be alot easier if I could use the dropdown in this instance due to the differences in what the different os's return for TimezoneNames.

Thanks Again
Sam
AndyAinscowFreelance programmer / ConsultantCommented:
Aha, that makes sense.
Would it be of use that you had a class with extra info:  a unique ID (you create), the time offset and the timezone name.  Then you display the name but have the ID behind the scenes in the dropdown, so from the selected item you get the unique ID then from which you can then get the time offset.
SamCashAuthor Commented:
Andy,

Yes that would work, but I am trying not to make another round trip to IIS and SQL.  When the page is first loaded, I have a JavaScript function that gets the TimezoneName from the client (whether it be PC or Mac) with that TimezoneName JavaScript picks the selected item.  This gets them their local timezone as a default (they may select a different one)  they also pick other parameters before finally submitting.  The code behind processes this data with the selected TimezoneName and Offset,

Thanks for your assistance
Sam
David Johnson, CD, MVPOwnerCommented:
There is no Canada Central Time or US Eastern Standard Time (saw this in another question) it is simply Central Standard Time (CST) and Eastern Standard Time (EST)
Alexandre SimõesManager / Technology SpecialistCommented:
Well, wrapping up everything that has been said, the ID proposal of @AndyAinscow is the way to go, but it doesn't have to be a meaningless numeric identifier, you can build your own ID based on the info you have. After all, this value is a String.

So your problem is that you have duplicate key values and when you set a value, the control pick the first it finds for that key, not necessarily the one that the user chose.

The solution can be to create a key that is the concatenation of the text and the value and deal with the split server-side.
Picking your example, and using a semicolon as the separator, it would be something like:
ddl.Items.Insert(0, new ListItem("0_text", "0_text;0_value"));
ddl.Items.Insert(1, new ListItem("1_text", "1_text;1_value"));
ddl.Items.Insert(2, new ListItem("2_text", "2_text;2_value"));
ddl.Items.Insert(3, new ListItem("3_text", "3_text;2_value"));
ddl.Items.Insert(4, new ListItem("4_text", "4_text;3_value"));
ddl.Items.Insert(5, new ListItem("5_text", "5_text;3_value"));
ddl.Items.Insert(6, new ListItem("6_text", "6_text;3_value"));
ddl.Items.Insert(7, new ListItem("7_text", "7_text;4_value"));

Open in new window

Server-Side, when you get the selected value you just need to split it by semicolon, get the right end side and store it.
Of course, when you need to set a value you need to redo the concatenation so that it can be found in the list.

This is an acceptable solution for me if you keep this logic at the view level. Data layers should know nothing about this as this is a pure UI problem.

Also like this, you also avoid the problem you mentioned of having to query the DB again by ID.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
SamCashAuthor Commented:
Thanks all,

Hope everyone had a great Thanksgiving.  Sorry for the "neglected" I got all last week off and where I went had no computers or cell phones!

So, I built a table with the first column as the TimezoneName from various sources (PC and MAC, David the two os,s return different results when the client queries either the list of TimezoneNames or the TimezoneName appended to Date();).  I am using this first column as the logical KEY, all unique,  and is the "Text" of the dropdown.  A second column is the TimezoneOffset, (-08:00:00) has duplicates, is the "Value" of the dropdown.  One example of usage, a small javascript function is fired on "<body onload>" and not a "postback".  The function gets the ClientTimezoneName from the client, parses the TimezoneName from var d = new Date().toString(); and selects BY TEXT,
ddl.options[i].text == ClientTimezoneName

Open in new window

, NOT BY VALUE.  This works on the 4 main browsers on MAC or PC.  This gives the desired result without hitting IIS or SQL a second time.

Thanks for all your assistance
Sam
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.