Creating custom item
Custom item (green radio-flag)
Custom item from custom item (red radio-flag)
</> Source
<!DOCTYPE html>
<html>
<head>
<title>Creating custom item</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<link rel="stylesheet" type="text/css" href="../../../codebase/fonts/font_roboto/roboto.css"/>
<link rel="stylesheet" type="text/css" href="../../../codebase/dhtmlx.css"/>
<script src="../../../codebase/dhtmlx.js"></script>
<style>
/* green */
div.dhxcombolist_material div.dhxcombo_option div.dhxcombo_checkbox.dhxcombo_radio_green_1 {
background-image: url("../common/flags2/flag_green.png");
background-position: center center;
}
/* red */
div.dhxcombolist_material div.dhxcombo_option div.dhxcombo_checkbox.dhxcombo_radio_red_1 {
background-image: url("../common/flags2/flag_red.png");
background-position: center center;
}
/* unchecked - common */
div.dhxcombolist_material div.dhxcombo_option div.dhxcombo_checkbox.dhxcombo_radio_green_0,
div.dhxcombolist_material div.dhxcombo_option div.dhxcombo_checkbox.dhxcombo_radio_red_0 {
background-image: url("../common/flags2/flag_gray.png");
background-position: center center;
}
/* log */
#log_here {
font-size: 8pt;
font-family: Tahoma;
width: 500px;
height: 120px;
border: 1px solid #cecece;
padding: 2px 5px;
overflow: auto;
}
</style>
<script>
var myCombo, myCombo2;
var eventIndex = 1;
function doOnLoad() {
// green
myCombo = new dhtmlXCombo("combo_zone", "combo", 230, "my_radio_green");
myCombo.load("../common/data2_short.json");
myCombo.enableFilteringMode(true);
// onRadioCheck is a custom event used in custom item type, just as an example
myCombo.attachEvent("onRadioCheck", function(value, state){
log("onRadioCheck event for green, value: "+value+", new state: "+state.toString());
return true;
});
// red
myCombo2 = new dhtmlXCombo("combo_zone2", "combo2", 230, "my_radio_red");
myCombo2.load("../common/data2_short.json");
myCombo2.enableFilteringMode(true);
myCombo2.attachEvent("onRadioCheck", function(value, state){
log("onRadioCheck event for red, value: "+value+", new state: "+state.toString());
return true;
});
}
function log(text) {
var t = document.getElementById("log_here");
t.innerHTML += (eventIndex++)+") "+text+"<br>";
t.scrollTop = t.scrollHeight;
}
// green checkbox
dhtmlXCombo.prototype.modes.my_radio_green = {
// define if top image will present (at least you can use it for margin to justify text)
image: true,
// defile css for image, for better inheritance (see my_radio_red)
image_css: "dhxcombo_checkbox dhxcombo_radio_green_#state#",
option_css: "dhxcombo_option_text dhxcombo_option_text_chbx",
// items pull, here we will keep all items to be able to uncheck them
items: {},
// last checked item within group, will used on loading stage,
// only first item will checked if more than one have "checked" set to true
last_checked: {},
// this is basic render function, called by combo instance
render: function(item, data) {
// item - div created by combo, placed in popup list
// data - item data, json from init/server
// all items from simple combo belong to common parent,
// we will set custom attr to it and collect items from common parent to group,
// this will allow to separate items from several combos on page
if (typeof(item.parentNode._optRbGroup) == "undefined") {
// 1st creation, assign uniq id to parent
item.parentNode._optRbGroup = window.dhx4.newId();
this.items[item.parentNode._optRbGroup] = {}; // storage for items from single combo
}
this.items[item.parentNode._optRbGroup][item._optId] = item;
// check only first item from group
var checked = window.dhx4.s2b(data.checked);
if (checked) {
if (typeof(this.last_checked[item.parentNode._optRbGroup]) == "undefined") {
// first matched item, mark group
this.last_checked[item.parentNode._optRbGroup] = true;
} else {
// group already have checked item, clear flag
checked = false;
}
}
// here you can save some item's params
// value - mandatory, no matter how to save it, you just will need to return it several times
item._conf = {
value: data.value,
css: "",
checked: checked
};
// main item class, make sure if you will change it - you need to add corresponding css
item.className = "dhxcombo_option";
// item text/image if any
// dhxcombo_checkbox - default css for checkbox/image, postfix can be easily modified, see css above
// dhxcombo_option_text dhxcombo_option_text_chbx - also default option text css
// if you plan to use different css rules - make sure you not forgot to add them
// text will saved later
item.innerHTML = "<div class='"+String(this.image_css).replace("#state#",(item._conf.checked?"1":"0"))+"'></div>"+
"<div class='"+this.option_css+"'> </div>";
// add custom attr to radio-button image, to separate what element was clicked
// item._optId - inner option uniq id (different than value), assigned by combo
// can help you to identify your option
item.firstChild._optRbId = item._optId;
// apply css (default code, just for def-code compat)
if (data.css != null) {
item.lastChild.style.cssText += data.css;
item._conf.css = data.css;
}
// apply item text if any, also default code, will copied for "option" mode functionality
// you also can use your own
this.setText(item, data.text);
// return object instance
return this;
},
destruct: function(item) {
// nothing special, just clear storage
this.items[item.parentNode._optRbGroup][item._optId] = null;
item._conf = null;
},
setChecked: function(item, state) {
// check/uncheck item code
item._conf.checked = window.dhx4.s2b(state);
item.firstChild.className = String(this.image_css).replace("#state#",(item._conf.checked?"1":"0"));
// is state==true - we need to turn "off" all other items from the same list
if (state == true) {
for (var a in this.items[item.parentNode._optRbGroup]) {
if (a != item._optId) { // skip current item
this.setChecked(this.items[item.parentNode._optRbGroup][a], false);
}
}
}
},
isChecked: function(item) {
// true if checked
return (item._conf.checked==true);
},
getExtraData: function(item) {
// extra data will added to data returned by getOption()
return {type: "my_radio_green", checked: item._conf.checked, extra_param: "value"};
},
optionClick: function(item, ev, combo) {
// called when option clicked, return true allows selection+confirm, return false - not
// for exaple - return false to prevent list hiding if image was clicked
var r = true;
var t = (ev.target||ev.srcElement);
while (r == true && t != null && t != item) {
// check if node have "custom attr" (was set in render())
if (t._optRbId != null) {
// call custom event, if handler will return true - allow state-change
// do not allow uncheck item by click
if (item._conf.checked == false && combo.callEvent("onRadioCheck", [item._conf.value,!item._conf.checked]) === true) {
this.setChecked(item, !this.isChecked(item));
// also here we need to uncheck any checked button
};
r = false; // return value, false if image was clicked
} 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;
}
};
// copy some basic functionality like setText/getText, setValue, setSelected/isSelected (in-list highlight) from default item "option"
dhtmlXComboExtend("my_radio_green", "option");
// red checkbox, this item actually the same as green but css changed a bit
dhtmlXCombo.prototype.modes.my_radio_red = {
image_css: "dhxcombo_checkbox dhxcombo_radio_red_#state#"
};
dhtmlXComboExtend("my_radio_red", "my_radio_green");
</script>
</head>
<body onload="doOnLoad();">
<h3>Custom item (green radio-flag)</h3>
<div id="combo_zone"></div>
<br>
<h3>Custom item from custom item (red radio-flag)</h3>
<div id="combo_zone2"></div>
<br><br><br><br><br><br><br><br><br><br>
<div id="log_here"></div>
</body>
</html>
Documentation
Check documentation to learn how to use the components and easily implement them in your applications.