📄 selectbox.js
字号:
* @param {String} text option title
* @param {String} value option value
* @param {Boolean} selected selection state
* @param {Boolean} defaultSelected selection state
* @param {Boolean} sort
* @param {Boolean} update if 'false' is not explicitly specified, option is added immediately
* @return {Boolean} addition state
*/
this.addOption = function ( text /* :String */
,value /* :String */
,defaultSelected /* :Boolean */
,selected /* :Boolean */
,sort /* :Boolean */
,update /* :Boolean */) /* :Boolean */ {
if (!isScalar(text) || !isScalar(value)) return false;
if (isUndefined(update)) update = true;
options[options.length] = { 'text' : text
,'value' : value
,'defaultSelected' : defaultSelected
,'selected' : selected
,'visible' : true
,'fixed' : false
};
if (update && node.options.length<maxlistlen) {
node.options[node.options.length] = new Option ( text ,value ,defaultSelected ,selected);
node.options[node.options.length-1].__idx = options.length-1;
}
/*
* overload the 'toString' method
*/
options[options.length-1].toString = __toString;
/*
* update the track
*/
__saveOptionsTrack ('added', text, value);
if (sort) this.sort();
return true;
}
/**
* Adds the array of the options to the list
*
* @param {Array} list array of the options
* @param {Boolean} sort
* @return {Boolean}
* @scope public
*/
this.addOptionsList = function ( list /* :Array */
,sort /* :Boolean */ ) /* :Boolean */ {
if (isUndefined(list) || !isNumeric(list.length) || list.length<1) return false;
for (var i=0, lL=list.length; i<lL; i++) {
var li = list[i];
if (li.text) self.addOption (li.text, li.value?li.value:li.text
,Boolean(li.selected), Boolean(li.defaultSelected)
,false, false);
else if (isScalar(li)) self.addOption (li, li
,false, false
,false, false);
else if (li[0]) self.addOption (li[0], li[1]?li[1]:li[0]
,Boolean(li[2]), Boolean(li[3])
,false, false);
}
if (sort) this.sort();
else this.updateOptions();
return true;
}
//-------------------------------------------
// OPTIONS TRANSFER
//-------------------------------------------
/**
* Copies selected options to another select box
*
* @param {SelectBox} to SelectBox to copy options to
* @param {Boolean} autosort enables autosort on update
* @param {RegExp} regex string to keep matching options
* @return {Boolean} move state
*/
this.copySelectedOptions = function ( to /* :Selectbox*/
,regex /* :RegExp */
,autosort /* :Boolean */) /* :Boolean */{
if (!to || !to.addOption) return false;
/*
* Unselect matching options, if required
*/
if (regex) {
self.unselectMatchingOptions(regex);
}
/*
* Copy them over
*/
for (var i=0, oL=options.length; i<oL; i++) {
if (options[i].selected && options[i].visible) {
to.addOption (options[i].text, options[i].value, options[i].selected, options[i].defaultSelected);
}
}
if (autosort) {
to.sort();
} else {
to.updateOptions();
}
return true;
}
/**
* Copies all options to another SelectBox
*
* @param {SelectBox} to SelectBox to copy options to
* @param {Boolean} autosort enables autosort on update
* @param {RegExp} regex string to keep matching options
* @return {Boolean} move state
*/
this.copyAllOptions = function ( to /* :Selectbox*/
,regex /* :RegExp */
,autosort /* :Boolean */) /* :Boolean */{
if (!to || !to.addOption) return false;
self.selectAllOptions();
self.copySelectedOptions(to,regex,autosort);
}
/**
* Moves selected options to another select box
*
* This function moves options between select boxes. Works best with
* multi-select boxes to create the common Windows control effect.
* Passes all selected values from the first object to the second
* object and re-sorts each box.
* If a third argument of 'false' is passed, then the lists are not
* sorted after the move.
* If a fourth string argument is passed, this will function as a
* Regular Expression to match against the TEXT or the options. If
* the text of an option matches the pattern, it will NOT be moved.
* It will be treated as an unmoveable option.
* You can also put this into the <SELECT> object as follows:
* onDblClick="moveSelectedOptions(this,this.form.target)
* This way, when the user double-clicks on a value in one box, it
* will be transferred to the other (in browsers that support the
* onDblClick() event handler).
*
* @param {SelectBox} to SelectBox to copy options to
* @param {Boolean} autosort enables autosort on update
* @param {RegExp} regex string to keep matching options
* @return {Boolean} move state
*/
this.moveSelectedOptions = function ( to /* :Selectbox*/
,regex /* :RegExp */
,autosort /* :Boolean */) /* :Boolean */{
if (!to || !to.addOption) return false;
/*
* Unselect matching options, if required
*/
if (regex) {
self.unselectMatchingOptions(regex);
}
/*
* Reset selection on the target box
*/
to.unselectAllOptions();
/*
* Move them over
*/
var opts = self.removeSelectedOptions(false);
for (var i=opts.length-1; i>=0; i--) {
to.addOption (opts[i].text, opts[i].value, opts[i].defaultSelected, opts[i].selected);
}
if (autosort) {
to.sort();
self.sort();
} else {
to.updateOptions();
self.updateOptions();
}
return true;
}
/**
* Move all options to another SelectBox
*
* @param {SelectBox} to SelectBox to copy options to
* @param {Boolean} autosort enables autosort on update
* @param {RegExp} regex string to keep matching options
* @return {Boolean} move state
*/
this.moveAllOptions = function ( to /* :Selectbox*/
,regex /* :RegExp */
,autosort /* :Boolean */) /* :Boolean */{
if (!to || !to.addOption) return false;
self.selectAllOptions();
self.moveSelectedOptions(to,regex,autosort);
}
//-------------------------------------------
// OPTIONS MOVEMENT
//-------------------------------------------
/**
* Swap 2 options
*
* @param {Number} idx1
* @param {Number} idx2
* @return {Boolean} swap state
* @scope public
*/
this.swapOptions = function ( idx1 /* :Number */
,idx2 /* :Number */) /* :Boolean */ {
if (!options[idx1] || options[idx2]) return false;
var tmp = options[idx1];
options[idx1] = options[idx2];
options[idx2] = tmp;
this.updateOptions();
}
/**
* Moves specified option up
*
* @return {Boolean} operation state
* @scope public
*/
this.moveSelectedOptionsUp = function () /* :Boolean */{
var res = false;
for (i=0, oL=options.length; i<oL; i++) {
if (options[i].selected && options[i].visible) {
if (i != 0 && !options[i-1].selected && !options[i-1].fixed) {
this.swapOptions(i,i-1);
obj.options[i-1].selected = true;
}
}
}
}
/**
* Moves specified option up
*
* @return {Boolean} operation state
* @scope public
*/
this.moveSelectedOptionsUp = function () /* :Boolean */{
var res = false;
for (oL=i=options.length-1; i>=0; i--) {
if (options[i].selected && options[i].visible) {
if (i != oL && !options[i+1].selected && !options[i+1].fixed) {
this.swapOptions(i,i+1);
obj.options[i+1].selected = true;
}
}
}
}
//-------------------------------------------
// SELECTION MOVEMENT
//-------------------------------------------
/**
* Selects the option by it's id
*
* @param {Number} id option id
* @param {Boolean} force
* @return {Boolean}
* @scope public
*/
this.selectOption = function (id /* :Number */, force) {
if (!isNumber(id) || (!force && (id<0 || !node.options[Math.abs(id)]))) return false;
self.unselectAllOptions();
if (id >= node.options.length) {
id = node.options.length-1;
} else if (id < 0) {
id = 0;
}
node.options[id].selected = true;
options[node.options[id].__idx].selected = true;
return true;
}
/**
* Moves selection 1 position higher on the list, allows to cycle movement
* Don't use __updateOptions here, because it affects the visual performance
*
* @param {Boolean} cyclic allows to move selection from the beginning to the end of the list
* @scope public
*/
this.selectPrev = function (cycle /* :Boolean */) /* :void */{
var res = false
,selected = false;
for (i=node.options.length-1; i>=0; i--) {
if (selected || node.options[i].selected) {
var tmp = node.options[i].selected;
node.options[i].selected = selected;
options[node.options[i].__idx].selected = selected;
selected = tmp;
}
}
if (selected) {
if (cycle) {
for (i=node.options.length-1; i>=0; i--) {
node.options[0].selected = false;
node.options[i].selected = true;
options[node.options[0].__idx].selected = false;
options[node.options[i].__idx].selected = true;
break;
}
} else {
node.options[0].selected = true;
options[node.options[0].__idx].selected = true;
}
}
}
/**
* Moves selection 1 position lower on the list, allows to cycle movement
* Don't use __updateOptions here, because it affects the visual performance
*
* @param {Boolean} cyclic allows to move selection from the end to the beginning of the list
* @scope public
*/
this.selectNext = function (cycle /* :Boolean */) /* :void */ {
var res = false
,selected = false;
for (i=0, oL=node.options.length; i<oL; i++) {
if (selected || node.options[i].selected) {
var tmp = node.options[i].selected;
node.options[i].selected = selected;
options[node.options[i].__idx].selected = selected;
selected = tmp;
}
}
if (selected) {
if (cycle) {
for (i=0, oL=node.options.length; i<oL; i++) {
options[node.options[oL-1].__idx].selected = false;
options[node.options[i].__idx].selected = true;
node.options[oL-1].selected = false;
node.options[i].selected = true;
break;
}
} else {
node.options[oL-1].selected = true;
options[node.options[oL-1].__idx].selected = true;
}
}
}
/*
* let's call a constructor
*/
__construct(id);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -