/**
* @author Ryan Johnson
* @copyright 2008 PersonalGrid Corporation
* @package LivePipe UI
* @license MIT
* @url http://livepipe.net/control/rating
* @require prototype.js, livepipe.js
*/
/*global Prototype, Class, Option, $, $A, Control, $break, */
if(typeof(Prototype) == "undefined") {
throw "Control.SelectMultiple requires Prototype to be loaded."; }
if(typeof(Object.Event) == "undefined") {
throw "Control.SelectMultiple requires Object.Event to be loaded."; }
Control.SelectMultiple = Class.create({
select: false,
container: false,
numberOfCheckedBoxes: 0,
checkboxes: [],
hasExtraOption: false,
initialize: function(select,container,options){
this.options = {
checkboxSelector: 'input[type=checkbox]',
nameSelector: 'span.name',
labelSeparator: ', ',
valueSeparator: ',',
afterChange: Prototype.emptyFunction,
overflowString: function(str){
return str.truncate();
},
overflowLength: 30
};
Object.extend(this.options,options || {});
this.select = $(select);
this.container = $(container);
this.checkboxes = (typeof(this.options.checkboxSelector) == 'function') ?
this.options.checkboxSelector.bind(this)() :
this.container.getElementsBySelector(this.options.checkboxSelector);
var value_was_set = false;
if(this.options.value){
value_was_set = true;
this.setValue(this.options.value);
delete this.options.value;
}
this.hasExtraOption = false;
this.checkboxes.each(function(checkbox){
checkbox.observe('click',this.checkboxOnClick.bind(this,checkbox));
}.bind(this));
this.select.observe('change',this.selectOnChange.bind(this));
this.countAndCheckCheckBoxes();
if(!value_was_set) {
this.scanCheckBoxes(); }
this.notify('afterChange',this.select.options[this.select.options.selectedIndex].value);
},
countAndCheckCheckBoxes: function(){
this.numberOfCheckedBoxes = this.checkboxes.inject(0,function(number,checkbox){
checkbox.checked = (this.select.options[this.select.options.selectedIndex].value == checkbox.value);
var value_string = this.select.options[this.select.options.selectedIndex].value;
var value_collection = $A(value_string.split ? value_string.split(this.options.valueSeparator) : value_string);
var should_check = value_collection.any(function(value) {
if (!should_check && checkbox.value == value) {
return true; }
}.bind(this));
checkbox.checked = should_check;
if(checkbox.checked) {
++number; }
return number;
}.bind(this));
},
setValue: function(value_string){
this.numberOfCheckedBoxes = 0;
var value_collection = $A(value_string.split ? value_string.split(this.options.valueSeparator) : value_string);
this.checkboxes.each(function(checkbox){
checkbox.checked = false;
value_collection.each(function(value){
if(checkbox.value == value){
++this.numberOfCheckedBoxes;
checkbox.checked = true;
}
}.bind(this));
}.bind(this));
this.scanCheckBoxes();
},
selectOnChange: function(){
this.removeExtraOption();
this.countAndCheckCheckBoxes();
this.notify('afterChange',this.select.options[this.select.options.selectedIndex].value);
},
checkboxOnClick: function(checkbox){
this.numberOfCheckedBoxes = this.checkboxes.findAll(function (c) {
return c.checked;
}).length;
this.scanCheckBoxes();
this.notify('afterChange', this.numberOfCheckedBoxes === 0 ? "" :
this.select.options[this.select.options.selectedIndex].value);
},
scanCheckBoxes: function(){
switch(this.numberOfCheckedBoxes){
case 1:
this.checkboxes.each(function(checkbox){
if(checkbox.checked){
$A(this.select.options).each(function(option,i){
if(option.value == checkbox.value){
this.select.options.selectedIndex = i;
throw $break;
}
}.bind(this));
throw $break;
}
}.bind(this));
break;
case 0:
this.removeExtraOption();
break;
default:
this.addExtraOption();
break;
}
},
getLabelForExtraOption: function(){
var label = (typeof(this.options.nameSelector) == 'function' ?
this.options.nameSelector.bind(this)() :
this.container.getElementsBySelector(this.options.nameSelector).inject([],function(labels,name_element,i){
if(this.checkboxes[i].checked) {
labels.push(name_element.innerHTML); }
return labels;
}.bind(this))
).join(this.options.labelSeparator);
return (label.length >= this.options.overflowLength && this.options.overflowLength > 0) ?
(typeof(this.options.overflowString) == 'function' ? this.options.overflowString(label) : this.options.overflowString) :
label;
},
getValueForExtraOption: function(){
return this.checkboxes.inject([],function(values,checkbox){
if(checkbox.checked) {
values.push(checkbox.value); }
return values;
}).join(this.options.valueSeparator);
},
addExtraOption: function(){
this.removeExtraOption();
this.hasExtraOption = true;
this.select.options[this.select.options.length] = new Option(this.getLabelForExtraOption(),this.getValueForExtraOption());
this.select.options.selectedIndex = this.select.options.length - 1;
},
removeExtraOption: function(){
if(this.hasExtraOption){
this.select.remove(this.select.options.length - 1);
this.hasExtraOption = false;
}
}
});
Object.Event.extend(Control.SelectMultiple);