...

View Full Version : A neat way of displaying 2 characters as names in an array/select input



Ace.....
11-21-2012, 05:23 PM
The code below works very nicely, offering a compact means of selection, while offering potential for a long list of options.
However, the 2 character codes are meaningless to the user.

Is there a neat way of providing the description in the select box, while allowing me to grab the 2 character code from the users selection?



function addOption(selectbox,text,value )
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}

function addOption_list(selectbox)
{
var x = new Array("af","ar","az","be","bg","bn");
for (var i=0; i < x.length;++i)
{addOption(document.drop_list.mylist, x[i], x[i]);}
}

<body>
<form name="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="nul">Your choice</option></select>
</form>
</body>

Philip M
11-21-2012, 05:48 PM
The code below works very nicely, offering a compact means of selection, while offering potential for a long list of options.
However, the 2 character codes are meaningless to the user.

Is there a neat way of providing the description in the select box, while allowing me to grab the 2 character code from the users selection?



function addOption(selectbox,text,value )
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}

function addOption_list(selectbox)
{
var x = new Array("af","ar","az","be","bg","bn");
for (var i=0; i < x.length;++i)
{addOption(document.drop_list.mylist, x[i], x[i]);}
}

<body>
<form name="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="nul">Your choice</option></select>
</form>
</body>

Yes, of course. You are populating your select list with the same values for both value and text.

Simply make another array y containing the corresponding text values.
And then
addOption(document.drop_list.mylist, y[i], x[i]);

It is recommended that you place the opening brace following the function, if, else, for, while, do, switch, and try statements on the same line and not on the following line. Apart from that every Javascript statement should be followed by a semi-colon (;). It is quite possible to disregard this advice, but if you do one day it will rise up and bite you in the undercarriage.


All advice is supplied packaged by intellectual weight, and not by volume. Contents may settle slightly in transit.

Old Pedant
11-21-2012, 08:52 PM
As Philip said, you could use:

var codes = new Array("af","ar","az","be","bg","bn");
var countries = new Array("Afghanistan","Argentina",".... );
But a perhaps better way is this:


var countries = {
af : "Afghanistan",
ar : "Argentina",
...
};

function addOption_list(selectbox)
{
for ( var abbrev in countries )
{
selectbox.options.add( new Option( countries[abbrev], abbrev ) );
}
}


By creating your list as a set of object properties, you ensure that the right code is associated with the right text.

Ace.....
11-22-2012, 12:50 AM
I have to say that Philip's code worked straight out of the box.
Clearly it was immediately recognisable, because it was effectively the same code, and I've worked with this method on numerous occasions.
The only leap of faith I had to make was .mylist displaying the descriptions, while .mylist.value displayed the selected code.
I see it's the case (and its perfect), but as to why it does this, I don't understand.


function addOption_list(selectbox){
var code = new Array("af","ar","az");
var countries = new Array("Hull","Bev","Driff");
for (var i=0; i < code.length;++i)
{addOption(document.drop_list.mylist, countries[i], code[i]);}}
function mychoice(){alert(document.drop_list.mylist.value)}


I did then spend a good deal of time on Old Pedant's script.
However I failed to develop it to the point where it would populate the select box. Clearly highlighting my limitations I'm afraid. :(

But anyway.... it's a win.
1 out of 2 ain't bad. :)

Old Pedant
11-22-2012, 01:21 AM
Here...a complete working version using my code:


<html>
<body>
<form id="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="">Your choice</option>
</select>
<input name="fill" type="button" value="Fill the list"/>
</form>


<script type="text/javascript">
(
function( )
{
var choices = {
af : "Hull",
ar : "Bev",
az : "Driff"
};

var form = document.getElementById("drop_list"); // named forms are OBSOLETE! use ids

form.mylist.onchange = function() { alert("You chose " + this.value ); };

form.fill.onclick = function() { addOption_list( form.mylist ); };

function addOption_list(selectbox)
{
for ( var val in choices )
{
var txt = choices[val];
selectbox.options.add( new Option( txt, val ) );
}
}

} // end of master anonymous function

)(); // self-invoke master function
</script>
</body>
</html>


You don't have to put the JS code at the end of the <body>, as I have done.

But if you do so you get some advantages:
(1) You don't have to worry about delaying the initialization until window.onload time.
(2) By using an anonymous master function as I have, your JS code can't possibly conflict with any other JS used on the page (e.g., from libraries or what have you).
(3) As you can see, I didn't have to put any inline event handlers in the HTML code. Whether you care about that is up to you. I'm not fanatic about it, but it is considered more unobtrusive use of JS code. But in this case, your page won't function without JS, so I personally don't think this is of any importance.

Old Pedant
11-22-2012, 01:34 AM
Finally, here's yet another way. Use an array *OF* arrays.

Again, the point is to make sure that the code and text forms of the options are guaranteed to be lined up. It's so easy to omit an item when using parallel arrays that I avoid them like the plague.


<html>
<body>
<form id="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="">Your choice</option>
</select>
<input name="fill" type="button" value="Fill the list"/>
</form>


<script type="text/javascript">
(
function( )
{
var choices = [ /* an array OF arrays */
[ "af", "Hull" ],
[ "ar", "Bev" ],
[ "az", "Driff" ]
];

var form = document.getElementById("drop_list"); // named forms are OBSOLETE! use ids

form.mylist.onchange = function() { alert("You chose " + this.value ); };

form.fill.onclick = function() { addOption_list( form.mylist ); };

function addOption_list(selectbox)
{
for ( var c = 0; c < choices.length; ++c )
{
var val = choices[c][0]
var txt = choices[c][1];
selectbox.options.add( new Option( txt, val ) );
}
}

} // end of master anonymous function

)(); // self-invoke master function
</script>
</body>
</html>


Oh...and try clicking on that "Fill the list" button twice. Or three times.

Hmmmm....

There are easy fixes for that, if you care.

Philip M
11-22-2012, 08:31 AM
I have to say that Philip's code worked straight out of the box.
Clearly it was immediately recognisable, because it was effectively the same code, and I've worked with this method on numerous occasions.


Yet once again, there is more than one way to skin a cat. :) My suggestion involved minimal alteration to the OP's existing code.

I don't completely agree with Old Pedant's remark that "the point is to make sure that the code and text forms of the options are guaranteed to be lined up. It's so easy to omit an item when using parallel arrays that I avoid them like the plague." A lot depends on how many items there are. And testing ought to reveal that error very quickly. And it is not "guaranteed". You can still get the two corresponding values transposed, for example.

jmrker
11-22-2012, 01:16 PM
Finally, here's yet another way. Use an array *OF* arrays.



<html>
<body>
<form id="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="">Your choice</option>
</select>
<input name="fill" type="button" value="Fill the list"/>
</form>


<script type="text/javascript">
(
function( )
{
var choices = [ /* an array OF arrays */
[ "af", "Hull" ],
[ "ar", "Bev" ],
[ "az", "Driff" ]
];

var form = document.getElementById("drop_list"); // named forms are OBSOLETE! use ids

form.mylist.onchange = function() { alert("You chose " + this.value ); };

form.fill.onclick = function() { addOption_list( form.mylist ); };

function addOption_list(selectbox)
{
for ( var c = 0; c < choices.length; ++c )
{
var val = choices[c][0]
var txt = choices[c][1];
selectbox.options.add( new Option( txt, val ) );
}
}

} // end of master anonymous function

)(); // self-invoke master function
</script>
</body>
</html>




Neat-Oh!

One question for "Old Pedant":
Is it possible to dynamically add more elements to the 'choices' array when it is inside the master function?

Ace.....
11-22-2012, 02:45 PM
The script below does seem to posses some kind of beauty.

I tried both versions.
Both contain the fill list bug.

I can see that the listing of the array 'codes against descriptions' is very good visually.

Perhaps the classic array is easier to produce, though I suppose with 'search and replace' pretty much any format can be produced.

Given that the bug was fixed in the latter two scripts.
Which of the 3 options are the most efficient?
Or is there no difference.




<html>
<body>
<form id="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="">Your choice</option>
</select>
<input name="fill" type="button" value="Fill the list"/>
</form>


<script type="text/javascript">
(
function( )
{
var choices = [ /* an array OF arrays */
[ "af", "Hull" ],
[ "ar", "Bev" ],
[ "az", "Driff" ]
];

var form = document.getElementById("drop_list"); // named forms are OBSOLETE! use ids

form.mylist.onchange = function() { alert("You chose " + this.value ); };

form.fill.onclick = function() { addOption_list( form.mylist ); };

function addOption_list(selectbox)
{
for ( var c = 0; c < choices.length; ++c )
{
var val = choices[c][0]
var txt = choices[c][1];
selectbox.options.add( new Option( txt, val ) );
}
}

} // end of master anonymous function

)(); // self-invoke master function
</script>
</body>
</html>

Philip M
11-22-2012, 03:00 PM
Which of the 3 options are the most efficient?
Or is there no difference.

I would say that there is no discernable difference. I would prefer clarity and simplicity to 'efficiency' any time.

jmrker
11-22-2012, 03:12 PM
I would say that there is no discernable difference. I would prefer clarity and simplicity to 'efficiency' any time.

The efficiency here is more the burden of the operator as the code is only executed during setup and selection events. It is not being executed continuously.

Old Pedant
11-22-2012, 04:47 PM
I tried both versions.
Both contain the fill list bug.


I have no idea what the "fill list bug" is. What did you do to fix it??

********

Philip is correct that any of the three versions will work just fine and he a nd JMrkr are correct in saying that performance will not be an issue.

Old Pedant
11-22-2012, 04:49 PM
Is it possible to dynamically add more elements to the 'choices' array when it is inside the master function?

???

Sure, if you provide a way inside the master function to do so.

If you mean could you do so from JS code external to the master function, then no. In which case, if that's something you need, simply move choices outside the anonymous function.

Ace.....
11-23-2012, 09:56 AM
I have no idea what the "fill list bug" is. What did you do to fix it??

I didn't attempt to fix it.
I ran both scripts, and tested as you suggested:

Clicking 'Fill the list' each time adds the array to the list.
However, I note that this also occurs with the script I posted.
In most cases, I believe this wouldn't matter, as the function would be called internally, and only once.

I guess the problem would arise, if there was a requirement for a user to choose between sets of data to fill the list.

On the issue of your advice below:



<form id="drop_list">
<select size="1" name="mylist" style="text-align: center; cursor: pointer;">
<option value="">Your choice</option>
</select>
<input name="fill" type="button" value="Fill the list"/>

var form = document.getElementById("drop_list"); // named forms are OBSOLETE! use ids

form.mylist.onchange = function() { alert("You chose " + this.value ); };

form.fill.onclick = function() { addOption_list( form.mylist ); };


I note that select & input both use names, and are accessed by them, while form has an id and is accessed by it.

What is the new rule vis a vis names & id usage?

Philip M
11-23-2012, 11:56 AM
form name = "name" is obsolete, and you should use id instead.

Form elements must have a name assigned if they are to be passed to a server-side script. They can have (unique) ids as well, but this is optional and form elements can equally well (as here) be addressed by name.

Ace.....
11-23-2012, 03:12 PM
Everything is working well.
Id's are updated, and careful use of gedit and office calc, have got the arrays in place.

This is when it becomes obvious that I ALSO do need to access the chosen description, and not just the chosen code.

My initial lack of understanding, as to why myFrom() is grabbing the code (and not the description), is now coming back to haunt me.

How can I modify myFrom() to display the selected description?


function addOption_list(selectbox)
{
var code = new Array("af","ar","az");
var countries = new Array("Hull","Bev","Driff");
for (var i=0; i < code.length;++i)
{addOption(document.getElementById('from'),countries[i],code[i]);}
}
function myFrom(){alert(document.getElementById('from').value)}

<body><form>
<select id="from" size="1" name="from"><option value="nul">From</option></select>
</form></body>

Philip M
11-23-2012, 03:28 PM
Do you mean that you want the text of the option as opposed to the value?

If so, why not make the option value the same as the text?

Or:-


var si = document.getElementById("from").selectedIndex; // using form ID
var txt = document.getElementById("from").options[si].text;

Ace.....
11-23-2012, 05:21 PM
Yes of course.
One of the early lessons I learned around 12 years ago. :o

I can still hear the echo from the penny dropping - selectedIndex, options & values.

The problem is, that it's not like riding a bike.

:)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum