resetting multiple SELECT values

D

dewed

I know just enough javascript to hurt myself.. but hopefully someone
can point me in the right direction.

I have a pretty large form generated from an uploaded CSV file, the
form might have up to 100 select/option tags like this . . .

<select name="qty2">
<option value="0">0</option>
<option value="2">2</option>
<option value="4">4</option>
<option value="6">6</option>
<option value="8">8</option>
</select>

qty2 is for the 2nd line of the file, and could be a maximum of qty100

I need a javascript function that will loop though qty2-qty100 and
reset all options to zero..

Something like this...
<SCRIPT LANGUAGE="JavaScript"><!--
function resetqty()
{
var lines=0;
while (lines<=100)
{
var element = 'qty'.lines;
document.forms['formname'].elements[element].value = "0";
lines++;
}
}
//-->
</SCRIPT>

but of course I don't know what I'm doing here, and I suspect my
element var
isn't doing what I had hoped.
 
R

RobG

I know just enough javascript to hurt myself.. but hopefully someone
can point me in the right direction.

I have a pretty large form generated from an uploaded CSV file, the
form might have up to 100 select/option tags like this . . .

<select name="qty2">
<option value="0">0</option>
<option value="2">2</option>
<option value="4">4</option>
<option value="6">6</option>
<option value="8">8</option>
</select>

qty2 is for the 2nd line of the file, and could be a maximum of qty100

I need a javascript function that will loop though qty2-qty100 and
reset all options to zero..

If you are using the CSV data with DOM methods to create the select,
then you can easily set the value as you go. Same goes for if you are
creating an HTML string and assigning it to the innerHTML property of
an element. Creating the select element then looping over all the
options to change their value is inefficient.

But perhaps that isn't what you are doing.
Something like this...
<SCRIPT LANGUAGE="JavaScript"><!--

The language attribute was deprecated over a decade ago, the type
attribute is required (in HTML 4). There hasn't been a need for HTML
comments inside script tags since NN2, so you can remove them to. :)

Also, please manually format code to about 70 character lines so auto-
wrapping doesn't affect your post. I'll do it this time:
function resetqty()
{
var lines=0;
while (lines<=100) {
var element = 'qty'.lines;

I suspect that what you are after is concatenation:

var element = 'qty' + lines;

What is happening in your code is that although 'qty' is a primitive,
the following period '.' is interpreted as a property accessor.
Attempting to access a property of a string primitive will cause it to
be converted to a String object (but only for the purpose of
evaluating 'qty'.lines). String objects don't have a lines property,
so undefined is returned and assigned to element.

While declaring element inside an if block is harmless, it is
considered bad coding practice. Javascript only has function scope,
declaring variables inside blocks infers block scope and might confuse
those more familiar with languages that have block scope.

Also, since the value assigned to element is to be used as a name
property, it might be better to be called "name":

var name = 'qty' + lines;
document.forms['formname'].elements[element].value = "0";

The value of "element" is the name of an option, but option elements
aren't added directly to the form's elements collection. They are
properties of the select's options collection so:


document.forms['formname'].elements['qty2'].options[element].value =
"0";

will do the trick. See below for a shorter version.

A more defensive approach to the above that sets the value of all
options regardless of their name is (untested):

var form = document.forms['formname'];
var select = form && form.elements['qty2'];
var options = select && select.options;
var i;

if (options) {
i = options.length;
while (i--) {
options.value = '0';
}
}
}
}
//-->

Remove that line too.
</SCRIPT>

but of course I don't know what I'm doing here, and I suspect my
element var
isn't doing what I had hoped.

And them some. :)
 
J

Jukka K. Korpela

dewed said:
I have a pretty large form generated from an uploaded CSV file, the
form might have up to 100 select/option tags like this . . .

<select name="qty2">
<option value="0">0</option>
<option value="2">2</option>
<option value="4">4</option>
<option value="6">6</option>
<option value="8">8</option>
</select>

I would rather use
<input type="number" name="qty2" min="0" max="8" step="2" value="0">
for usability reasons. It is faster and easier to type "8" than to open a
dropdown, scroll down to "8", and hit Enter. And as browsers start
supporting type="number" as defined in HTML5 drafts, you get a control that
typically lets the user type in a number _or_, if he prefers, scroll up and
down.
On other browsers, like still on IE and Firefox, the element degrades
gracefully to a simple text input box, as if it had type="text" and not
type="number". Admittedly, then the input box is default-wide, which means
too wide, but you can fix this with a simple piece of JavaScript:

var input = document.getElementsByTagName("input");
for(var i = 0; i < input.length; i++) {
if(input.type == "text") {
input.size = 1;
input.maxLength = 1; }}

(This assumes that all input elements with type="number" are expected to
accept a single digit as input.)

And you might wish to check the input for correctness immediately, but let's
return to that if needed.

Now said:
I need a javascript function that will loop though qty2-qty100 and
reset all options to zero..

I suppose that means removing the option elements so that only <option
value="0">0</option> remains. I wonder what next... as this operation does
not sound meaningful in isolation. The continuation of the story has an
impact on how the first part is best done.
Something like this...

Well, it's in fairly old-fashioned style, and not that robust. Besides...
var element = 'qty'.lines;

is Perl style; in JavaScript, string catenation is "+", not "."
document.forms['formname'].elements[element].value = "0";

That would set the <select> element's value property to 0, but that would
not change anything, as the property is initialized to that (generally, to
the value property of the initially selected <option> element). What you
apparently wish to do is to effectively remove all but the first <option>
element. The simplest way to do that is to set the <select> element's length
(which indicates the number of <option> elements in it) to 1.

This would work:

<SCRIPT LANGUAGE="JavaScript">
function resetqty()
{
var select = document.forms['formname'].getElementsByTagName("select");
for(var i = 0; i < select.length; i++) {
if(select.name == "qty" + (i+2)) {
select.length = 1; }}
}
</SCRIPT>
 
T

Thomas 'PointedEars' Lahn

Jukka said:
I would rather use
<input type="number" name="qty2" min="0" max="8" step="2" value="0">
for usability reasons. It is faster and easier to type "8" than to open a
dropdown, scroll down to "8", and hit Enter.

Arguing with recent browsers, you should know that almost all of them (if
not all of them, I do not know about IE 9's behavior) allow you to type the
text when the control has focus, in order to change the value. IOW, you
only have to type "8" in order to select the option with text "8" there.
And as browsers start supporting type="number" as defined in HTML5 drafts,
you get a control that typically lets the user type in a number _or_, if
he prefers, scroll up and down.
On other browsers, like still on IE and Firefox, the element degrades
gracefully to a simple text input box, as if it had type="text" and not
type="number". Admittedly, then the input box is default-wide, which means
too wide, but you can fix this with a simple piece of JavaScript:

Given that the list of options is very short, and limited to certain (even)
numbers, it is not better to use simple `input' elements here. With regard
to usability, using an input element here (thereby allowing *all* input –
HTML5 validation does not work properly yet) increases the probability for
user error, which is far more relevant and problematic as it would require a
lot more action on part of the user than just dropping down the list and
selecting an item from it (if that).

And from the developer perspective, having to add additional form validation
for something that can be dealt with a list of limited options can hardly be
justified.
var input = document.getElementsByTagName("input");

This should not be necessary or desired. document.getElementsByTagName()
iterates over the whole document tree, so *all* forms in the document;
calling the getElementsByTagName() method of a parent element node might be
better.

But we are talking about a form here, so there should be a `form' element,
and the object that represents it has an `elements' collection that can be
more efficiently iterated over (see below).
for(var i = 0; i < input.length; i++) {

Always more efficient than that, and written less confusing with regard to
whitespace (to differentiate between control statements and method calls):

for (var i = 0, len = input.length; ++i)

or, where reverse order is acceptable,

for (var i = input.length; i--;)
if(input.type == "text") {
input.size = 1;
input.maxLength = 1; }}


Like above, one should avoid repeated property accesses, as those can reduce
the runtime-efficiency of code considerably. And fixing the same whitespace
issue as above along with a bracing style that cannot be recommended,
results in:

for (var i = input.length; i--;)
{
var thisInput = input;
if (thisInput == "text")
{
thisInput.size = 1;
thisInput.maxLength = 1;
}
}

Assignment of the same constant value to both properties also allows for

thisInput.size = thisInput.maxLength = 1;
(This assumes that all input elements with type="number" are expected to
accept a single digit as input.)

You mean type="text", as that is what your code does.
I suppose that means removing the option elements so that only <option
value="0">0</option> remains.

How did you get that idea? If error correction was to be performed on this
statement, both Levensthein distance calculation and Occam's Razor suggest
that `select' was meant instead of `option', thereby selecting the first
option with value/text "0".
I wonder what next... as this operation does not sound meaningful in
isolation. The continuation of the story has an impact on how the first
part is best done.


Well, it's in fairly old-fashioned style, and not that robust. Besides...


is Perl style; in JavaScript, string catenation is "+", not "."

True, the OP would probably store the `undefined' value in `element' because
String objects do not have a built-in `lines' property.
document.forms['formname'].elements[element].value = "0";

That would set the <select> element's value property to 0, but that would
not change anything, as the property is initialized to that (generally, to
the value property of the initially selected <option> element).

Not necessarily.

Indeed, the `value' property of objects implementing the HTMLSelectElement
interface should not be used at all, because implementations differ in its
meaning.

The following approach should be used instead (which is what the OP asked
for):

document.forms["formname"].elements[element].selectedIndex = 0;

assuming that the first item is to be selected (which in some cases the
`value' assigment above would).

If that is triggered from a control in the same form, then it is possible to
take a shortcut route through its `form' property:

<form …>
<select name="qty1">
…
</select>
…
<script type="text/javascript">
function resetQty(form)
{
for (var i = form.elements; i--;)
{
var control = form.elements;
if (control.type == "select-one"
&& control.name.indexOf("qty") == 0)
{
control.selectedIndex = 0;
}
}
}

<!-- Generated dynamically so that no-script users are not confused by
a dysfunctional button -->
document.write('<button type="button" onclick="resetQty(this.form)"'
'accesskey="R"><u>R</u>eset Quantities<\/button>');
</script>
</form<

It would be easier client-side if the `select' controls were all named the
same, as they would be part of a NodeList then:

function resetQty(form)
{
var qtys = form.elements["qty"]
for (var i = qtys.length; i--;)
{
qtys.selectedIndex = 0;
}
}
What you apparently wish to do is to effectively remove all but the first
<option> element.

No, they said what they wanted. But being overconfident of your (scripting)
abilities, you did not listen carefully enough.
The simplest way to do that is to set the <select> element's length (which
indicates the number of <option> elements in it) to 1.

This would work:

<SCRIPT LANGUAGE="JavaScript">

It *might* work, but it could only be Valid HTML 3.2. The `SCRIPT' element
requires a `type' attribute in HTML 4, and it does not have a `language'
attribute in the current HTML5 (apparently there is a contradiction in the
current HTML5 Working Draft in that it does not specify a `language'
attribute in the interface definition but refers to one in the prose¹).
SHOULD/MUST be:

function resetqty()
{
var select = document.forms['formname'].getElementsByTagName("select");
for(var i = 0; i < select.length; i++) {
if(select.name == "qty" + (i+2)) {
select.length = 1; }}
}


Assuming that would work everywhere, that is very likely _not_ what the OP
asked for.

_______
¹ <http://www.w3.org/TR/html5/scripting-1.html#script>

PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
<script type="text/javascript">
[…]
<!-- Generated dynamically so that no-script users are not confused
by
a dysfunctional button -->

Make that

/*
* Generated dynamically so that no-script users are not confused
* by a dysfunctional button
*/

(It's not XHTML, and if it were,
document.write('<button type="button" onclick="resetQty(this.form)"'
'accesskey="R"><u>R</u>eset Quantities<\/button>');
</script>

would be a syntax error at least.)


PointedEars
 
J

Jukka K. Korpela

Thomas 'PointedEars' Lahn wrote:

[His usual pointless besserwisserism and trolling, mostly, and then: ]
How did you get that idea?

From the words "reset all options to zero". Literally it could mean setting
<option value="1">1</option> etc. all to <option value="0">0</option> , but
a menu with identical options sounds absurd, so the next assumption is the
one I wrote.
[...] suggest that `select' was meant instead of `option',

Setting all selects to zero isn't quite clear either. It might mean removing
_all_ options, or something else.
thereby selecting the first option with value/text "0".

That's a plausible interpretation, though it requires _two_ steps of
deviating from the question asked.

Maybe the OP wishes to comment on this.

More importantly, knowing the bigger picture would be essential. For
example, the resident troll is worrying about "efficiency", but it is
inefficient to worry about efficiency without knowing that it actually
matters. Up to 100 select elements isn't really an issue when discussing
client-side code, but if the page as a whole contains 100,000 input
elements, then it may matter how you efficiently you traverse only those
elements that you need to process.

If the OP really wants just to initialize a collection of <select> fields
(or some other fields), presumably as an operation triggered by a button or
some other event, then it's fairly simple as soon as one knows the exact
conditions. That is, exactly which fields should be affected?

What matters is not efficiency or coding style (which is something that
trolls just love to whine about, even if you imitated their own style) but
the logic by which you limit the operations to exactly those elements that
need to be handled. And this should be done so that it adapts to many kinds
of modifications to the page. Using name attributes "qty2", "qty3", ... up
to at most "qty100" doesn't sound like robust design, but sometimes you need
to work with existing structure. If you can affect the design of the
software that generates the page in the first place, then using a class
attribute might be optimal. (Name attributes of input fields specify the
name part of the name=value contribution that the field makes to the form
data upon submit, so they are part of the inteface to the external world and
may need to be adapted according to it. A class attribute is internal, for
use in styling, or in client-side scripting, or both.)
 
T

Thomas 'PointedEars' Lahn

Jukka said:
From the words "reset all options to zero". Literally it could mean
setting <option value="1">1</option> etc. all to <option
value="0">0</option> , but a menu with identical options sounds absurd, so
the next assumption is the one I wrote.

The next reasonable assumption is _not_ that all select elements should be
reduced to have only one option.
[...] suggest that `select' was meant instead of `option',

Setting all selects to zero isn't quite clear either. It might mean
removing _all_ options, or something else.

But since all `select' elements here have an `option' element that has the
value and content "0" …
That's a plausible interpretation, though it requires _two_ steps of
deviating from the question asked.

That would be reading "zero" as "0"? Come on.
Maybe the OP wishes to comment on this.

More importantly, knowing the bigger picture would be essential. […]

Apparently the bigger picture is that the OP wants to have those `select'
elements be reset in a way that does not require the document to be
reloaded, a frequently requested feature that can be accomplished with
client-side scripting.
If the OP really wants just to initialize a collection of <select> fields
(or some other fields), presumably as an operation triggered by a button
or some other event, then it's fairly simple as soon as one knows the
exact conditions. That is, exactly which fields should be affected?

What matters is not efficiency or coding style [snip other ad-hominem
attack]

Yes, it is. Clarity helps with understanding, and efficiency is one of the
most important things in a Web application.

As for calling other people names, I had given you a well-meant advice
already, as I have previously regarding your unjustified overconfidence
in your knowledge in this field, but you just would not listen.

So it seems the time has come for you to get a taste of your own medicine:

While aspiring to be a uomo universale, you have ended up as being only a
high-level dilettante in several fields. A dilettante who does not listen,
who instead attacks what he is unable to understand.


PointedEars
 
T

Thomas 'PointedEars' Lahn

RobG said:
I suspect that what you are after is concatenation:

var element = 'qty' + lines;

Yes, that should be obvious.
[…]
document.forms['formname'].elements[element].value = "0";

The value of "element" is the name of an option, […]

No, it is not. It is the name of a form control, the `select' element in
question.
document.forms['formname'].elements['qty2'].options[element].value =
"0";

See also <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-30606413>

But the options here do not have names. Note that objects implementing the
HTMLSelectElement interface do have a writable `value' property, and it can
be used exactly as the OP did:

<http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-59351919>

However, this property should not be used, the `selectedIndex' property
should be used instead (for reasons already mentioned):

<http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-85676760>

So good suggestions aside, what was *functionally* wrong here was only the
concatenation.


PointedEars
 
S

Scott Sauyet

Thomas said:
Jukka said:
[ ... ]
for(var i = 0; i < input.length; i++) {

Always more efficient than that, and written less confusing with regard to
whitespace (to differentiate between control statements and method calls):

  for (var i = 0, len = input.length; ++i)

for (var i = 0, len = input.length; i < len; ++i)
^^^^^^^^
I'm sure this was just a typo. I know you (T'PE'L) know this, and
most readers of this group understand it, but the OP is a self-
proclaimed neophyte.

-- Scott
 
T

Thomas 'PointedEars' Lahn

Scott said:
Thomas said:
Jukka said:
[ ... ]
for(var i = 0; i < input.length; i++) {

Always more efficient than that, and written less confusing with regard
to whitespace (to differentiate between control statements and method
calls):

for (var i = 0, len = input.length; ++i)

for (var i = 0, len = input.length; i < len; ++i)
^^^^^^^^
I'm sure this was just a typo. I know you (T'PE'L) know this, and
most readers of this group understand it, but the OP is a self-
proclaimed neophyte.

Yes, indeed. Thanks.


PointedEars
 
S

SAM

Le 21/04/11 00:15, dewed a écrit :
I know just enough javascript to hurt myself.. but hopefully someone
can point me in the right direction.

I have a pretty large form generated from an uploaded CSV file, the
form might have up to 100 select/option tags like this . . .

<select name="qty2">
<option value="0">0</option>
<option value="2">2</option>
<option value="4">4</option>
<option value="6">6</option>
<option value="8">8</option>
</select>

to catch the select :
var s = document.forms['formname'].elements['qty2'];

to delete all its options :
s.length = 0;

to add an option :
var o = new Option();
o.text = 'X';
o.value = 'x';
s.options[s.length] = o;
or :
s.options[s.length] = new Option('X','x');


to fix each option to zero (*) :
var n = s.length;
while (n--) {
s[n].text = 'zero';
s[n].value = 0;
}


(*) not understood the utility to get each option with value 0 ... ?!
Something like this...
<SCRIPT LANGUAGE="JavaScript"><!--

no :

function resetqty()


function resetOptions(s) {
s = s.typeof == 'string'? document.formname.elements : s;
var n = s.length;
while (n--) {
s[n].text = 'zero';
s[n].value = 0;
}
}
</script>

<p><button onclick="resetOptions('qty2568')">all qty2568 to 0</button>

<form name="formname" action="foo.php">
<p><select name="qty2568" onclick="resetOptions(this)">
<option ...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top