/**
|
* jQuery EasyUI 1.5.2
|
*
|
* Copyright (c) 2009-2017 www.jeasyui.com. All rights reserved.
|
*
|
* Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
|
* To use it on other terms please contact us: info@jeasyui.com
|
*
|
*/
|
/**
|
* combobox - jQuery EasyUI
|
*
|
* Dependencies:
|
* combo
|
*
|
*/
|
(function($){
|
function getRowIndex(target, value){
|
var state = $.data(target, 'combobox');
|
return $.easyui.indexOfArray(state.data, state.options.valueField, value);
|
}
|
|
/**
|
* scroll panel to display the specified item
|
*/
|
function scrollTo(target, value){
|
var opts = $.data(target, 'combobox').options;
|
var panel = $(target).combo('panel');
|
var item = opts.finder.getEl(target, value);
|
if (item.length){
|
if (item.position().top <= 0){
|
var h = panel.scrollTop() + item.position().top;
|
panel.scrollTop(h);
|
} else if (item.position().top + item.outerHeight() > panel.height()){
|
var h = panel.scrollTop() + item.position().top + item.outerHeight() - panel.height();
|
panel.scrollTop(h);
|
}
|
}
|
panel.triggerHandler('scroll'); // trigger the group sticking
|
}
|
|
function nav(target, dir){
|
var opts = $.data(target, 'combobox').options;
|
var panel = $(target).combobox('panel');
|
var item = panel.children('div.combobox-item-hover');
|
if (!item.length){
|
item = panel.children('div.combobox-item-selected');
|
}
|
item.removeClass('combobox-item-hover');
|
var firstSelector = 'div.combobox-item:visible:not(.combobox-item-disabled):first';
|
var lastSelector = 'div.combobox-item:visible:not(.combobox-item-disabled):last';
|
if (!item.length){
|
item = panel.children(dir=='next' ? firstSelector : lastSelector);
|
} else {
|
if (dir == 'next'){
|
item = item.nextAll(firstSelector);
|
if (!item.length){
|
item = panel.children(firstSelector);
|
}
|
} else {
|
item = item.prevAll(firstSelector);
|
if (!item.length){
|
item = panel.children(lastSelector);
|
}
|
}
|
}
|
if (item.length){
|
item.addClass('combobox-item-hover');
|
var row = opts.finder.getRow(target, item);
|
if (row){
|
$(target).combobox('scrollTo', row[opts.valueField]);
|
if (opts.selectOnNavigation){
|
select(target, row[opts.valueField]);
|
}
|
}
|
}
|
}
|
|
/**
|
* select the specified value
|
*/
|
function select(target, value, remainText){
|
var opts = $.data(target, 'combobox').options;
|
var values = $(target).combo('getValues');
|
if ($.inArray(value+'', values) == -1){
|
if (opts.multiple){
|
values.push(value);
|
} else {
|
values = [value];
|
}
|
setValues(target, values, remainText);
|
}
|
}
|
|
/**
|
* unselect the specified value
|
*/
|
function unselect(target, value){
|
var opts = $.data(target, 'combobox').options;
|
var values = $(target).combo('getValues');
|
var index = $.inArray(value+'', values);
|
if (index >= 0){
|
values.splice(index, 1);
|
setValues(target, values);
|
}
|
}
|
|
/**
|
* set values
|
*/
|
function setValues(target, values, remainText){
|
var opts = $.data(target, 'combobox').options;
|
var panel = $(target).combo('panel');
|
|
if (!$.isArray(values)){
|
values = values.split(opts.separator);
|
}
|
if (!opts.multiple){
|
values = values.length ? [values[0]] : [''];
|
}
|
|
// unselect the old rows
|
var oldValues = $(target).combo('getValues');
|
if (panel.is(':visible')){
|
panel.find('.combobox-item-selected').each(function(){
|
var row = opts.finder.getRow(target, $(this));
|
if (row){
|
if ($.easyui.indexOfArray(oldValues, row[opts.valueField]) == -1){
|
$(this).removeClass('combobox-item-selected');
|
}
|
}
|
});
|
}
|
$.map(oldValues, function(v){
|
if ($.easyui.indexOfArray(values, v) == -1){
|
var el = opts.finder.getEl(target, v);
|
if (el.hasClass('combobox-item-selected')){
|
el.removeClass('combobox-item-selected');
|
opts.onUnselect.call(target, opts.finder.getRow(target, v));
|
}
|
}
|
});
|
|
var theRow = null;
|
var vv = [], ss = [];
|
for(var i=0; i<values.length; i++){
|
var v = values[i];
|
var s = v;
|
var row = opts.finder.getRow(target, v);
|
if (row){
|
s = row[opts.textField];
|
theRow = row;
|
var el = opts.finder.getEl(target, v);
|
if (!el.hasClass('combobox-item-selected')){
|
el.addClass('combobox-item-selected');
|
opts.onSelect.call(target, row);
|
}
|
}
|
vv.push(v);
|
ss.push(s);
|
}
|
|
if (!remainText){
|
$(target).combo('setText', ss.join(opts.separator));
|
}
|
if (opts.showItemIcon){
|
var tb = $(target).combobox('textbox');
|
tb.removeClass('textbox-bgicon ' + opts.textboxIconCls);
|
if (theRow && theRow.iconCls){
|
tb.addClass('textbox-bgicon ' + theRow.iconCls);
|
opts.textboxIconCls = theRow.iconCls;
|
}
|
}
|
$(target).combo('setValues', vv);
|
panel.triggerHandler('scroll'); // trigger the group sticking
|
}
|
|
/**
|
* load data, the old list items will be removed.
|
*/
|
function loadData(target, data, remainText){
|
var state = $.data(target, 'combobox');
|
var opts = state.options;
|
state.data = opts.loadFilter.call(target, data);
|
|
opts.view.render.call(opts.view, target, $(target).combo('panel'), state.data);
|
|
var vv = $(target).combobox('getValues');
|
$.easyui.forEach(state.data, false, function(row){
|
if (row['selected']){
|
$.easyui.addArrayItem(vv, row[opts.valueField]+'');
|
}
|
});
|
if (opts.multiple){
|
setValues(target, vv, remainText);
|
} else {
|
setValues(target, vv.length ? [vv[vv.length-1]] : [], remainText);
|
}
|
|
opts.onLoadSuccess.call(target, data);
|
}
|
|
/**
|
* request remote data if the url property is setted.
|
*/
|
function request(target, url, param, remainText){
|
var opts = $.data(target, 'combobox').options;
|
if (url){
|
opts.url = url;
|
}
|
param = $.extend({}, opts.queryParams, param||{});
|
// param = param || {};
|
|
if (opts.onBeforeLoad.call(target, param) == false) return;
|
|
opts.loader.call(target, param, function(data){
|
loadData(target, data, remainText);
|
}, function(){
|
opts.onLoadError.apply(this, arguments);
|
});
|
}
|
|
/**
|
* do the query action
|
*/
|
function doQuery(target, q){
|
var state = $.data(target, 'combobox');
|
var opts = state.options;
|
|
var highlightItem = $();
|
var qq = opts.multiple ? q.split(opts.separator) : [q];
|
if (opts.mode == 'remote'){
|
_setValues(qq);
|
request(target, null, {q:q}, true);
|
} else {
|
var panel = $(target).combo('panel');
|
panel.find('.combobox-item-hover').removeClass('combobox-item-hover');
|
panel.find('.combobox-item,.combobox-group').hide();
|
var data = state.data;
|
var vv = [];
|
$.map(qq, function(q){
|
q = $.trim(q);
|
var value = q;
|
var group = undefined;
|
highlightItem = $();
|
for(var i=0; i<data.length; i++){
|
var row = data[i];
|
if (opts.filter.call(target, q, row)){
|
var v = row[opts.valueField];
|
var s = row[opts.textField];
|
var g = row[opts.groupField];
|
var item = opts.finder.getEl(target, v).show();
|
if (s.toLowerCase() == q.toLowerCase()){
|
value = v;
|
if (opts.reversed){
|
highlightItem = item;
|
} else {
|
select(target, v, true);
|
}
|
}
|
if (opts.groupField && group != g){
|
opts.finder.getGroupEl(target, g).show();
|
group = g;
|
}
|
}
|
}
|
vv.push(value);
|
});
|
_setValues(vv);
|
}
|
function _setValues(vv){
|
if (opts.reversed){
|
highlightItem.addClass('combobox-item-hover');
|
} else {
|
setValues(target, opts.multiple ? (q?vv:[]) : vv, true);
|
}
|
}
|
}
|
|
function doEnter(target){
|
var t = $(target);
|
var opts = t.combobox('options');
|
var panel = t.combobox('panel');
|
var item = panel.children('div.combobox-item-hover');
|
if (item.length){
|
item.removeClass('combobox-item-hover');
|
var row = opts.finder.getRow(target, item);
|
var value = row[opts.valueField];
|
if (opts.multiple){
|
if (item.hasClass('combobox-item-selected')){
|
t.combobox('unselect', value);
|
} else {
|
t.combobox('select', value);
|
}
|
} else {
|
t.combobox('select', value);
|
}
|
}
|
var vv = [];
|
$.map(t.combobox('getValues'), function(v){
|
if (getRowIndex(target, v) >= 0){
|
vv.push(v);
|
}
|
});
|
t.combobox('setValues', vv);
|
if (!opts.multiple){
|
t.combobox('hidePanel');
|
}
|
}
|
|
/**
|
* create the component
|
*/
|
function create(target){
|
var state = $.data(target, 'combobox');
|
var opts = state.options;
|
|
$(target).addClass('combobox-f');
|
$(target).combo($.extend({}, opts, {
|
onShowPanel: function(){
|
$(this).combo('panel').find('div.combobox-item:hidden,div.combobox-group:hidden').show();
|
setValues(this, $(this).combobox('getValues'), true);
|
$(this).combobox('scrollTo', $(this).combobox('getValue'));
|
opts.onShowPanel.call(this);
|
}
|
}));
|
|
var p = $(target).combo('panel');
|
p.unbind('.combobox');
|
for(var event in opts.panelEvents){
|
p.bind(event+'.combobox', {target:target}, opts.panelEvents[event]);
|
}
|
}
|
|
function mouseoverHandler(e){
|
$(this).children('div.combobox-item-hover').removeClass('combobox-item-hover');
|
var item = $(e.target).closest('div.combobox-item');
|
if (!item.hasClass('combobox-item-disabled')){
|
item.addClass('combobox-item-hover');
|
}
|
e.stopPropagation();
|
}
|
function mouseoutHandler(e){
|
$(e.target).closest('div.combobox-item').removeClass('combobox-item-hover');
|
e.stopPropagation();
|
}
|
function clickHandler(e){
|
var target = $(this).panel('options').comboTarget;
|
if (!target){return;}
|
var opts = $(target).combobox('options');
|
var item = $(e.target).closest('div.combobox-item');
|
if (!item.length || item.hasClass('combobox-item-disabled')){return}
|
var row = opts.finder.getRow(target, item);
|
if (!row){return;}
|
if (opts.blurTimer){
|
clearTimeout(opts.blurTimer);
|
opts.blurTimer = null;
|
}
|
opts.onClick.call(target, row);
|
var value = row[opts.valueField];
|
if (opts.multiple){
|
if (item.hasClass('combobox-item-selected')){
|
unselect(target, value);
|
} else {
|
select(target, value);
|
}
|
} else {
|
$(target).combobox('setValue', value).combobox('hidePanel');
|
}
|
e.stopPropagation();
|
}
|
function scrollHandler(e){
|
var target = $(this).panel('options').comboTarget;
|
if (!target){return;}
|
var opts = $(target).combobox('options');
|
if (opts.groupPosition == 'sticky'){
|
var stick = $(this).children('.combobox-stick');
|
if (!stick.length){
|
stick = $('<div class="combobox-stick"></div>').appendTo(this);
|
}
|
stick.hide();
|
var state = $(target).data('combobox');
|
$(this).children('.combobox-group:visible').each(function(){
|
var g = $(this);
|
var groupData = opts.finder.getGroup(target, g);
|
var rowData = state.data[groupData.startIndex + groupData.count - 1];
|
var last = opts.finder.getEl(target, rowData[opts.valueField]);
|
if (g.position().top < 0 && last.position().top > 0){
|
stick.show().html(g.html());
|
return false;
|
}
|
});
|
}
|
}
|
|
$.fn.combobox = function(options, param){
|
if (typeof options == 'string'){
|
var method = $.fn.combobox.methods[options];
|
if (method){
|
return method(this, param);
|
} else {
|
return this.combo(options, param);
|
}
|
}
|
|
options = options || {};
|
return this.each(function(){
|
var state = $.data(this, 'combobox');
|
if (state){
|
$.extend(state.options, options);
|
} else {
|
state = $.data(this, 'combobox', {
|
options: $.extend({}, $.fn.combobox.defaults, $.fn.combobox.parseOptions(this), options),
|
data: []
|
});
|
}
|
create(this);
|
if (state.options.data){
|
loadData(this, state.options.data);
|
} else {
|
var data = $.fn.combobox.parseData(this);
|
if (data.length){
|
loadData(this, data);
|
}
|
}
|
request(this);
|
});
|
};
|
|
|
$.fn.combobox.methods = {
|
options: function(jq){
|
var copts = jq.combo('options');
|
return $.extend($.data(jq[0], 'combobox').options, {
|
width: copts.width,
|
height: copts.height,
|
originalValue: copts.originalValue,
|
disabled: copts.disabled,
|
readonly: copts.readonly
|
});
|
},
|
cloneFrom: function(jq, from){
|
return jq.each(function(){
|
$(this).combo('cloneFrom', from);
|
$.data(this, 'combobox', $(from).data('combobox'));
|
$(this).addClass('combobox-f').attr('comboboxName', $(this).attr('textboxName'));
|
});
|
},
|
getData: function(jq){
|
return $.data(jq[0], 'combobox').data;
|
},
|
setValues: function(jq, values){
|
return jq.each(function(){
|
setValues(this, values);
|
});
|
},
|
setValue: function(jq, value){
|
return jq.each(function(){
|
setValues(this, $.isArray(value)?value:[value]);
|
});
|
},
|
clear: function(jq){
|
return jq.each(function(){
|
setValues(this, []);
|
});
|
},
|
reset: function(jq){
|
return jq.each(function(){
|
var opts = $(this).combobox('options');
|
if (opts.multiple){
|
$(this).combobox('setValues', opts.originalValue);
|
} else {
|
$(this).combobox('setValue', opts.originalValue);
|
}
|
});
|
},
|
loadData: function(jq, data){
|
return jq.each(function(){
|
loadData(this, data);
|
});
|
},
|
reload: function(jq, url){
|
return jq.each(function(){
|
if (typeof url == 'string'){
|
request(this, url);
|
} else {
|
if (url){
|
var opts = $(this).combobox('options');
|
opts.queryParams = url;
|
}
|
request(this);
|
}
|
});
|
},
|
select: function(jq, value){
|
return jq.each(function(){
|
select(this, value);
|
});
|
},
|
unselect: function(jq, value){
|
return jq.each(function(){
|
unselect(this, value);
|
});
|
},
|
scrollTo: function(jq, value){
|
return jq.each(function(){
|
scrollTo(this, value);
|
});
|
}
|
};
|
|
$.fn.combobox.parseOptions = function(target){
|
var t = $(target);
|
return $.extend({}, $.fn.combo.parseOptions(target), $.parser.parseOptions(target,[
|
'valueField','textField','groupField','groupPosition','mode','method','url',
|
{showItemIcon:'boolean',limitToList:'boolean'}
|
]));
|
};
|
|
$.fn.combobox.parseData = function(target){
|
var data = [];
|
var opts = $(target).combobox('options');
|
$(target).children().each(function(){
|
if (this.tagName.toLowerCase() == 'optgroup'){
|
var group = $(this).attr('label');
|
$(this).children().each(function(){
|
_parseItem(this, group);
|
});
|
} else {
|
_parseItem(this);
|
}
|
});
|
return data;
|
|
function _parseItem(el, group){
|
var t = $(el);
|
var row = {};
|
row[opts.valueField] = t.attr('value')!=undefined ? t.attr('value') : t.text();
|
row[opts.textField] = t.text();
|
row['selected'] = t.is(':selected');
|
row['disabled'] = t.is(':disabled');
|
if (group){
|
opts.groupField = opts.groupField || 'group';
|
row[opts.groupField] = group;
|
}
|
data.push(row);
|
}
|
};
|
|
var COMBOBOX_SERNO = 0;
|
var defaultView = {
|
render: function(target, container, data){
|
var state = $.data(target, 'combobox');
|
var opts = state.options;
|
|
COMBOBOX_SERNO++;
|
state.itemIdPrefix = '_easyui_combobox_i' + COMBOBOX_SERNO;
|
state.groupIdPrefix = '_easyui_combobox_g' + COMBOBOX_SERNO;
|
state.groups = [];
|
|
var dd = [];
|
var group = undefined;
|
for(var i=0; i<data.length; i++){
|
var row = data[i];
|
var v = row[opts.valueField]+'';
|
var s = row[opts.textField];
|
var g = row[opts.groupField];
|
|
if (g){
|
if (group != g){
|
group = g;
|
state.groups.push({
|
value: g,
|
startIndex: i,
|
count: 1
|
});
|
dd.push('<div id="' + (state.groupIdPrefix+'_'+(state.groups.length-1)) + '" class="combobox-group">');
|
dd.push(opts.groupFormatter ? opts.groupFormatter.call(target, g) : g);
|
dd.push('</div>');
|
} else {
|
state.groups[state.groups.length-1].count++;
|
}
|
} else {
|
group = undefined;
|
}
|
|
var cls = 'combobox-item' + (row.disabled ? ' combobox-item-disabled' : '') + (g ? ' combobox-gitem' : '');
|
dd.push('<div id="' + (state.itemIdPrefix+'_'+i) + '" class="' + cls + '">');
|
if (opts.showItemIcon && row.iconCls){
|
dd.push('<span class="combobox-icon ' + row.iconCls + '"></span>');
|
}
|
dd.push(opts.formatter ? opts.formatter.call(target, row) : s);
|
dd.push('</div>');
|
}
|
$(container).html(dd.join(''));
|
}
|
};
|
|
$.fn.combobox.defaults = $.extend({}, $.fn.combo.defaults, {
|
valueField: 'value',
|
textField: 'text',
|
groupPosition: 'static', // or 'sticky'
|
groupField: null,
|
groupFormatter: function(group){return group;},
|
mode: 'local', // or 'remote'
|
method: 'post',
|
url: null,
|
data: null,
|
queryParams: {},
|
showItemIcon: false,
|
limitToList: false, // limit the inputed values to the listed items
|
view: defaultView,
|
|
keyHandler: {
|
up: function(e){nav(this,'prev');e.preventDefault()},
|
down: function(e){nav(this,'next');e.preventDefault()},
|
left: function(e){},
|
right: function(e){},
|
enter: function(e){doEnter(this)},
|
query: function(q,e){doQuery(this, q)}
|
},
|
inputEvents: $.extend({}, $.fn.combo.defaults.inputEvents, {
|
blur: function(e){
|
var target = e.data.target;
|
var opts = $(target).combobox('options');
|
if (opts.reversed || opts.limitToList){
|
if (opts.blurTimer){
|
clearTimeout(opts.blurTimer);
|
}
|
opts.blurTimer = setTimeout(function(){
|
var existing = $(target).parent().length;
|
if (existing){
|
if (opts.reversed){
|
$(target).combobox('setValues', $(target).combobox('getValues'));
|
} else if (opts.limitToList){
|
doEnter(target);
|
}
|
opts.blurTimer = null;
|
}
|
},50);
|
}
|
}
|
}),
|
panelEvents: {
|
mouseover: mouseoverHandler,
|
mouseout: mouseoutHandler,
|
click: clickHandler,
|
scroll: scrollHandler
|
},
|
filter: function(q, row){
|
var opts = $(this).combobox('options');
|
return row[opts.textField].toLowerCase().indexOf(q.toLowerCase()) >= 0;
|
},
|
formatter: function(row){
|
var opts = $(this).combobox('options');
|
return row[opts.textField];
|
},
|
loader: function(param, success, error){
|
var opts = $(this).combobox('options');
|
if (!opts.url) return false;
|
$.ajax({
|
type: opts.method,
|
url: opts.url,
|
data: param,
|
dataType: 'json',
|
success: function(data){
|
success(data);
|
},
|
error: function(){
|
error.apply(this, arguments);
|
}
|
});
|
},
|
loadFilter: function(data){
|
return data;
|
},
|
finder:{
|
getEl:function(target, value){
|
var index = getRowIndex(target, value);
|
var id = $.data(target, 'combobox').itemIdPrefix + '_' + index;
|
return $('#'+id);
|
},
|
getGroupEl:function(target, gvalue){
|
var state = $.data(target, 'combobox');
|
var index = $.easyui.indexOfArray(state.groups, 'value', gvalue);
|
var id = state.groupIdPrefix + '_' + index;
|
return $('#'+id);
|
},
|
getGroup:function(target, p){
|
var state = $.data(target, 'combobox');
|
var index = p.attr('id').substr(state.groupIdPrefix.length+1);
|
return state.groups[parseInt(index)];
|
},
|
getRow:function(target, p){
|
var state = $.data(target, 'combobox');
|
var index = (p instanceof $) ? p.attr('id').substr(state.itemIdPrefix.length+1) : getRowIndex(target, p);
|
return state.data[parseInt(index)];
|
}
|
},
|
|
onBeforeLoad: function(param){},
|
onLoadSuccess: function(data){},
|
onLoadError: function(){},
|
onSelect: function(record){},
|
onUnselect: function(record){},
|
onClick: function(record){}
|
});
|
})(jQuery);
|