views:

33

answers:

1

I need to create an interface that upon selection of a parent multi select, it updates a child multi select of options. It is intended that the parent multi select can have none, one or many options selected and the child element displays a union of items that both parents have (or falls back to all items).

Take for example:

  • When parent 1 is selected, all status items for parent 1 should be allowed to be selected
  • When parent 1 and parent 2 are selected all status items that are allowed within both parent 1 and 2 should be allowed to be selected in the child element

After searching around here and doing a lot of googling I think I have got close, but this solution unfortunately does not fully satisfy the second requirement.

I may be approaching this totally the wrong way, so I'm open to suggestions.

The JS:

$(document).ready(function(){

var allOptions = $('#children option').clone();

function children_update() {
    $('#parents > option:selected').each(function() { 
        $('#children').html(allOptions.filter('.option-' + parseInt($(this).val())));    
    });
    if(!$('#parents > option:selected').length) { $('#children').html(allOptions); }
}

children_update();

$('#parents').change(function() { children_update(); });
});

The HTML

    Parents<br />
<select multiple name="parents[]" id="parents">
<option value="1">parent 1</option>
<option value="2">parent 2</option>
<option value="3">parent 3</option>
</select>

<br />
Children<br />
<select multiple name="children[]" id="children">
<option value="1" class="option-1">child 1 (1)</option>
<option value="2" class="option-1 option-2">child 2 (1,2)</option>
<option value="3" class="option-1 option-2 option-3">child 3 (1,2,3)</option>
<option value="4" class="option-1 option-2">child 4 (1,2)</option>
<option value="5" class="option-2">child 5 (2)</option>
<option value="6" class="option-3">child 6 (3)</option>
</select>

Thanks

A: 

How about changing the children_update function to this...

function children_update() {
    $("#children option").attr('disabled','true');   //start off with all disabled
    $('#parents > option:selected').each(function() {
        var num = $(this).val();
        $("#children .option-"+num).attr('disabled','false');
    });
    if(!$('#parents > option:selected').length){           //if no parents selected
        $("#children option").attr('disabled','false');    //enable all options
    }
}

If I understand the problem correctly, that should work. However, if you're doing a more strict combinatorial thing (like only showing child options that match the exact combination of parent options), then please feel free to correct me on this.

EDIT:

Okay, here's a new solution:

function children_update() {
    $("#children option").attr('disabled','true');   //start off with all disabled
    var selectors = getSelectors();
    $("#children option"+selectors).attr('disabled','false');
}

function getSelectors(){
    var parents = $("#parents").val();
    var selectors = "";
    if (parents){
        $.each(parents, function(index, val){
            selectors = selectors + ".option-" + val;
        });
    }
    return selectors;
}
Matt
Thanks for the suggestion, It is a requirement that strict matching be done: only showing child options that are matched by all selected parent options. It may be that a different approach is required? Happy to hear any thoughts you may have.
nathan-unleashed
Just so I understand this correctly...If ONLY parent 1 is selected: only child 1 will be enabled. If parents 1 AND 2 are selected: only children 2 and 4 will be enabled. If parents 1 AND 2 AND 3 are selected: only child 3 will be enabled.Is that the scheme you're going for?
Matt
Sorry I wasn't clear to begin with, but yes that is what i'm going for. Any combination of parents will disable/enable their respective child elements.
nathan-unleashed
Thanks! I changed the 'true' and 'false' respectively to not have quotes it worked as expected. It doesn't work in safari with show/hide or disabled true/false, but I believe that to be more of a safari bug than anything.
nathan-unleashed