/*
Product Name: dhtmlxSuite
Version: 5.2.0
Edition: Professional
License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
Copyright UAB Dinamenta http://www.dhtmlx.com
*/
function dhtmlXCombo(parentId, formName, width, optionType, tabIndex) {
// console.info("allow html in options?");
// console.info("add placeholder?");
// console.info("iframe for IE6");
var that = this;
var apiObj = null;
var skin = null;
if (typeof(parentId) == "object" && !parentId.tagName) {
apiObj = parentId;
parentId = apiObj.parent;
width = apiObj.width;
formName = apiObj.name;
optionType = apiObj.mode;
skin = apiObj.skin;
}
this.cont = (typeof(parentId)=="string"?document.getElementById(parentId):parentId);
this.conf = {
skin: null,
form_name: formName||"dhxcombo",
combo_width: (parseInt(width)||this.cont.offsetWidth||120)-(dhx4.isFF||dhx4.isIE||dhx4.isChrome||dhx4.isOpera?2:0),
combo_image: false,
combo_focus: false,
opts_type: (typeof(optionType)=="string" && typeof(this.modes[optionType]) !="undefined" ? optionType : "option"),
opts_count: 8, // count of visible items
opts_count_min: 3, // min count of visible items (when near screen edge)
opts_width: null,
item_h: null,
list_zi_id: window.dhx4.newId(), // "dhxcombo_list_"+window.dhx4.newId(), // z-index id
allow_free_text: true,
allow_empty_value: true, // allow empty value in combo (when free_text not allowed)
free_text_empty: false, // when free text not allowed and incorrect value entered restore last selected value or reset to empty
enabled: true,
btn_left: ((window.dhx4.isIE6||window.dhx4.isIE7||window.dhx4.isIE8) && typeof(window.addEventListener) == "undefined" ? 1:0), // 1 for IE8-
// search in r/o mode
ro_mode: false,
ro_text: "",
ro_tm: null,
ro_tm_time: 750,
// images
img_path: "",
img_def: "",
img_def_dis: true, // if set to true - img_def used for disabled
// templates
template: {
header: true, // render header in multicolumn mode, added in 4.5.1
input: "#text#",// template for top-input
option: "#text#" // template for option text
},
// filtering
f_func: null,
f_mode: false, // "start", "between"
f_url: false,
f_cache: false,
f_cache_data: {},
f_dyn: false,
f_dyn_end: false, // check if last response have opts
f_mask: "", // last loaded mask from server
f_ac: true, // autocomplete if f_mode:"start" filtering mode
f_ac_text: "",
f_server_tm: null,
f_server_last: "",
f_loading: false,
// scroll tm
s_tm: null,
s_time: 200,
s_mode: "select", // type of subload request calling, 'select' last item or 'scroll' to last item
// hover-selected
last_hover: null,
last_selected: null,
last_match: null,
last_text: "",
last_value: "",
tm_hover: null,
tm_confirm_blur: null,
// nav settings
clear_click: false,
clear_blur: false,
clear_bsp: false,
clear_key: false,
// skin params
i_ofs: 23, // top-image offset
sp: {
dhx_skyblue: {list_ofs: 1, hdr_ofs: 1, scr_ofs: 1},
dhx_web: {list_ofs: 0, hdr_ofs: 1, scr_ofs: 0},
dhx_terrace: {list_ofs: 1, hdr_ofs: 1, scr_ofs: 1},
material: {list_ofs: 0, hdr_ofs: 1, scr_ofs: 1}
},
// autowidth for columns mode
col_w: null
};
this.conf.combo_image = (this.modes[this.conf.opts_type].image==true);
this.t = {}; // options will here
this.base = document.createElement("DIV");
//this.base.className = "dhxcombo_"+this.conf.skin;
this.base.style.width = this.conf.combo_width+"px";
this.base.innerHTML = ""+
""+ // value
""+ // new_value
"
"+
(this.conf.combo_image?""+this.modes[this.conf.opts_type].getTopImage(null, this.conf.enabled)+"
":"");
this.cont.appendChild(this.base);
this.list = document.createElement("DIV");
this.list._listId = window.dhx4.newId(); // used when combo attached to popup
this.list.style.display = "none";
document.body.insertBefore(this.list, document.body.firstChild);
// auto-subload logic
this._doOnListScroll = function() {
if (that.conf.s_tm != null) window.clearTimeout(that.conf.s_tm);
that.conf.s_tm = window.setTimeout(that._doOnListScrollAction, that.conf.s_time);
}
this._doOnListScrollAction = function() {
that.conf.s_tm = null;
if (that.conf.s_mode == "scroll" && that.list.scrollHeight - that.list.scrollTop - 10 < that.list.clientHeight) {
that._subloadRequest();
}
}
if (typeof(window.addEventListener) == "function") {
this.list.addEventListener("scroll", this._doOnListScroll, false);
} else {
this.list.attachEvent("onscroll", this._doOnListScroll);
}
// apply skin
this.setSkin(skin||window.dhx4.skin||(typeof(dhtmlx)!="undefined"?dhtmlx.skin:null)||window.dhx4.skinDetect("dhxcombo")||"material");
this._updateTopImage = function(id) {
if (!this.conf.combo_image) return;
if (id != null) {
this.base.lastChild.innerHTML = this.t[id].obj.getTopImage(this.t[id].item, this.conf.enabled);
} else {
this.base.lastChild.innerHTML = this.modes[this.conf.opts_type].getTopImage(null, this.conf.enabled);
}
}
/* filtering */
this._filterOpts = function(hiddenMode) {
if (this.conf.f_server_tm) window.clearTimeout(this.conf.f_server_tm);
var k = String(this.base.firstChild.value).replace(new RegExp(this._fixRE(this.conf.f_ac_text)+"$","i"),"");
if (this.conf.f_server_last == k.toLowerCase()) {
this._checkForMatch();
return;
}
// check if user-filter specified
if (this.conf.f_url != null && this.checkEvent("onDynXLS")) {
this.conf.f_server_last = k.toLowerCase();
this.callEvent("onDynXLS", [k]);
return;
}
if (this.conf.f_url) {
// server
if (k.length == 0) {
this.conf.f_server_last = k.toLowerCase();
this.clearAll();
return;
}
// check cache
if (this.conf.f_cache == true && this.conf.f_cache_data[k] != null) {
// load from cache
this.clearAll();
this.conf.f_server_last = k.toLowerCase();
for (var q=0; q 0 && that.base.offsetHeight > 0);
if (v == true && that.conf.enabled == true && that.conf.combo_focus == true && hiddenMode !== true) {
// autocomplete if any
if (that.conf.f_ac && that.conf.f_mode == "start" && that.conf.clear_bsp == false && that.list.firstChild != null) {
// autocomplete
var sid = that.list.firstChild._optId;
var text = String(that.t[sid].obj.getText(that.list.firstChild, true));
if (k == that.base.firstChild.value && String(text).toLowerCase().indexOf(String(k).toLowerCase()) === 0) {
that.base.firstChild.value = text;
that.conf.f_ac_text = text.substr(k.length);
that._selectRange(k.length, text.length);
}
}
that._showList(true);
that._checkForMatch();
}
callBack = null;
}
if (window.dhx4.ajax.method == "post") {
window.dhx4.ajax.post(that.conf.f_url, params, callBack);
} else if (window.dhx4.ajax.method == "get") {
window.dhx4.ajax.get(that.conf.f_url+(String(that.conf.f_url).indexOf("?")>=0?"&":"?")+params, callBack);
}
},200);
}
} else {
// client
this.conf.f_server_last = k.toLowerCase();
var r = (k.length==0?true:new RegExp((this.conf.f_mode=="start"?"^":"")+this._fixRE(k),"i"));
var acText = null;
for (var a in this.t) {
var t = false;
if (r !== true) {
if (this.conf.f_func != null) {
var option = this._getOption(this.t[a].item._optId, q);
t = (this.conf.f_func.apply(window, [k, option]) == true);
} else {
var text = this.t[a].obj.getText(this.t[a].item, true);
t = (r.test(text) == true);
}
}
if (r === true || t == true) {
this.t[a].item.style.display = "";
if (acText == null && k.length > 0) acText = String(this.t[a].obj.getText(this.t[a].item, true));
} else {
this.t[a].item.style.display = "none";
}
}
if (this.conf.f_ac && this.conf.f_mode == "start" && this.conf.clear_bsp == false && acText != null) {
this.conf.f_ac_text = acText.replace(new RegExp("^"+k,"i"),"");
this.base.firstChild.value = acText;
this._selectRange(this.conf.f_server_last.length, this.base.firstChild.value.length);
}
// if any text selected and backspace pressed - clear highlight
// usefull for "between" mode
if (this.conf.f_mode == "between" && this.conf.clear_bsp == true) {
this._checkForMatch(true);
}
if (hiddenMode !== true) {
this._showList(true);
this._checkForMatch();
}
}
}
this._searchRO = function(s) {
if (this.conf.ro_tm) window.clearTimeout(this.conf.ro_tm);
this.conf.ro_text += s;
this._showList();
for (var q=0; q
...
img_src - also add the 4th parameter to combobox constructor - "image"
checked - checkbox state, for combo with "checkbox" type, 0 by default
*/
var t = {add:false,options:[]};
var root = (selectToObj==true?data:data.getElementsByTagName("complete"));
if (root.length > 0) {
if (window.dhx4.s2b(root[0].getAttribute("add")) == true) t.add = true;
var nodes = root[0].childNodes;
for (var q=0; q
for (var a in {width:1, css:1, header:1, option:1}) {
if (col.getAttribute(a) != null) colData[a] = col.getAttribute(a);
}
// extra header and option if any
//
for (var a in {header:1, option:1}) {
var h = col.getElementsByTagName(a);
if (h[0] != null && h[0].firstChild != null) colData[a] = window.dhx4._xmlNodeValue(h[0]);
}
if (template.columns == null) template.columns = [];
template.columns.push(colData);
}
col = null;
}
}
}
n = null;
}
this.setTemplate(template);
}
// option
if (String(nodes[q].tagName).toLowerCase() == "option") {
var optSelected = false;
if (selectToObj == true) {
optSelected = (t.options.length==selectedIndex);
} else {
optSelected = window.dhx4.s2b(nodes[q].getAttribute("selected"));
}
var opt = {
value: nodes[q].getAttribute("value"),
text: window.dhx4._xmlNodeValue(nodes[q]),
selected: optSelected,
checked: window.dhx4.s2b(nodes[q].getAttribute("checked"))
};
// images
for (var a in {img:1,img_dis:1,img_src:1,img_src_dis:1,css:1}) {
if (nodes[q].getAttribute(a) != null) opt[a] = nodes[q].getAttribute(a);
}
// text
for (var w=0; w hide list if any
this._doOnBodyMouseDown = function() {
if (that.conf.clear_click) {
that.conf.clear_click = false;
return;
}
that._confirmSelect("blur");
}
// input focus/blur
this._doOnInputFocus = function() {
that.conf.clear_blur = false;
// if forus back to input - cancel confirm (occured when user clicked on arrow while list opened)
if (that.conf.tm_confirm_blur) window.clearTimeout(that.conf.tm_confirm_blur);
// ev
if (that.conf.combo_focus == false) {
that.conf.combo_focus = true;
if (that.conf.skin == "material" && that.base.className.match(/dhxcombo_actv/) == null) {
that.base.className += " dhxcombo_actv";
}
that.callEvent("onFocus",[]);
}
}
this._doOnInputBlur = function() {
if (that.conf.clear_blur == true) {
that.conf.clear_blur = false;
return;
}
// start confirm tm
if (that.conf.tm_confirm_blur) window.clearTimeout(that.conf.tm_confirm_blur);
that.conf.tm_confirm_blur = window.setTimeout(function(){
if (that.conf.clear_click == false) {
// if (that._isListVisible()) that._hideList();
that._confirmSelect("blur");
that.conf.combo_focus = false;
if (that.conf.skin == "material" && that.base.className.match(/dhxcombo_actv/) != null) {
that.base.className = that.base.className.replace(/\s*dhxcombo_actv/gi, "");
}
that.callEvent("onBlur",[]);
}
},20);
}
// input events, typing/filtering
this._doOnInputKeyUp = function(e) {
e = e||event;
if (that.conf.f_mode != false) {
that.conf.clear_bsp = (e.keyCode==8||e.keyCode==46); // backspace(8) and delete(46)
that._filterOpts();
return;
} else {
that._checkForMatch();
}
}
this._doOnInputKeyDown = function(e) {
e = e||event;
// console.log("onkeypress ", e.keyCode, " ", e.charCode)
// up (38) /down (40)
if ((e.keyCode == 38 || e.keyCode == 40) && !e.ctrlKey && !e.shiftKey && !e.altKey) {
if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
e.cancelBubble = true;
that._keyOnUpDown(e.keyCode==38?-1:1);
}
// F2
if (e.keyCode == 113) {
if (!that._isListVisible()) {
that._showList();
if (that.base.firstChild.value == that.conf.last_text) {
that._setSelected(that.conf.last_selected, true, true);
that.base.firstChild.value = that.conf.last_text;
that.conf.f_server_last = that.base.firstChild.value.toLowerCase();
} else {
that.conf.f_server_last = that.base.firstChild.value.toLowerCase();
if (that.conf.f_mode == false) that._checkForMatch();
}
} else {
}
}
// esc
if (e.keyCode == 27) {
// cancel operation, restore last value
if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
e.cancelBubble = true;
that._cancelSelect();
}
// enter
if (e.keyCode == 13) {
if (e.preventDefault) e.preventDefault(); // if combo attached to form
that._confirmSelect("kbd");
}
// selection in r/o mode
if (that.conf.ro_mode == true && ((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 65 && e.keyCode <= 90))) {
that._searchRO(String.fromCharCode(e.keyCode).toLowerCase());
e.cancelBubble = true;
}
that.conf.clear_key = true;
that.callEvent("onKeyPressed",[e.keyCode||e.charCode]);
}
this._doOnInputKeyPress = function(e) {
if (that.conf.clear_key) {
that.conf.clear_key = false;
return;
}
e = e||event;
that.callEvent("onKeyPressed",[e.keyCode||e.charCode]);
}
this._keyOnUpDown = function(dir) {
// select(just hover) next/prev item in a list
var item = null;
if (this.conf.last_hover) {
item = this.t[this.conf.last_hover].item;
} else if (this.conf.last_selected) {
item = this.t[this.conf.last_selected].item;
}
if (!item && this._getListVisibleCount() == 0) return;
if (item != null && item.style.display != "") item = null;
this._showList();
if (item != null) {
// check if item highlighted
if (this.t[item._optId].obj.isSelected(item)) item = this._getNearItem(item, dir);
} else {
item = this.list.firstChild;
if (item.style.display != "") item = this._getNearItem(item, 1);
}
if (item == null) return; // first/last
this._setSelected(item._optId, true, true);
if (this.conf.f_mode == false) {
this.base.firstChild.value = this.t[item._optId].obj.getText(item, true);
} else {
var text = String(this.t[item._optId].obj.getText(item, true));
if (this.conf.f_mode == "start" && this.conf.f_ac == true) {
if (text.toLowerCase().indexOf(this.conf.f_server_last) === 0) {
// try to find match and select part of text
this.conf.f_ac_text = text.substring(this.conf.f_server_last.length, text.length);
this.base.firstChild.value = text;
this._selectRange(this.conf.f_server_last.length, this.base.firstChild.value.length);
} else {
// insert all text and select
this.base.firstChild.value = text;
this.conf.f_server_last = this.base.firstChild.value.toLowerCase();
this._selectRange(0, this.base.firstChild.value.length);
}
} else {
// just insert text into main input
this.base.firstChild.value = text;
this.conf.f_server_last = this.base.firstChild.value.toLowerCase();
}
}
//
item = null;
}
this.conf.evs_nodes = [
{node: document.body, evs: {mousedown: "_doOnBodyMouseDown"}},
{node: this.base, evs: {mousedown: "_doOnBaseMouseDown"}},
{node: this.base.firstChild, evs: {keyup: "_doOnInputKeyUp", keydown: "_doOnInputKeyDown", keypress: "_doOnInputKeyPress", focus: "_doOnInputFocus", blur: "_doOnInputBlur"}},
{node: this.list, evs: {mousemove: "_doOnListMouseMove", mousedown: "_doOnListMouseDown", mouseup: "_doOnListMouseUp", mouseout: "_doOnListMouseOut"}}
];
for (var q=0; q
if (typeof(selectId) == "string") selectId = document.getElementById(selectId);
// collect params
var comboWidth = width || selectId.offsetWidth;
var formName = selectId.getAttribute("name")||null;
// add node
var comboNode = document.createElement("SPAN");
selectId.parentNode.insertBefore(comboNode, selectId);
// combo mode
var comboMode = selectId.getAttribute("mode")||selectId.getAttribute("opt_type")||"option";
// init combo
var combo = new dhtmlXCombo(comboNode, formName, comboWidth, comboMode);
comboNode = null;
var imagePath = selectId.getAttribute("imagePath");
if (imagePath) combo.setImagePath(imagePath);
var defImg = selectId.getAttribute("defaultImage");
var defImgDis = selectId.getAttribute("defaultImageDis");
if (window.dhx4.s2b(defImgDis) == true) defImgDis = true;
if (defImg != null || defImgDis != null) combo.setDefaultImage(defImg, defImgDis);
// options
var opts = combo._xmlToObj([selectId], true, selectId.selectedIndex);
if (opts.options.length > 0) combo.addOption(opts.options);
opts = null;
// remove select
selectId.parentNode.removeChild(selectId);
selectId = null;
return combo;
};
/* common funcs */
dhtmlXCombo.prototype.setName = function(name) { // change name for form
this.conf.form_name = name;
this.base.childNodes[1].name = name;
this.base.childNodes[2].name = name.replace(/(\[.*)?$/, "_new_value$1");
};
dhtmlXCombo.prototype.readonly = function(mode) { // enable/disable readonly mode
if (window.dhx4.s2b(mode)) {
this.base.firstChild.setAttribute("readOnly", "true");
this.conf.ro_mode = true;
} else {
this.base.firstChild.removeAttribute("readOnly");
this.conf.ro_mode = false;
}
};
dhtmlXCombo.prototype.setPlaceholder = function(text) { // new in 4.0, limited support
if (typeof(text) == "undefined" || text == null) text = "";
this.base.firstChild.setAttribute("placeholder", String(text));
};
dhtmlXCombo.prototype.setTemplate = function(tpl) {
for (var a in tpl) {
if (typeof(this.conf.template[a]) != "undefined") {
if (a == "header") {
this.conf.template[a] = window.dhx4.s2b(tpl[a]);
} else {
this.conf.template[a] = String(tpl[a]);
}
}
};
// columns
if (tpl.columns != null) {
this._mcMakeTemplate(tpl.columns);
} else {
this._mcDetachHeader();
}
// template changed, update combo text and update rendered options
for (var a in this.t) {
this.t[a].obj.setText(this.t[a].item, this.t[a].item._conf.text);
};
this._confirmSelect("template");
};
dhtmlXCombo.prototype.setSkin = function(skin) {
if (skin == this.conf.skin) return;
this.conf.skin = skin;
this.base.className = "dhxcombo_"+this.conf.skin+(this.conf.enabled?"":" dhxcombo_disabled");
this.list.className = "dhxcombolist_"+this.conf.skin+(this.hdr!=null?" dhxcombolist_multicolumn":"");
if (this.hdr != null) this.hdr.className = "dhxcombolist_"+this.conf.skin+" dhxcombolist_hdr";
this.conf.i_ofs = (skin == "material"?26:23);
this._adjustBase();
};
dhtmlXCombo.prototype.getInput = function() { // returns input, new in 4.0
return this.base.firstChild;
};
dhtmlXCombo.prototype.getButton = function() { // returns button, new in 4.0
return this.base.childNodes[this.base.childNodes.length-(this.conf.combo_image?2:1)];
};
dhtmlXCombo.prototype.getList = function() { // do we need it?
return this.list;
};
dhtmlXCombo.prototype.getBase = function() { // do we need it?
return this.base;
};
dhtmlXCombo.prototype.getParent = function() { // do we need it?
return this.DOMParent;
};
dhtmlXCombo.prototype.forEachOption = function(handler) { // iterator, new in 4.0
for (var q=0; q= this.list.childNodes.length) return;
var id = this.list.childNodes[index]._optId;
this._setSelected(id, this._isListVisible(), true);
this._confirmSelect("script");
};
dhtmlXCombo.prototype.unSelectOption = function() { // unselects option
if (this.conf.last_hover != null) {
this.t[this.conf.last_hover].obj.setSelected(this.t[this.conf.last_hover].item, false);
this.conf.last_hover = null;
}
this.base.firstChild.value = "";
if (this.conf.f_mode != false) {
this._filterOpts(true);
}
this._hideList();
this._updateTopImage(null);
this._confirmSelect("script");
};
dhtmlXCombo.prototype.confirmValue = function() {
this._confirmSelect("script");
};
/* enable/disable */
dhtmlXCombo.prototype.enable = function(mode) {
mode = (typeof(mode)=="undefined"?true:window.dhx4.s2b(mode));
if (this.conf.enabled == mode) return;
this.conf.enabled = mode;
if (mode) {
this.base.className = "dhxcombo_"+this.conf.skin;
this.base.firstChild.removeAttribute("disabled");
} else {
this._hideList();
this.base.className = "dhxcombo_"+this.conf.skin+" dhxcombo_disabled";
this.base.firstChild.setAttribute("disabled","true");
}
// update disabled image if any
this._updateTopImage(this.conf.last_selected);
};
dhtmlXCombo.prototype.disable = function(mode) {
mode = (typeof(mode)=="undefined"?true:window.dhx4.s2b(mode));
this.enable(!mode);
};
dhtmlXCombo.prototype.isEnabled = function() {
return (this.conf.enabled==true);
};
/* visibility */
dhtmlXCombo.prototype.show = function(mode) {
if (typeof(mode) == "undefined") mode = true; else mode = window.dhx4.s2b(mode);
this.base.style.display = (mode==true?"":"none");
};
dhtmlXCombo.prototype.hide = function(mode) {
if (typeof(mode) == "undefined") mode = true;
this.show(!mode);
};
dhtmlXCombo.prototype.isVisible = function() {
return (this.base.style.display=="");
};
/* filtering */
dhtmlXCombo.prototype.setFilterHandler = function(f) {
if (typeof(f) == "function") {
this.conf.f_func = f;
this.conf.f_mode = true;
this.conf.f_dyn = this.conf.f_cache = this.conf.f_url = null;
} else if (typeof(f) == "string" && typeof(window[f]) == "function") {
this.conf.f_func = window[f];
this.conf.f_mode = true;
this.conf.f_dyn = this.conf.f_cache = this.conf.f_url = null;
} else {
this.conf.f_func = null;
}
};
dhtmlXCombo.prototype.enableFilteringMode = function(mode, url, cache, dyn) {
if (mode == true || mode == "between") {
this.conf.f_mode = (mode==true?"start":"between");
if (url) {
this.conf.f_url = url;
this.conf.f_cache = window.dhx4.s2b(cache);
this.conf.f_dyn = window.dhx4.s2b(dyn);
} else {
this.conf.f_url = null;
this.conf.f_cache = false;
this.conf.f_dyn = false;
}
} else {
this.conf.f_mode = false;
this.conf.f_url = null;
this.conf.f_cache = false;
this.conf.f_dyn = false;
}
};
dhtmlXCombo.prototype.filter = function(handler, showList) { // new in 4.0
for (var q=0; qb?r:-1*r);
});
} else if (typeof(mode) == "function" || typeof(window[mode]) == "function") {
if (typeof(window[mode]) == "function") mode = window[mode];
r.sort(function(a,b){
return mode.apply(window, [a[1],b[1]]);
});
}
// reorder
while (this.list.childNodes.length > 0) this.list.removeChild(this.list.lastChild);
for (var q=0; q onBottom) onBottom = null;
var itemsToShow = Math.min((onBottom==null?onTop:onBottom), this.conf.opts_count, itemsCount);
var h = (itemsToShow a2) {
// on bottom
this.list.scrollTop = y2-this.list.clientHeight+(this.hdr!=null&&this.conf.template.header==true?-this.conf.sp[this.conf.skin].scr_ofs:0);
}
};
/* in-list selection/highlighting */
dhtmlXCombo.prototype._setSelected = function(id, scrollToItem, updateImg, mouseMove) {
this.conf.temp_selected = null;
if (updateImg) this._updateTopImage(id);
if (id != null && this.conf.last_hover == id) {
if (scrollToItem) this._scrollToItem(id);
return;
}
if (this.conf.last_hover != null) {
this.t[this.conf.last_hover].obj.setSelected(this.t[this.conf.last_hover].item, false);
this.conf.last_hover = null;
if (id == null) this.callEvent("onSelectionChange", []);
}
if (id != null) {
this.t[id].obj.setSelected(this.t[id].item, true);
this.conf.last_hover = id;
if (mouseMove != true) {
this.conf.temp_selected = id;
this.callEvent("onSelectionChange", []);
}
// last item selected, try subload
if (this.conf.s_mode == "select" && this.t[id].item == this.t[id].item.parentNode.lastChild) this._subloadRequest();
if (scrollToItem) this._scrollToItem(id);
}
};
// auto-subload
dhtmlXCombo.prototype._subloadRequest = function() {
if (this.conf.f_url != null && this.conf.f_dyn == true && this.conf.f_dyn_end == false) {
var params = "mask="+encodeURIComponent(this.conf.f_mask)+"&pos="+this.list.childNodes.length;
var t = this;
var callBack = function(r){
// cache
if (t.conf.f_cache) t.conf.f_cache_data[t.conf.f_mask].data.push(r.xmlDoc.responseXML);
var k = t.list.childNodes.length;
// skip clear opts w/o add='true'
t.conf.f_loading = true;
t.load(r.xmlDoc.responseXML);
t.conf.f_loading = false;
// if no more opts left on server, stop dyn requests
if (k == t.list.childNodes.length) {
t.conf.f_dyn_end = true;
if (t.conf.f_cache) t.conf.f_cache_data[t.conf.f_mask].dyn_end = true;
}
callBack = t = null;
}
if (window.dhx4.ajax.method == "post") {
window.dhx4.ajax.post(this.conf.f_url, params, callBack);
} else if (window.dhx4.ajax.method == "get") {
window.dhx4.ajax.get(this.conf.f_url+(String(this.conf.f_url).indexOf("?")>=0?"&":"?")+params, callBack);
}
}
};
/* add / remove options */
dhtmlXCombo.prototype.addOption = function(value, text, css, img, selected) {
// selected added in 4.0
/*
single option, 4 params
z.addOption(value, text, css, img_src);
value, text, css (css string attached to the option, optional), img_src (path to the option icon image, just for "image" combo type)
several options, array of array (in this case you can't use 4th parameter img_src - improve?)
z.addOption([["a","option A", "color:red;"],[],[],...]);
several options, as an array of objects (you can use 4 parameters)
z.addOption([{value: "a", text: "option A", img_src: "../images/blue.gif", css:"color:red;"},{},{}...]);
*/
var toSelect = null;
if (!(value instanceof Array)) {
// single option
var id = this._renderOption({value:value, text:text, css:css, img:img});
if (toSelect == null && window.dhx4.s2b(selected) == true) toSelect = id;
} else {
// array with opts
for (var q=0; q"+(cols[q].option||" ")+"
";
h += ""+(cols[q].header||" ")+"
";
//
this.conf.col_w += w+1;
}
var w = 500;
var k = document.createElement("DIV");
k.style.position = "absolute";
k.style.top = "10px";
k.style.left = -w*2+"px";
k.style.width = w+"px";
k.style.height = "50px";
k.style.overflowY = "scroll";
k.innerHTML = "
";
document.body.appendChild(k);
this.conf.col_w += w-k.firstChild.offsetWidth+10;
k.parentNode.removeChild(k);
k = null;
this.conf.template.option = t;
this._mcAttachHeader(h);
this.list.className += " dhxcombolist_multicolumn";
};
dhtmlXCombo.prototype._mcAttachHeader = function(text) {
if (this.hdr == null) {
this.hdr = document.createElement("DIV");
this.hdr.className = "dhxcombolist_"+this.conf.skin+" dhxcombolist_hdr";
this.hdr.style.display = "none";
this.list.parentNode.insertBefore(this.hdr, this.list);
if (typeof(window.addEventListener) == "function") {
this.hdr.addEventListener("mousedown", this._doOnListMouseDown, false);
} else {
this.hdr.attachEvent("onmousedown", this._doOnListMouseDown);
}
// remove top-image from input
if (this.conf.opts_type == "checkbox" && this.conf.combo_image == true) {
this.conf.combo_image = false;
if (this.base.lastChild.className.match(/dhxcombo_top_image/) != null) this.base.removeChild(this.base.lastChild);
this._adjustBase();
}
}
this.hdr.innerHTML = ""+text+"
";
};
dhtmlXCombo.prototype._mcDetachHeader = function() {
if (this.hdr != null) {
if (typeof(window.addEventListener) == "function") {
this.hdr.removeEventListener("mousedown", this._doOnListMouseDown, false);
} else {
this.hdr.detachEvent("onmousedown", this._doOnListMouseDown);
}
this.hdr.parentNode.removeChild(this.hdr);
this.hdr = null;
}
this.conf.col_w = null;
this.conf.item_h = null;
};
/****************************************************************************************************************************************************************************************************************/
/* options */
dhtmlXCombo.prototype.modes = {}; // option types
dhtmlXCombo.prototype.doWithItem = function(index, method, param1, param2) { // wrapper to perform opts operations from combo
// get option inner id
var id = (index >= 0 && index < this.list.childNodes.length ? this.list.childNodes[index]._optId : null);
if (id == null) return null; // opt no found
if (typeof(this.t[id].obj[method]) != "function") return null; // function not found
// generate params
var params = [this.t[id].item];
for (var q=2; q ";
if (data.css != null) {
item.lastChild.style.cssText = data.css;
item._conf.css = data.css;
}
this.setText(item, data.text);
return this;
},
destruct: function(item) {
item._conf = null;
},
update: function(item, data) {
item._conf.value = data.value;
item._conf.css = data.css;
item.lastChild.style.cssText = data.css;
this.setText(item, data.text);
},
setText: function(item, text, skip) {
item._conf.text = text;
var t = (typeof(text) == "object" ? window.dhx4.template(item._tpl.option, this.replaceHtml(item._conf.text, skip), true) : window.dhx4.trim(this.replaceHtml(item._conf.text, skip)||""));
item.lastChild.innerHTML = (t.length==0?" ":t);
},
getText: function(item, asStringInput, asStringOption) {
if (window.dhx4.s2b(asStringInput) && typeof(item._conf.text) == "object") return window.dhx4.template(item._tpl.input, item._conf.text, true);
if (window.dhx4.s2b(asStringOption) && typeof(item._conf.text) == "object") return window.dhx4.template(item._tpl.option, item._conf.text, true);
return item._conf.text;
},
getValue: function(item) {
return item._conf.value;
},
getCss: function(item) {
return item._conf.css;
},
setSelected: function(item, state) {
item.className = "dhxcombo_option"+(state?" dhxcombo_option_selected":"");
},
isSelected: function(item) {
return String(item.className).indexOf("dhxcombo_option_selected") >= 0;
},
getExtraData: function(item) {
// optional function,
// adds extra data to option object returned by getOption()
return {type: "option"};
},
replaceHtml: function(text, skip) {
if (text === 0) text = "0";
if (this.html == true) return text;
if (typeof(skip) == "undefined" || skip == null) skip = {};
if (typeof(text) == "object" && text) {
var t = {};
for (var a in text) {
t[a] = (skip[a]==true?text[a]:this.replaceHtml(text[a]));
}
} else {
var t = (text||"").replace(/[\<\>\&\s]/g, function(t){
switch (t) {
case "<": return "<";
case ">": return ">";
case "&": return "&";
case " ": return " ";
}
return t;
});
}
return t;
}
};
/****************************************************************************************************************************************************************************************************************/
dhtmlXCombo.prototype.modes.checkbox = {
image: true, // disable in code if multicolumn
html: false,
image_css: "dhxcombo_checkbox dhxcombo_chbx_#state#",
option_css: "dhxcombo_option_text dhxcombo_option_text_chbx",
render: function(item, data) {
if (this.image_css_regexp == null) this.image_css_regexp = new RegExp(this.image_css.replace("#state#","\\d*"));
item._conf = {value: data.value, css: "", checked: window.dhx4.s2b(data.checked)};
item.className = "dhxcombo_option";
var skip = {}; // skip html replace
if (data.multicol == true) {
data.text.checkbox = " ";
skip.checkbox = true;
item.innerHTML = "";
} else {
item.innerHTML = ""+
"
";
}
if (data.css != null) {
item.lastChild.style.cssText += data.css;
item._conf.css = data.css;
}
this.setText(item, data.text, skip);
return this;
},
setChecked: function(item, state) {
item._conf.checked = window.dhx4.s2b(state);
var css = String(this.image_css).replace("#state#",(item._conf.checked?"1":"0"));
this._changeChbxCss(item.childNodes, css);
},
_changeChbxCss: function(nodes, css) {
for (var q=0; q 0) {
this._changeChbxCss(nodes[q].childNodes, css);
}
}
},
isChecked: function(item) {
return (item._conf.checked==true);
},
getExtraData: function(item) {
return {type: "checkbox", checked: item._conf.checked};
},
optionClick: function(item, ev, combo) {
// called when option clicked, return true allows selection+confirm, return false - not
var r = true;
var t = (ev.target||ev.srcElement);
while (r == true && t != null && t != item && t.className != null) {
if (t.className.match(this.image_css_regexp) != null) {
var args = [item._conf.value, !item._conf.checked];
if (combo.callEvent("onBeforeCheck", args) === true) {
this.setChecked(item, !this.isChecked(item));
combo.callEvent("onCheck", args);
};
r = false;
args = null;
} else {
t = t.parentNode;
}
}
t = combo = item = null;
return r;
},
getTopImage: function(item, enabled) {
// returns html for top image
// if item not specified - default image
// enabled specify if combo enabled
return "";
},
topImageClick: function(item, combo) {
// called when user clicked on top-image,
// return true/false to allow defailt action (open/close list) ot not
// for checkbox - perform default action
return true;
}
};
dhtmlXComboExtend("checkbox", "option");
dhtmlXCombo.prototype.setChecked = function(index, mode) {
this.doWithItem(index, "setChecked", mode);
};
dhtmlXCombo.prototype.getChecked = function(index) {
// return checked values
var t = [];
for (var q=0; q"+
"
";
if (data.css != null) {
item.lastChild.style.cssText += data.css;
item._conf.css = data.css;
}
this.setText(item, data.text);
this.setImage(item, data.img, data.img_dis, data.img_path, data.img_def, data.img_def_dis);
return this;
},
update: function(item, data) {
item._conf.value = data.value;
item._conf.css = data.css;
item.lastChild.style.cssText = data.css;
this.setText(item, data.text);
this.setImage(item, data.img, data.img_dis, data.img_path, data.img_def, data.img_def_dis);
},
setImage: function(item, img, img_dis, path, def, def_dis) {
// image
if (img != null && img.length > 0) {
img = path+img;
} else if (def != null && def.length > 0) {
img = path+def;
} else {
img = null;
}
// image
if (img_dis != null && img_dis.length > 0) {
img_dis = path+img_dis;
} else if (def_dis != null && def_dis.length > 0) {
img_dis = path+def_dis;
} else if (def_dis == true) {
img_dis = img;
} else {
img_dis = null;
}
item._conf.img = img;
item._conf.img_dis = img_dis;
item.firstChild.style.backgroundImage = (img!=null?"url("+img+")":"none");
},
getExtraData: function(item) {
return {type: "image"};
},
getTopImage: function(item, enabled) {
// returns html for top image
// if item not specified - default image
var a = (enabled?"img":"img_dis");
if (item != null && item._conf[a] != null) return "";
return "";
}
};
dhtmlXComboExtend("image", "option");
dhtmlXCombo.prototype.setDefaultImage = function(img, imgDis) {
// sets default image
// set imgDis to tru to use the same image as for enabled combo, default
if (img != null) this.conf.img_def = img;
if (imgDis != null) this.conf.img_def_dis = imgDis;
};
dhtmlXCombo.prototype.setImagePath = function(path) {
this.conf.img_path = path;
};