views:

144

answers:

4

I have 2 select boxes on a page with a variable number of options in them.

For instance:

<fieldset>
    <label for="fizzwizzle">Select a Fizzwizzle</label>
    <select name="fizzwizzle" id="fizzwizzle" size="10">
        <option>Fizzwizzle_01</option>
        <option>Fizzwizzle_02</option>
        <option>Fizzwizzle_03</option>
        <option>Fizzwizzle_04</option>
    </select>
</fieldset>
<fieldset>
    <label for="fizzbaggot">Select a Fizzbaggot</label>
    <select name="fizzbaggot" id="fizzbaggot" size="10">
        <option>Fizzbaggot_01</option>
    </select>
</fieldset>

I would like to verify that both of these select boxes have a selected option. My initial thought is to simply use JQuery but I can't seem to figure out how to do that. My attempts so far have been futile but I have the following code that I think should work with the missing link.

function verify_selectboxen_selection() {
    var allSelected = true;

    $('select').each(function() {
      /* if select box doesn't have a selected option */
            allSelected = false;
            break;
    });

    if (!allSelected) {
        alert('You must select a Job and a Disposition File.');
    }
    return allSelected;
}

Seems simple enough. Thoughts?

+1  A: 

You can use the :selected selector for this.

var unselected = [] 
$('select').each(function(){
    if (0 == $(this).find('option:selected').length) {
        unselected.push(this.id);
    }
});

if (unselected.length != 0) {
    // unselected contains the ids of non-selected select boxes
}

Or you could check their values with val(). This presumes that you have a default option with no value (ie empty string value).

var unselected = [] 
$('select').each(function(){
    if ('' == $(this).val()) {
        unselected.push(this.id);
    }
});

if (unselected.length != 0) {
    // unselected contains the ids of non-selected select boxes
}
Lachlan Roche
Good answer. It's just no where near as compact. Thanks for the effort, though.
Tim Visher
+3  A: 

In jQuery you can use the :selected selector to get the total options selected. This number out to match the number of select's themselves:

if ($("select").length === $("option:selected").length) {
  // they match
}
Jonathan Sampson
This works perfectly with a few modifications. My code looks like `if($('select').length === $('select option:selected').length)`. No parens on the last length. Edit that and I can accept your answer. Thanks!
Tim Visher
@Tim: Sorry about the parens - `$.width()` and `$.height()` have ruined me ;)
Jonathan Sampson
Except for `select multiple`, and `select` with no child `option`​s, this will *always* be true. A select-one box always has a selected option even if the user has not interacted with the control.
bobince
Are you sure, @bobince? This is working in testing.
Tim Visher
@Tim: A select with an option automatically has an option selected - the first option.
Jonathan Sampson
@Jonathan: I understand that. That's not the part I'm disputing. The solution you posted works. If I don't select anything in the select boxes, then I correctly identify that nothing was selected using your method. Is this something JQuery tries to be intelligent about, perhaps?
Tim Visher
@Tim: The point @bobince is making is that a selection is made regardless if you do the selecting or not. The first option will be selected by default. If this is alright with your project, then there are no worries :)
Jonathan Sampson
@Jonathan: That's what I'm saying. When I don't select anything and submit the form, the code says that nothing is selected. Am I missing something about the behaviour you and @bobince are describing? I would expect, as @bobince says, that your test would always return true because the select boxes come in with a selection each. That's not the behavior I'm seeing.
Tim Visher
I'm unable to reproduce this. If I have a non-empty, non-multiple select, `$('option:selected').length` is always 1 for me. Would be interested to see a test case if you can make that not happen!
bobince
Finally had some time to put this demo together. Tested and verified in both Firefox and Chrome. What am I missing? http://j.mp/9i7dur
Tim Visher
Spotted it. The problem was that I forgot to mention that I set the size attribute on the select tags. I added an example to the demo page I put together. Sorry for the confusion. http://j.mp/9i7dur
Tim Visher
Interestingly enough, I discovered as well that Chrome 4.0.249.89 (38071) doesn't seem to honor the `size` attribute unless it's 1. Otherwise it makes the size = the number of options. Maybe. I didn't pursue it much further.
Tim Visher
@TimVisher: Your demo seems to work for me. Each demo requires the user to select an option from both `select` elements. The last set of `select` elements implicitly select the first `option` element once the page loads. What's the problem?
Jonathan Sampson
No problem at all. What I was referring to was the confusion between myself and @bobince and you. As far as I can tell, the reason @bobince thought your solution wouldn't work was because I had forgotten to mention that I had set the size attribute to be greater than the number of options. When that is set, @bobince's concerns seem to disappear. Sorry for the confusion.
Tim Visher
@TimVisher: Hehe, no problem. Sorry for causing you so much distraction here. Glad to hear your problem is resolved.
Jonathan Sampson
A: 
 function checkSelects() {
        return $("select :selected").length == $("select").length;
    }

alert(checkSelects());
F.Aquino
+1  A: 

I would like to verify that both of these select boxes have a selected option

It's not possible for a (non-multiple) select box not to have a selected option! If you don't declare selected on one of the option​s, the browser will automatically select the first option.

So: return true; :-)

If you want to have an ‘unselected’ initial state, you'd have to include a no-option option for it, usually the first one:

<select name="fizzbaggot">
    <option value="" selected="selected">(Select a fizzbaggot)</option>
    <option>foo</option>
    <option>baz</option>
    <option>bar</option>
</select>

Then you can check whether a different option to that one has been selected, either by saying:

$('select').each(function() {
    if ($(this).val()!=='')
        allSelected= false;
});

Or, if you might want to use the empty string as a valid value, you can just look at the index of the selected option:

$('select').each(function() {
    if (this.selectedIndex===0)
        allSelected= false;
});
bobince