7

From W3schools example (do not make any comment about W3Schools I am just using it for an example). A select option looks like this:

<select>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select> 

Lets say that I have two select options with the same name

<select name="name[]">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select> 

<select name="name[]">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select> 

Now, what I want to accomplish using jQuery, that if somebody selected an option from the first select.. he/she cannot select it from the second select. How can I accomplish that? i.e. how can I automatically remove Volvo from the second select if it was selected in the first select? If it is not possible using jQuery, then how can I prevent it using PHP?

My guess is by using array_unique :

    foreach(array_unique($_POST['name']) as $name){
        if (!empty($name)){
               // do something
        }

[Edit after posting the question]

this question is relevant to mine. However, I do not want the option to be disabled.. I want the option to be removed or hidden. Also, I would like to see how it can be done using PHP

Community
  • 1
  • 1
syrkull
  • 2,295
  • 4
  • 35
  • 68

3 Answers3

11

Fiddle: http://jsfiddle.net/jFMhP/

To go through all selects, make the javascript like:

$('select').change(function() {
    var myOpt = [];
    $("select").each(function () {
        myOpt.push($(this).val());
    });
    $("select").each(function () {
        $(this).find("option").prop('hidden', false);
        var sel = $(this);
        $.each(myOpt, function(key, value) {
            if((value != "") && (value != sel.val())) {
                sel.find("option").filter('[value="' + value +'"]').prop('hidden', true);
            }
        });
    });
});

And that will remove the options from all other selects.

Alternate Option

Alternate Option to only use 'named' selectors jsFiddle: http://jsfiddle.net/jlawrence/HUkRa/2/ Code:

$('select[name="name[]"]').change(function() {
    var myName = '[name="name[]"]';
    var myOpt = [];
    $("select"+ myName).each(function () {
        myOpt.push($(this).val());
    });
    $("select"+ myName).each(function () {
        $(this).find("option").prop('hidden', false);
        var sel = $(this);
        $.each(myOpt, function(key, value) {
            if((value != "") && (value != sel.val())) {
                sel.find("option").filter('[value="' + value +'"]').prop('hidden', true);
            }
        });
    });
});
Jon
  • 4,746
  • 2
  • 24
  • 37
4

You can use hidden attribute (or simply .hide(), display: none) to temporarily hide necessary option, thus making it impossible to select it:

var $second = $('.select-two');
$('.select-one').change(function() {
    $second.find('option').prop('hidden', false)
    .filter('[value="' + $(this).val() + '"]').prop('hidden', true);
    $(this).val() == $second.val() && $second.val('');
});

http://jsfiddle.net/FDRE7/

And of course we can also make it work in both directions:

var $select = $('.select').change(function() {
    var $other = $select.not(this);
    $select.find('option').prop('hidden', false)
    .filter('[value="' + $(this).val() + '"]').prop('hidden', true);
    $(this).val() == $other.val() && $other.val('');
});

http://jsfiddle.net/FDRE7/1/

You may also want to validate this data on the server side. In this case if user selected the same values then POST array will look like:

Array
(
    [name] => Array
        (
            [0] => mercedes
            [1] => mercedes
        )
)

So it's quite easy to check:

if ($_POST['name'][0] == $_POST['name'][1]) {
    // not allowed, redirect back
}

or

if (count(array_unique($_POST['name'])) == 1) {
    // not allowed, redirect back
}
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • this works with the first select.. I want it to work with both selects. Whenever you pick a value from the second one.. it should be removed from the first one.. and the opposite is true. – syrkull Mar 31 '13 at 18:46
  • exactly what I wanted. Please explain how you can prevent storing the same option using PHP so I can pick this answer as the right answer. – syrkull Mar 31 '13 at 18:56
  • This is probably my fault.. and not yours because I did not explain my question enough. there are many flows in your code. First, the jquery code will only work on two selects.. it will not work on more than two. `count()` is not an efficient solution to validate.. there has to be a better way.. again, what if I have more than two selects elements? – syrkull Mar 31 '13 at 19:17
  • 2
    If there can be more elements `if (count(array_unique($_POST['name'])) != count($_POST['name']))`. – dfsq Mar 31 '13 at 19:20
0

Thanks @Jon, for my case I need to do a small change to change selected option in next select, and run the process for first load:

    $('select').change(function() {
        var myOpt = [];
        $("select").each(function () {
            //change selected in next select box
            if (myOpt.indexOf(jqml(this).val()) >= 0) {
                  $(this).find('option:selected').next().attr('selected', 'selected');
            }
            myOpt.push($(this).val());
        });
        $("select").each(function () {
            $(this).find("option").prop('hidden', false);
            var sel = $(this);
            $.each(myOpt, function(key, value) {
                if((value != "") && (value != sel.val())) {
                    sel.find("option").filter('[value="' + value +'"]').prop('hidden', true);
                }
            });
        });
    });
    //do the process for first load
    $('select').change();
masoud2011
  • 896
  • 9
  • 10