Thursday, 2 May 2013

JQuery: disable options on a 2nd select box, when a specific selection is chosen in 1st select box

Backing up this JSFiddle I was playing around with at:

http://jsfiddle.net/hatft/3/


Scenario:

* User has selectboxes to enter "Opening hours", starting time and
closing times using two select boxes.

* When user selects "Closed" in first selectbox, the 2nd select box
must not allow the user to choose any times, and must have "-" as the
value.

* When user changes from "Closed" to some other value, the 2nd select
box must work as normal, allowing user to choose anything

Strictly speaking, we would probably want to do more validation so that:

- closing time is mandatory when start time is selected
- closing time is not earlier than starting time


HTML:

<h3 class="margin-bottom10">Your opening hours</h3>

<table>
<tbody>
<tr class="opening-hours-mon-fri display_none">
<td>Monday</td>
<td>
<select id="postad-monFrom" name="openhrs_mon_from">
<option>Please select</option>
<option value="closed">Closed</option>
<option value="0:00am">0:00am</option>
<option value="0:30am">0:30am</option>
<option value="1:00am">1:00am</option>
</select>
<!--<label for="postad-monTo">to</label>-->to
<select id="postad-monTo"
name="attributeMap[appliance_phone_repair.openhrs_mon_to_s]">
<option></option>
<option value="-">-</option>
<option value="0:00am">0:00am</option>
<option value="0:30am">0:30am</option>
<option value="1:00am">1:00am</option>
</select>
</td>
</tr>
<tr class="opening-hours-mon-fri">
<td>
<label for="postad-tuesFrom">Tuesday</label>
</td>
<td>
<select id="postad-tuesFrom"
name="attributeMap[appliance_phone_repair.openhrs_tues_from_s]">
<option>Select time</option>
<option value="closed">Closed</option>
<option value="0:00am">0:00am</option>
<option value="0:30am">0:30am</option>
<option value="1:00am">1:00am</option>
</select>

<label for="postad-tuesTo">to</label>

<select id="postad-tuesTo"
name="attributeMap[appliance_phone_repair.openhrs_tues_to_s]">
<option></option>
<option value="-">-</option>
<option value="0:00am">0:00am</option>
<option value="0:30am">0:30am</option>
<option value="1:00am">1:00am</option>
</select>
</td>
</tr>
</tbody>
</table>



JAVASCRIPT (uses jQuery 1.6.4)


// TEST SELECTORS BY CHANGING BKGROUND COLOR
//$('[class^="opening-hours-"]').css("background-color", "red");
$('[class^="opening-hours-"]').find('select[id$="From"]').css("background-color",
"yellow");

/*

TIL:

1. You need to use .nextAll() instead of .next()

next() ONLY WORKS IF THE SELECT BOX IS THE NEXT ELEMENT.

IF THERE IS ANYTHING IN BETWEEN, LIKE A <label>, then this won't work.

the earlier version of this only works because "to" was not inside a label

2. When "Closed" is chosen, set the "to" selectbox to "-" and don't
allow any other choices

- set disabled attribute on the options that were not selected
- when value of "From" selectbox is NOT "Closed", then remove disabled
attribute on the "To" options


*/


$('[class^="opening-hours-"]').find('select[id$="From"]').change(function () {
if ($(this).val() == 'closed') {
/*
DOES NOT WORK BECAUSE .next() only gets the
immediately following element.
*/
var $toSelect = $(this).nextAll('select[id$="To"]');
$toSelect.css("background-color", "red");
$toSelect.val('-');
$toSelect.find(':not(:selected)').attr('disabled','disabled');
} else {
$(this).nextAll('select[id$="To"]').find(':not(:selected)').removeAttr('disabled');
$(this).nextAll('select[id$="To"]').css("background-color", "white");


}
});

No comments: