views:

36

answers:

3

Once upon a time, I had a DropDownList with Options built using this code:

<%= Html.DropDownList("SomeName", someSelectList)%>

which produced HTML like this:

<select id="SomeName" name="SomeName">
<option>ABC</option>
<option>DEF</option>
<option>GHI</option>
<option>JKL</option>
</select>

Form Submission would always return one of the above options to my class's public member "SomeName" via ModelBinding. My internal validation code would then select the correct numerical value from an internal Dictionary. Life was good.

Then I was asked to show the numerical values as they were being selected via Javascript/JQuery in a separate Textbox. So now I have the following options:

<select id="SomeName" name="SomeName">
<option value="50">ABC</option>
<option value="10">DEF</option>
<option value="25">GHI</option>
<option value="10">JKL</option>
</select>

and the following JQuery code:

$(document).ready(function() {
    $('#SomeName').change(function() {
        $("input#someNumber").val($('#SomeName').val());
    });
});

User selects the String and is shown the numerical value in the box. Great.

The problem now is that when the Form is Submitted, the Model Binding gets the numerical Value (eg. 50) rather than the String (eg. ABC)

How do I over-ride this behavior and get the selected String again?

+2  A: 

When a form is posted, the value of the selected option is always posted back. To get the text of the option, you'll need a server-side lookup table to match numeric values with names. Alternately, you can change your select back to how it was originally and have a lookup table in JavaScript land to show the numeric value rather than placing value attributes on your options.

Jacob
Wow. That's pretty crappy. well, thanks for cluing me in. Anyway.. I can't do the server-side thing because (as shown in my original post above) the numerical values aren't unique. I'll have to go the 2nd route have another lookup table and have Javascript manipulate that.
Pretzel
+1  A: 

Pretzel - try:

$("#SomeName option:selected").text();

in fact, the combo of the above and $("#SomeName").val(); should give you everything you need.

cheers...

jim
I thought about this and it generally works if Javascript is enabled on the browser, but I'm operating under the assumption that javascript might be broken.
Pretzel
i'm confused. i thought this issue arose out of the 'new' requirement to '...show the numerical values as they were being selected via Javascript/JQuery' - doh :)
jim
if javascript were assumed, you'd have a whole raft of options. i know we talk about progressive enhancement but some things can regressively paint you into a corner unless some minimum 'term of use' is put in place. i know this the hard way as i had to mandate javascript as a requirement for a site that we are working on just now as the functionality was just getting too restrictive to contain inside the 'no js' box. of course, your case may vary (and nice one if it does) but in our case, we showed too many jquery goodies for the stakeholders to ignore :)
jim
yeah, well, I'm a bit of a n00b when it comes to modern web 2.0 development. So I'm still figuring out what's realistic and what isn't. I've been told to operate under the assumption that Javascript will most likely work, but if it doesn't, then the app better degrade gracefully. Ergo, I can't rely on JS to populate fields for the user.
Pretzel
that's fair enough. in that case, a 'side' suggestion may be to code the value of the select with both relevant data values and parse them at the server side. so something like <option value="25#GHI">GHI</option> might be the way to go. tho of course, you'd then have to parse the number out for the textbox to display to the js enabled users (tho this still has me baffled i.e. that special priviledge is given in terms of displaying in the textbox). i'll follow this thread to see how you solve it as it's an unusual scenario. all the best again- jim
jim
Jim: You'll be pleased to know that I ended up going this route. It works fine as loog as Javascript is enabled and running fine which I think will be 99.9% of the time. I'll figure out how to degrade gracefully one day, but not today. Thanks again!
Pretzel
Btw, I considered your last suggestion of parsing out the values, but that seems like an ugly hack. Still, I'm sure we've all committed worse programming crimes than that... ;)
Pretzel
pretzel - nice stuff. btw, remember to include the <noscript> tags in your template. i'll detail in a new message exactly what i do in this respect
jim
+1  A: 

pretzel,

as i mentioned briefly in the comment, you should 'grace' the 0.1% of non js users with some 'message' if they don't have js turned on. here's what i have immediately following the <body> tag in my templates:

<noscript>
  <div id="noscript" class="readme">
    <p>Yoursite name requires that you have javascript turned on - 
    Follow <a target="_blank" href="http://www.google.com/support/bin/answer.py?answer=23852"&gt;
    this walkthrough</a> to enable javascript</p>
  </div>
</noscript>

and this can be additionally styled by using the css nostyle stuff:

noscript{
    background-color: red;
    color: white;
    border: 2px solid white;
    font-size: 1.2em;
}

or by using the better approach of using a defined class for it:

.readme {
    background-color:#702444;
    color:#FFFFFF;
    display:block;
    margin:10px 5px;
    padding:10px;
    text-align:center;
    font-weight: bold;
    border: 6px solid #fff;
}

.readme a 
{
    color: #FFAC50;
}

etc, etc...

cheers again

jim
Hey Jim, Thanks very much for the follow-up. I'll add this to my web app today.
Pretzel