Created
August 23, 2013 19:27
-
-
Save ernestom/6323055 to your computer and use it in GitHub Desktop.
weird checkboxes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head></head> | |
<body> | |
<form> | |
<dl id="f_audio"> | |
<dd> | |
<label for="subtitled"> | |
<input type="checkbox" name="subtitled" id="subtitled" value="1" />Subtitulada | |
</label> | |
</dd> | |
<dd> | |
<label for="dubbed"> | |
<input type="checkbox" name="dubbed" id="dubbed" value="1" />Doblada | |
</label> | |
</dd> | |
</dl> | |
<dl id="f_flags"> | |
<dd> | |
<label for="sd"> | |
<input type="checkbox" name="sd" id="sd" value="1" />Funciones normales | |
</label> | |
</dd> | |
<dd> | |
<label for="threeD"> | |
<input type="checkbox" name="threeD" id="threeD" value="1" />3D | |
</label> | |
</dd> | |
<dd> | |
<label for="fourD"> | |
<input type="checkbox" name="fourD" id="fourD" value="1" />4D | |
</label> | |
</dd> | |
<dd> | |
<label for="imax"> | |
<input type="checkbox" name="imax" id="imax" value="1" />IMAX | |
</label> | |
</dd> | |
<dd> | |
<label for="jumbo"> | |
<input type="checkbox" name="jumbo" id="jumbo" value="1" />Macro pantallas | |
</label> | |
</dd> | |
<dd> | |
<label for="digital"> | |
<input type="checkbox" name="digital" id="digital" value="1" />Calidad digital | |
</label> | |
</dd> | |
</dl> | |
</form> | |
<script src="weirdcheckboxeslib.js"></script> | |
<script> | |
// HTML IDs | |
var showtimeTypeFilters = $$('#sd, #threeD, #fourD, #imax, #jumbo, #digital'); | |
var audioTypeFilters = $$('#subtitled, #dubbed'); | |
// event callbacks | |
showtimeTypeFilters.addEvent('change', function(event) { | |
Enelcine.Showtime.disableIncompatibleTypeFilters({ | |
element: event.target, | |
rules: Enelcine.Showtime.filterRules.byShowtimeType | |
}); | |
}); | |
audioTypeFilters.addEvent('change', function(event) { | |
Enelcine.Showtime.disableIncompatibleTypeFilters({ | |
element: event.target, | |
rules: Enelcine.Showtime.filterRules.byAudioType | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Enelcine = {Showtime: {}}; | |
/* | |
TODO: Improve documentation. | |
Rule structure inside the "bySomething" keys: | |
// exclusion object | |
{ | |
// elementId whose rules will be evaluated upon the user | |
// checking/unchecking the checkbox. | |
elementId: [ // array of two rules | |
// rule when elementId is CHECKED: | |
// element ids or exclusion objects to disable | |
[], | |
// rule when elementId is UNCHECKED: | |
// element ids or exclusion objects to disable | |
[] | |
], | |
} | |
*/ | |
Enelcine.Showtime.filterRules = { | |
byShowtimeType: { | |
sd: [ | |
// unchecked | |
null, | |
// checked | |
['threeD', 'fourD', 'imax', 'jumbo', 'digital'] | |
], | |
threeD: [ | |
// unchecked | |
[ | |
{imax: [ | |
// unchecked | |
null, | |
// checked | |
['sd', 'jumbo', 'fourD', 'digital'] | |
]}, | |
{jumbo: [ | |
// unchecked | |
null, | |
// checked | |
['sd', 'fourD', 'imax'] | |
]} | |
], | |
// checked | |
['sd', 'fourD', 'digital', | |
{jumbo: [ | |
// unchecked | |
[ | |
{imax: [ | |
// unchecked | |
null, | |
// checked | |
['jumbo'] | |
]} | |
], | |
// checked | |
['imax'] | |
]} | |
] | |
], | |
fourD: [ | |
// unchecked | |
null, | |
// checked | |
['sd', 'threeD', 'imax', 'digital', 'jumbo'] | |
], | |
jumbo: [ | |
// unchecked | |
[ | |
{threeD: [ | |
// unchecked | |
[ | |
{digital: [ | |
// unchecked | |
null, | |
// checked | |
['threeD'] | |
]} | |
], | |
// checked | |
['sd', 'fourD', 'digital'] | |
]}, | |
{digital: [ | |
null, | |
['imax', 'threeD', 'fourD', 'sd'] | |
]} | |
], | |
// checked | |
['sd', 'fourD', 'imax', { | |
threeD: [ | |
// unchecked | |
[{digital: [ | |
// unchecked | |
null, | |
// checked | |
['threeD'] | |
]}], | |
// checked | |
['digital'] | |
] | |
}] | |
], | |
imax: [ | |
// unchecked | |
[{threeD: [ | |
// unchecked | |
null, | |
// checked | |
['sd', 'fourD', 'digital'] | |
]}], | |
// checked | |
['sd', 'jumbo', 'fourD', 'digital'] | |
], | |
digital: [ | |
// unchecked | |
[{jumbo: [ | |
// unchecked | |
null, | |
// checked | |
['sd', 'fourD', 'imax'] | |
]}], | |
// checked | |
['sd', 'fourD', 'imax', 'threeD', | |
{jumbo: [ | |
// unchecked | |
['imax', 'threeD', 'fourD', 'sd'], | |
// checked | |
null | |
]} | |
] | |
] | |
}, | |
byAudioType: { | |
subtitled: [ | |
// unchecked | |
null, | |
// checked | |
['dubbed'] | |
], | |
dubbed: [ | |
// unchecked | |
null, | |
// checked | |
['subtitled'] | |
] | |
} | |
}; | |
Enelcine.Showtime.disableIncompatibleTypeFilters = function(options) { | |
options = options || {}; | |
options.element = options.element ? options.element : this; | |
var logPrefix = 'Enelcine.Showtime.disableIncompatibleTypeFilters: '; | |
var elementId = options.element.id; | |
var isChecked = options.element.checked; | |
var disabledClass = options.disabledClass || 'disabled'; | |
var selectedClass = options.selectedClass || 'selected'; | |
var excludingCheckboxesIds = Object.keys(options.rules); | |
var excludingCheckboxes = {}; | |
console.info(logPrefix + 'Disabling/highlighting incompatible filters from ' + elementId); | |
if (excludingCheckboxesIds.indexOf(elementId) < 0) { | |
console.log(logPrefix + 'Caller #' + elementId + ' is not an excludingCheckbox'); | |
return; | |
} | |
var total = 0; | |
excludingCheckboxesIds.forEach(function(ec) { | |
// object as a default to avoid TypeErrors | |
var elem = $(ec) | |
excludingCheckboxes[ec] = elem || {}; | |
if (elem) { | |
total++; | |
// prevent the ugly text selection over the parent label when clicking a checkbox | |
var parentLabel = elem.getParent('label'); | |
parentLabel.setStyle('-webkit-user-select', 'none'); | |
parentLabel.setStyle('-moz-user-select', 'none'); | |
parentLabel.setStyle('user-select', 'none'); | |
} | |
}); | |
if (!total) { | |
console.log(logPrefix + 'No incompatible filters found'); | |
return; | |
} | |
// sets the .checked attribute of the given element | |
// and adds or removes the disabled and selected classes | |
function setChecked(elem, checked, disable) { | |
if (!elem) { | |
console.log(logPrefix + 'Trying to disable unexistent element'); | |
return; | |
} | |
try { | |
if (checked !== null) { | |
elem.checked = checked; | |
} | |
elem.getParent('label')[elem.checked ? 'addClass' : 'removeClass'](selectedClass); | |
elem.getParent('label')[disable ? 'addClass' : 'removeClass'](disabledClass); | |
} catch (e) { | |
console.log(logPrefix + 'ERROR in ' + elem.id + ': ' + e); | |
} | |
} | |
// sets all checkboxes as visually enabled, without modifying its checked state | |
function reset() { | |
Object.each(excludingCheckboxes, function(checkbox) { | |
// do not modify the checked state, only remove the disabled class | |
setChecked(checkbox, null, false); | |
}) | |
} | |
function disableByIds() { | |
if (arguments) { | |
reset(); | |
Array.each(arguments, function(checkboxId) { | |
setChecked(excludingCheckboxes[checkboxId], false, true); | |
}); | |
} | |
} | |
function processRule(elementId, rules) { | |
if (rules === null) { | |
console.log(logPrefix + 'No rules given for elementId ' + elementId); | |
return; | |
} | |
var ids = []; | |
var element = $(elementId); | |
if (!element || element.type != 'checkbox') { | |
throw logPrefix + 'Provided elementId ' + elementId + ' is not a checkbox'; | |
} | |
var index = +element.checked; | |
if ($type(rules) != 'array' || rules.length != 2 | |
|| (rules[index] !== null && $type(rules[index]) != 'array')) { | |
throw logPrefix + 'The rules must be an array with 2 items, each item being either an array or null'; | |
} | |
if (rules[index] === null) { | |
console.log(logPrefix + 'No rule ' + index + ' given for elementId ' + elementId); | |
return; | |
} | |
rules[index].forEach(function(item) { | |
var i = ['string', 'object'].indexOf($type(item)); | |
if (i < 0) { | |
throw logPrefix + 'Malformed rule: expecting array of strings or objects'; | |
} else if (i === 0) { | |
ids.push(item); | |
} else if (i === 1) { | |
var keys = Object.keys(item); | |
if (keys.length > 1) { | |
throw logPrefix + 'Malformed rule: objects must have an elementId as its only key'; | |
} | |
var nestedElementId = keys[0]; | |
var nestedIds = processRule(nestedElementId, item[nestedElementId]); | |
if (!nestedIds) { | |
console.log(logPrefix + 'Nested elementId ' + nestedElementId + ' returns no ids'); | |
return; | |
} | |
//console.log(logPrefix + 'Nested elementId "' + nestedElementId + '" returns ' + nestedIds.join(', ')); | |
nestedIds.forEach(function(id) { | |
ids.push(id); | |
}); | |
} | |
}); | |
return ids; | |
} | |
var ids = processRule(elementId, options.rules[elementId]); | |
console.info( | |
logPrefix + 'Unchecking invalid showtime checkboxes with ids: ' + | |
(ids ? ids.join(', ') : 'NO IDS') | |
); | |
disableByIds.apply(null, ids); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment