diff --git a/pqselect.dev.js b/pqselect.dev.js
index fb7f4f6..0c5ed4c 100644
--- a/pqselect.dev.js
+++ b/pqselect.dev.js
@@ -6,4 +6,786 @@
* http://paramquery.com/license
*
*/
-( function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( [
"jquery",
"jui/core",
"jui/widget",
"jui/position"
], factory );
} else {
factory( jQuery );
}
}(function($) {
"use strict";
$.support.touch = 'ontouchend' in document;
var fn = {};
fn.options = function() {
var KC = $.ui.keyCode;
return {
radio: false,
singlePlaceholder: 'Select an option',
checkbox: false,
displayText: '{0} of {1} selected',
maxDisplay: 4,
maxSelect: 0,
multiplePlaceholder: 'Select options',
selectallText: 'Select All',
closeOnWindowScroll: true,
closeOnWindowResize: true,
itemCls: 'pq-select-item ui-corner-all ui-state-default',
bootstrap: {on: false,
btn: 'btn btn-default',
popupCont: 'panel panel-default',
selectCls: 'label label-info',
itemCls: 'label label-default',
closeIcon: 'glyphicon glyphicon-remove',
searchIcon: 'glyphicon glyphicon-search',
hoverCls: ''
},
position: {
my: 'left top',
at: 'left bottom',
collision: 'flipfit'
},
kcOpen: [KC.DOWN, KC.ENTER, KC.UP],
deselect: true,
hoverCls: 'pq-state-hover',
search: true,
searchRule: 'contain',
_selectCls: 'pq-state-select',
selectCls: 'ui-state-highlight',
width: null,
maxSelectReach: null,
maxSelectExceed: null
};
}();
fn._setButtonWidth = function() {
var $select = this.element;
$select.show();
var o = this.options,
width = o.width ? o.width : $select[0].offsetWidth;
$select.hide();
this.$button.width(width);
};
fn._create = function() {
var that = this,
o = this.options,
bootstrap = o.bootstrap,
bts = bootstrap.on,
$select = this.element,
name = $select.attr('name'),
multiple = $select.attr('multiple'),
$button = $(
["
"].join(""));
if(bts){
o.selectCls += ' '+bootstrap.selectCls;
o.itemCls += ' '+bootstrap.itemCls;
}
this.$button = $button;
this.multiple = multiple ? true : false;
this.selector = 'label.pq-select-option-label.ui-state-enable:visible';
this._setButtonWidth();
$select.after($button);
$button.attr("name", name);
$button.addClass($select.attr("class"));
$select.addClass("pq-select");
this._extractData();
this._createPopup();
this._createMenu();
$button.on({
click: function(evt) {
if(o.disabled) return;
var $parent = $(this).parent('.pq-select-item'),
indx = parseInt($parent.attr("data-id"));
that.select(indx, false);
that.setText();
that.focus();
that.triggerChange();
return false;
}
}, '.ui-icon-close');
$button.on({
click: function(evt) {
if(o.disabled) return;
that.toggle();
return false;
},
focus: function(evt) {
if(o.disabled) return;
$(this).addClass('ui-state-hover');
},
blur: function(evt) {
$(this).removeClass('ui-state-hover');
},
mousedown: function(evt) {
if(o.disabled) return;
$(this).addClass('ui-state-active');
},
mouseup: function(evt) {
if(o.disabled) return;
$(this).removeClass('ui-state-active');
},
keydown: function(evt) {
if(o.disabled) return;
var keyCode = evt.keyCode,
kcOpen = o.kcOpen,
KC = $.ui.keyCode;
if ($.inArray(keyCode, kcOpen) !== -1) {
that.open();
}
else if (keyCode === KC.ESCAPE) {
that.close();
}
else if (keyCode === KC.SPACE) {
that.toggle();
}
}
});
this.setText();
var EN = this.eventNamespace;
$(window).on("resize"+EN, function(evt){
that.onWindowResize(evt);
});
$(window).on("scroll"+EN, function(evt){
that.onWindowScroll(evt);
});
};
fn.onWindowResize = function(){
if(this.options.closeOnWindowResize) this.close();
};
fn.onWindowScroll = function(){
if(this.options.closeOnWindowScroll) this.close();
};
fn.focus = function() {
var that = this;
if (!$.support.touch) {
that.$search.focus();
}
};
$.paramquery = $.paramquery || {};
$.paramquery.scrollView = function($ele) {
var ele = $ele[0],
top = ele.offsetTop,
ht = ele.offsetHeight,
parent = ele.offsetParent,
scrollTop = parent.scrollTop,
htParent = parent.clientHeight;
if (ht + top > htParent + scrollTop) {
$(parent).scrollTop(ht + top - htParent);
}
else if (top < scrollTop) {
$(parent).scrollTop(top);
}
};
$.paramquery.pageMove = function($ele, selector, next) {
var $nextele,
ht = $ele[0].offsetHeight,
parent = $ele[0].offsetParent,
htParent = parent.clientHeight;
do {
$nextele = $ele[next ? 'nextAll' : 'prevAll'](selector);
if ($nextele.length) {
$nextele = $($nextele[0]);
ht += $nextele[0].offsetHeight;
$ele = $nextele;
}
else
break;
} while (ht < htParent)
$.paramquery.scrollView($ele);
return $ele;
};
fn._move = function(next) {
var $label = this.$lastlabelHighlight;
if ($label && $label.length) {
var $next = $label[next ? 'nextAll' : 'prevAll'](this.selector);
if ($next.length) {
$next = $($next[0]);
this._highlight($next);
}
}
else {
this._hightlight();
}
};
fn._onkeydown = function(evt) {
var keyCode = evt.keyCode,
KC = $.ui.keyCode;
if (keyCode === KC.DOWN || keyCode === KC.UP) {
this._move(keyCode === KC.DOWN);
return false;
}
else if (keyCode === KC.PAGE_DOWN || keyCode === KC.PAGE_UP) {
var $label = $.paramquery.pageMove(
this.$lastlabelHighlight,
this.selector,
(keyCode === KC.PAGE_DOWN)
);
this._highlight($label);
return false;
}
if (keyCode === KC.TAB) {
this.close();
return false;
}
else if (keyCode === KC.ESCAPE) {
this.close();
}
else if (keyCode === KC.ENTER) {
if (this.$lastlabelHighlight) {
this.$lastlabelHighlight.trigger('label_changed');
return false;
}
}
};
fn.search = function(val) {
var data = this.data,
searchRule = this.options.searchRule,
contain = searchRule === 'contain';
for (var i = 0, len = data.length; i < len; i++) {
var rowData = data[i],
text = rowData.text.toUpperCase(),
indx = text.indexOf(val);
rowData.searchIndx = null;
if (indx === -1) {
rowData.hidden = true;
}
else if (contain === false && indx > 0) {
rowData.hidden = true;
}
else {
rowData.hidden = false;
rowData.searchIndx = indx;
}
}
};
fn._onkeyupsearch = function(evt) {
var $input = $(evt.target),
val = $.trim($input.val()).toUpperCase(),
data = this.data,
keyCode = evt.keyCode,
KC = $.ui.keyCode,
arr = [KC.DOWN, KC.UP, KC.ENTER, KC.PAGE_DOWN, KC.PAGE_UP];
if ($.inArray(keyCode, arr) === -1) {
this.search(val);
this._createMenu();
this.positionPopup();
}
};
fn._onChange = function(indx, checked) {
var that = this,
o = that.options,
multiple = this.multiple,
maxSelect = o.maxSelect,
selIndx = that.selectIndx;
if (multiple) {
if (checked) {
if (maxSelect && selIndx.length >= maxSelect) {
that._trigger('maxSelectExceed', null, {
option: that.$options[indx]
});
that.focus();
return false;
}
}
}
else if (selIndx.length) {
var prevIndx = selIndx[0];
if (indx === prevIndx) {
return false;
}
if (checked) {
this.select(prevIndx, false);
}
}
this.select(indx, checked);
that.setText();
that.setSelectAllState();
if (multiple) {
if (maxSelect && selIndx.length >= maxSelect) {
if (that._trigger('maxSelectReach', null, {
option: that.$options[indx]
}) !== false) {
that.close();
}
}
else {
that.focus();
}
}
else {
that.close();
}
this.triggerChange();
};
fn.setSelectAllState = function() {
var $chk = this.$popup.find(".pq-select-all input");
if ($chk.length) {
var data = this.data,
enabled = 0,
selectAll = 0;
for (var i = 0, len = data.length; i < len; i++) {
var rowData = data[i],
selected = rowData.selected,
disabled = rowData.disabled;
if (disabled) {
continue;
}
enabled++;
if (selected) {
selectAll++;
}
}
if (enabled === selectAll) {
$chk.prop('checked', true);
}
else {
$chk.prop('checked', false);
}
}
};
fn.getInstance = function() {
return {select: this};
};
fn.select = function(indx, add) {
var that = this,
selIndx = that.selectIndx,
o = this.options,
rowData = this.data[indx],
$option = $(that.$options[indx]),
$label = that.$popup.find("#pq-option-" + this.uuid + "-" + indx),
$input = $label.find("input");
$label[add ? 'addClass' : 'removeClass'](o._selectCls + ' ' +o.selectCls);
$input.prop('checked', add);
rowData.selected = add;
if (that.multiple) {
if (add) {
selIndx.push(indx);
}
else {
var indx2 = $.inArray(indx, selIndx);
selIndx.splice(indx2, 1);
}
$option.prop('selected', add);
}
else {
if (add) {
if(selIndx.length){
this.data[selIndx[0]].selected=false;
}
selIndx[0] = indx;
$option.prop('selected', add);
}
else {
that.selectIndx = [0];
this.data[0].selected = true;
$(that.$options[0]).prop('selected', true);
}
}
};
fn.triggerChange = function() {
this.element.trigger('change');
};
fn._extractData = function() {
var data = this.data = [],
$select = this.element,
$options = $select.find('option,optgroup'),
grouping = false,
disabled_group = false,
optgroup;
this.$options = $select.find('option');
for (var i = 0, len = $options.length; i < len; i++) {
var option = $options[i],
$option = $(option);
if (option.nodeName.toLowerCase() == 'optgroup') {
optgroup = $option.attr('label');
grouping = true;
disabled_group = $option.prop('disabled');
continue;
}
var selected = $option.prop('selected');
var disabled = $option.prop('disabled');
if(!disabled && grouping){
disabled = disabled_group;
}
var text = $option.text();
data.push({selected: selected, disabled: disabled, text: text, optgroup: optgroup });
}
this.grouping = grouping;
};
fn.refresh = function() {
this.search("");
this._setButtonWidth();
this._createPopup();
this._createMenu();
this.setText();
};
fn.refreshData = function() {
this._extractData();
this.refresh();
};
fn._createPopup = function() {
var that = this,
data = this.data,
o = this.options,
bootstrap = o.bootstrap,
bts = bootstrap.on,
multiple = that.multiple,
searchHTML = "",
headerHTML = "";
if (multiple && o.selectallText && !o.maxSelect) {
headerHTML = [""].join('');
}
if (o.search) {
searchHTML = [""].join("");
}
var $popupCont = $([""].join(''));
$popupCont.css({"font-family": this.$button.css("font-family"),
"font-size": this.$button.css("font-size")});
var $popup = $popupCont.children("div.pq-select-popup");
$popup.on({
keydown: function(evt) {
return that._onkeydown(evt);
}
});
$popup.find('.ui-icon-close').on({
click: function(evt) {
that.close();
return false;
}
});
$popup.on({
change: function(evt) {
var $select = that.element,
$input = $(this),
checked = $input.prop('checked') ? true : false,
data = that.data,
$options = that.$options;
for (var i = 0; i < data.length; i++) {
var rowData = data[i];
if (!rowData.disabled && rowData.selected !== checked) {
rowData.selected = checked;
$($options[i]).prop('selected', checked);
}
}
that._createMenu();
that.setText();
that.focus();
that.triggerChange();
}
}, 'label.pq-select-all input');
$popup.on({
mouseenter: function(evt) {
that._highlight($(this));
},
label_changed: function(evt) {
var $label = $(this),
id = $label.attr("id");
if (id) {
var checked = !$label.hasClass(o._selectCls),
indx = parseInt(id.split("-")[3]);
return that._onChange(indx, checked);
}
}
}, 'label.pq-select-option-label.ui-state-enable');
if((multiple && o.checkbox) || (!multiple && o.radio)){
$popup.on({
click: function(){
var $label = $(this).closest('label');
$label.trigger('label_changed');
}
},'label.pq-select-option-label.ui-state-enable input');
}
else{
$popup.on({
click: function(evt) {
$(this).trigger('label_changed');
}
}, 'label.pq-select-option-label.ui-state-enable');
}
if (this.$popupCont) {
this.$popupCont.remove();
}
this.$popupCont = $popupCont;
this.$popup = $popup;
this.$search = $popup.find(".pq-select-search-input").on({
keyup: function(evt) {
return that._onkeyupsearch(evt);
}
});
$(document.body).append($popupCont);
this.setSelectAllState();
};
fn._createMenu = function() {
var that = this,
data = this.data,
uuid = this.uuid,
o = this.options,
searchIndx,
searchLen = o.search ? $.trim(this.$search.val()).length : 0,
selectCls = ' ' + o._selectCls + ' '+ o.selectCls + ' ',
multiple = that.multiple,
type = multiple ? (o.checkbox ? 'type="checkbox"' : "") : (o.radio ? 'type="radio"' : ""),
textCls = type ? "pq-left-input" : (this.grouping ? "pq-left-group" : ""),
disabled, disabledCls,
selectIndx = that.selectIndx = [],
li = [],
poptgroup;
for (var i = 0; i < data.length; i++) {
var rowData = data[i],
disabled = rowData.disabled,
selected = rowData.selected,
text = rowData.text,
optgroup = rowData.optgroup;
if (selected) {
selectIndx.push(i);
}
if (rowData.hidden) {
continue;
}
if (poptgroup !== optgroup) {
li.push("", optgroup, "
");
poptgroup = optgroup;
}
var
checkedAttr = selected ? ' checked="checked" ' : "",
checkedCls = selected ? selectCls : "",
disabledAttr = disabled ? ' disabled="disabled" ' : "",
disabledCls = disabled ? "ui-state-disabled" : "ui-state-enable",
style = "";
if (i === 0 && text === "") {
continue;
}
if (searchLen) {
searchIndx = rowData.searchIndx;
text = text.substr(0, searchIndx) +
"" +
text.substr(searchIndx, searchLen) + "" +
text.substr(searchIndx + searchLen, text.length);
}
li.push(
""
);
}
var $menu = $([""].join(""));
if (this.$menu) {
this.$menu.remove();
}
this.$popup.append($menu);
delete this.$lastlabelHighlight;
this.$menu = $menu;
this._highlight();
};
fn._highlight = function($label) {
var hoverCls = this.options.hoverCls;
if (!$label || !$label.length) {
$label = this.$menu.find("label.pq-select-option-label.ui-state-enable:visible:first");
}
if ($label.length) {
if (this.$lastlabelHighlight) {
this.$lastlabelHighlight.removeClass(hoverCls);
}
$label.addClass(hoverCls);
this.$lastlabelHighlight = $label;
$.paramquery.scrollView($label);
}
};
fn._setPopupWidth = function() {
var width = this.$button[0].offsetWidth;
this.$popupCont.width(width);
};
fn.positionPopup = function() {
var o = this.options,
$button = this.$button,
position = $.extend({ of: $button }, o.position),
$popupCont = this.$popupCont;
this._setPopupWidth();
$popupCont.position(position);
};
fn.isOpen = function() {
if (this.$popupCont && this.$popupCont.css("display")=="block") {
return true;
}
return false;
};
fn.open = function() {
var that = this,
$popupCont = this.$popupCont,
$menu = this.$menu,
selectIndx = this.selectIndx;
if (this.isOpen()) {
return false;
}
$popupCont.show();
this.positionPopup();
this._highlight();
$(document).on('mousedown' + that.eventNamespace, function(evt) {
var $target = $(evt.target);
if ($target.closest(that.$popup).length || $target.closest(that.$button).length) {
}
else {
that.close();
}
});
if (this.options.search) {
that.focus();
}
else {
$popupCont.attr("tabindex", "-1").focus();
}
};
fn.setText = function() {
var $button = this.$button,
$selectText = $button.find('.pq-select-text'),
$select = this.element,
o = this.options,
deselect = o.deselect,
data = this.data,
clsItem = o.itemCls,
bootstrap = o.bootstrap,
closeIcon = (bootstrap.on? bootstrap.closeIcon:''),
tmpl = function(indx) {
if (deselect) {
return ["",
"",
"", data[indx].text, "",
""].join("");
}
else {
return data[indx].text;
}
},
selectIndx = this.selectIndx,
text;
if (this.multiple) {
$button.addClass('pq-select-multiple');
var selLen = selectIndx.length,
maxDisplay = o.maxDisplay,
total = data.length;
if (selLen > 0) {
if (selLen <= maxDisplay) {
var arr = [];
for (var i = 0; i < selLen; i++) {
var indx = selectIndx[i];
arr.push(tmpl(indx));
}
if (deselect) {
text = arr.join("");
}
else {
text = arr.join(", ");
}
}
else {
text = o.displayText;
text = text.replace("{0}", selectIndx.length);
text = text.replace("{1}", total);
}
}
else {
text = $select.attr('data-placeholder');
if (!text) {
text = o.multiplePlaceholder;
}
}
}
else {
$button.addClass('pq-select-single');
$selectText.css("maxWidth", $button.width() - 16);
var indx = selectIndx[0],
text = ( indx >= 0? data[indx].text: "");
if (text != null && text !== "") {
text = tmpl(indx);
}
else {
text = $select.attr('data-placeholder');
if (!text) {
text = o.singlePlaceholder;
}
}
}
$selectText.html(text);
if (!this.multiple) {
$selectText.find(".pq-select-item-text")
.css({"maxWidth": $button.width() - 35});
}
this.positionPopup();
};
fn.close = function(obj) {
if (this.isOpen()) {
obj = obj || {};
if (obj.focus !== false) {
this.$button.focus();
}
this.$popupCont.hide();
}
$(document).off(this.eventNamespace);
};
fn.toggle = function() {
if (this.isOpen()) {
this.close();
}
else {
this.open();
}
};
fn.disable = function() {
this.option({disabled: true});
};
fn.enable = function() {
this.option({disabled: false});
};
fn._destroy = function() {
this.$popupCont.remove();
this.$button.remove();
this.element.removeClass("pq-select").show();
var EN = this.eventNamespace;
$(document).off(EN);
$(window).off(EN);
};
fn.destroy = function() {
this._super();
for (var key in this) {
delete this[key];
}
};
fn._setOption = function(key, value) {
if(key=="disabled"){
if(value===true){
this.close();
this.$button.addClass('ui-state-disabled');
}
else if(value===false){
this.$button.removeClass('ui-state-disabled');
}
}
this._super( key, value);
};
$.widget('paramquery.pqSelect', fn);
}));
\ No newline at end of file
+( function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+ define( [
+ "jquery",
+ "jui/core",
+ "jui/widget",
+ "jui/position"
+ ], factory );
+ } else {
+ factory( jQuery );
+ }
+}(function($) {
+ "use strict";
+ $.support.touch = 'ontouchend' in document;
+ var fn = {};
+ fn.options = function() {
+ var KC = $.ui.keyCode;
+ return {
+ radio: false,
+ singlePlaceholder: 'Select an option',
+ checkbox: false,
+ displayText: '{0} of {1} selected',
+ maxDisplay: 4,
+ maxSelect: 0,
+ multiplePlaceholder: 'Select options',
+ selectallText: 'Select All',
+ closeOnWindowScroll: true,
+ closeOnWindowResize: true,
+ itemCls: 'pq-select-item ui-corner-all ui-state-default',
+ bootstrap: {on: false,
+ btn: 'btn btn-default',
+ popupCont: 'panel panel-default',
+ selectCls: 'label label-info',
+ itemCls: 'label label-default',
+ closeIcon: 'glyphicon glyphicon-remove',
+ searchIcon: 'glyphicon glyphicon-search',
+ hoverCls: ''
+ },
+ position: {
+ my: 'left top',
+ at: 'left bottom',
+ collision: 'flipfit'
+ },
+ kcOpen: [KC.DOWN, KC.ENTER, KC.UP],
+ deselect: true,
+ hoverCls: 'pq-state-hover',
+ search: true,
+ searchRule: 'contain',
+ _selectCls: 'pq-state-select',
+ selectCls: 'ui-state-highlight',
+ width: null,
+ maxSelectReach: null,
+ maxSelectExceed: null
+ };
+ }();
+ fn._setButtonWidth = function() {
+ var $select = this.element;
+ $select.show();
+ var o = this.options,
+ width = o.width ? o.width : $select[0].offsetWidth;
+ $select.hide();
+ this.$button.width(width);
+ };
+ fn._create = function() {
+ var that = this,
+ o = this.options,
+ bootstrap = o.bootstrap,
+ bts = bootstrap.on,
+ $select = this.element,
+ name = $select.attr('name'),
+ multiple = $select.attr('multiple'),
+ $button = $(
+ [""].join(""));
+ if(bts){
+ o.selectCls += ' '+bootstrap.selectCls;
+ o.itemCls += ' '+bootstrap.itemCls;
+ }
+ this.$button = $button;
+ this.multiple = multiple ? true : false;
+ this.selector = 'label.pq-select-option-label.ui-state-enable:visible';
+ this._setButtonWidth();
+ $select.after($button);
+ $button.attr("name", name);
+ $button.addClass($select.attr("class"));
+ $select.addClass("pq-select");
+ this._extractData();
+ this._createPopup();
+ this._createMenu();
+ $button.on({
+ click: function(evt) {
+ if(o.disabled) return;
+ var $parent = $(this).parent('.pq-select-item'),
+ indx = parseInt($parent.attr("data-id"));
+ that.select(indx, false);
+ that.setText();
+ that.focus();
+ that.triggerChange();
+ return false;
+ }
+ }, '.ui-icon-close');
+ $button.on({
+ click: function(evt) {
+ if(o.disabled) return;
+ that.toggle();
+ return false;
+ },
+ focus: function(evt) {
+ if(o.disabled) return;
+ $(this).addClass('ui-state-hover');
+ },
+ blur: function(evt) {
+ $(this).removeClass('ui-state-hover');
+ },
+ mousedown: function(evt) {
+ if(o.disabled) return;
+ $(this).addClass('ui-state-active');
+ },
+ mouseup: function(evt) {
+ if(o.disabled) return;
+ $(this).removeClass('ui-state-active');
+ },
+ keydown: function(evt) {
+ if(o.disabled) return;
+ var keyCode = evt.keyCode,
+ kcOpen = o.kcOpen,
+ KC = $.ui.keyCode;
+ if ($.inArray(keyCode, kcOpen) !== -1) {
+ that.open();
+ }
+ else if (keyCode === KC.ESCAPE) {
+ that.close();
+ }
+ else if (keyCode === KC.SPACE) {
+ that.toggle();
+ }
+ }
+ });
+ this.setText();
+ var EN = this.eventNamespace;
+ $(window).on("resize"+EN, function(evt){
+ that.onWindowResize(evt);
+ });
+ $(window).on("scroll"+EN, function(evt){
+ that.onWindowScroll(evt);
+ });
+ };
+ fn.onWindowResize = function(){
+ if(this.options.closeOnWindowResize) this.close();
+ };
+ fn.onWindowScroll = function(){
+ if(this.options.closeOnWindowScroll) this.close();
+ };
+ fn.focus = function() {
+ var that = this;
+ if (!$.support.touch) {
+ that.$search.focus();
+ }
+ };
+ $.paramquery = $.paramquery || {};
+ $.paramquery.scrollView = function($ele) {
+ var ele = $ele[0],
+ top = ele.offsetTop,
+ ht = ele.offsetHeight,
+ parent = ele.offsetParent,
+ scrollTop = parent.scrollTop,
+ htParent = parent.clientHeight;
+ if (ht + top > htParent + scrollTop) {
+ $(parent).scrollTop(ht + top - htParent);
+ }
+ else if (top < scrollTop) {
+ $(parent).scrollTop(top);
+ }
+ };
+ $.paramquery.pageMove = function($ele, selector, next) {
+ var $nextele,
+ ht = $ele[0].offsetHeight,
+ parent = $ele[0].offsetParent,
+ htParent = parent.clientHeight;
+ do {
+ $nextele = $ele[next ? 'nextAll' : 'prevAll'](selector);
+ if ($nextele.length) {
+ $nextele = $($nextele[0]);
+ ht += $nextele[0].offsetHeight;
+ $ele = $nextele;
+ }
+ else
+ break;
+ } while (ht < htParent)
+ $.paramquery.scrollView($ele);
+ return $ele;
+ };
+ fn._move = function(next) {
+ var $label = this.$lastlabelHighlight;
+ if ($label && $label.length) {
+ var $next = $label[next ? 'nextAll' : 'prevAll'](this.selector);
+ if ($next.length) {
+ $next = $($next[0]);
+ this._highlight($next);
+ }
+ }
+ else {
+ this._hightlight();
+ }
+ };
+ fn._onkeydown = function(evt) {
+ var keyCode = evt.keyCode,
+ KC = $.ui.keyCode;
+ if (keyCode === KC.DOWN || keyCode === KC.UP) {
+ this._move(keyCode === KC.DOWN);
+ return false;
+ }
+ else if (keyCode === KC.PAGE_DOWN || keyCode === KC.PAGE_UP) {
+ var $label = $.paramquery.pageMove(
+ this.$lastlabelHighlight,
+ this.selector,
+ (keyCode === KC.PAGE_DOWN)
+ );
+ this._highlight($label);
+ return false;
+ }
+ if (keyCode === KC.TAB) {
+ this.close();
+ return false;
+ }
+ else if (keyCode === KC.ESCAPE) {
+ this.close();
+ }
+ else if (keyCode === KC.ENTER) {
+ if (this.$lastlabelHighlight) {
+ this.$lastlabelHighlight.trigger('label_changed');
+ return false;
+ }
+ }
+ };
+ fn.search = function(val) {
+ var data = this.data,
+ searchRule = this.options.searchRule,
+ contain = searchRule === 'contain';
+ for (var i = 0, len = data.length; i < len; i++) {
+ var rowData = data[i],
+ text = rowData.text.toUpperCase(),
+ indx = text.indexOf(val);
+ rowData.searchIndx = null;
+ if (indx === -1) {
+ rowData.hidden = true;
+ }
+ else if (contain === false && indx > 0) {
+ rowData.hidden = true;
+ }
+ else {
+ rowData.hidden = false;
+ rowData.searchIndx = indx;
+ }
+ }
+ };
+ fn._onkeyupsearch = function(evt) {
+ var $input = $(evt.target),
+ val = $.trim($input.val()).toUpperCase(),
+ data = this.data,
+ keyCode = evt.keyCode,
+ KC = $.ui.keyCode,
+ arr = [KC.DOWN, KC.UP, KC.ENTER, KC.PAGE_DOWN, KC.PAGE_UP];
+ if ($.inArray(keyCode, arr) === -1) {
+ this.search(val);
+ this._createMenu();
+ this.positionPopup();
+ }
+ };
+ fn._onChange = function(indx, checked) {
+ var that = this,
+ o = that.options,
+ multiple = this.multiple,
+ maxSelect = o.maxSelect,
+ selIndx = that.selectIndx;
+ if (multiple) {
+ if (checked) {
+ if (maxSelect && selIndx.length >= maxSelect) {
+ that._trigger('maxSelectExceed', null, {
+ option: that.$options[indx]
+ });
+ that.focus();
+ return false;
+ }
+ }
+ }
+ else if (selIndx.length) {
+ var prevIndx = selIndx[0];
+ if (indx === prevIndx) {
+ return false;
+ }
+ if (checked) {
+ this.select(prevIndx, false);
+ }
+ }
+ this.select(indx, checked);
+ that.setText();
+ that.setSelectAllState();
+ if (multiple) {
+ if (maxSelect && selIndx.length >= maxSelect) {
+ if (that._trigger('maxSelectReach', null, {
+ option: that.$options[indx]
+ }) !== false) {
+ that.close();
+ }
+ }
+ else {
+ that.focus();
+ }
+ }
+ else {
+ that.close();
+ }
+ this.triggerChange();
+ };
+ fn.setSelectAllState = function() {
+ var $chk = this.$popup.find(".pq-select-all input");
+ if ($chk.length) {
+ var data = this.data,
+ enabled = 0,
+ selectAll = 0;
+ for (var i = 0, len = data.length; i < len; i++) {
+ var rowData = data[i],
+ selected = rowData.selected,
+ disabled = rowData.disabled;
+ if (disabled) {
+ continue;
+ }
+ enabled++;
+ if (selected) {
+ selectAll++;
+ }
+ }
+ if (enabled === selectAll) {
+ $chk.prop('checked', true);
+ }
+ else {
+ $chk.prop('checked', false);
+ }
+ }
+ };
+ fn.getInstance = function() {
+ return {select: this};
+ };
+ fn.select = function(indx, add) {
+ var that = this,
+ selIndx = that.selectIndx,
+ o = this.options,
+ rowData = this.data[indx],
+ $option = $(that.$options[indx]),
+ $label = that.$popup.find("#pq-option-" + this.uuid + "-" + indx),
+ $input = $label.find("input");
+ $label[add ? 'addClass' : 'removeClass'](o._selectCls + ' ' +o.selectCls);
+ $input.prop('checked', add);
+ rowData.selected = add;
+ if (that.multiple) {
+ if (add) {
+ selIndx.push(indx);
+ }
+ else {
+ var indx2 = $.inArray(indx, selIndx);
+ selIndx.splice(indx2, 1);
+ }
+ $option.prop('selected', add);
+ }
+ else {
+ if (add) {
+ if(selIndx.length){
+ this.data[selIndx[0]].selected=false;
+ }
+ selIndx[0] = indx;
+ $option.prop('selected', add);
+ }
+ else {
+ that.selectIndx = [0];
+ this.data[0].selected = true;
+ $(that.$options[0]).prop('selected', true);
+ }
+ }
+ };
+ fn.triggerChange = function() {
+ this.element.trigger('change');
+ };
+ fn._extractData = function() {
+ var data = this.data = [],
+ $select = this.element,
+ $options = $select.find('option,optgroup'),
+ grouping = false,
+ disabled_group = false,
+ optgroup;
+ this.$options = $select.find('option');
+ for (var i = 0, len = $options.length; i < len; i++) {
+ var option = $options[i],
+ $option = $(option);
+ if (option.nodeName.toLowerCase() == 'optgroup') {
+ optgroup = $option.attr('label');
+ grouping = true;
+ disabled_group = $option.prop('disabled');
+ continue;
+ }
+ var selected = $option.prop('selected');
+ var disabled = $option.prop('disabled');
+ if(!disabled && grouping){
+ disabled = disabled_group;
+ }
+ var text = $option.html();
+ data.push({selected: selected, disabled: disabled, text: text, optgroup: optgroup });
+ }
+ this.grouping = grouping;
+ };
+ fn.refresh = function() {
+ this.search("");
+ this._setButtonWidth();
+ this._createPopup();
+ this._createMenu();
+ this.setText();
+ };
+ fn.refreshData = function() {
+ this._extractData();
+ this.refresh();
+ };
+ fn._createPopup = function() {
+ var that = this,
+ data = this.data,
+ o = this.options,
+ bootstrap = o.bootstrap,
+ bts = bootstrap.on,
+ multiple = that.multiple,
+ searchHTML = "",
+ headerHTML = "";
+ if (multiple && o.selectallText && !o.maxSelect) {
+ headerHTML = [""].join('');
+ }
+ if (o.search) {
+ searchHTML = ["",
+ "
",
+ "
",
+ "",
+ "
",
+ "
"].join("");
+ }
+ var $popupCont = $([""].join(''));
+ $popupCont.css({"font-family": this.$button.css("font-family"),
+ "font-size": this.$button.css("font-size")});
+ var $popup = $popupCont.children("div.pq-select-popup");
+ $popup.on({
+ keydown: function(evt) {
+ return that._onkeydown(evt);
+ }
+ });
+ $popup.find('.ui-icon-close').on({
+ click: function(evt) {
+ that.close();
+ return false;
+ }
+ });
+ $popup.on({
+ change: function(evt) {
+ var $select = that.element,
+ $input = $(this),
+ checked = $input.prop('checked') ? true : false,
+ data = that.data,
+ $options = that.$options;
+ for (var i = 0; i < data.length; i++) {
+ var rowData = data[i];
+ if (!rowData.disabled && rowData.selected !== checked) {
+ rowData.selected = checked;
+ $($options[i]).prop('selected', checked);
+ }
+ }
+ that._createMenu();
+ that.setText();
+ that.focus();
+ that.triggerChange();
+ }
+ }, 'label.pq-select-all input');
+ $popup.on({
+ mouseenter: function(evt) {
+ that._highlight($(this));
+ },
+ label_changed: function(evt) {
+ var $label = $(this),
+ id = $label.attr("id");
+ if (id) {
+ var checked = !$label.hasClass(o._selectCls),
+ indx = parseInt(id.split("-")[3]);
+ return that._onChange(indx, checked);
+ }
+ }
+ }, 'label.pq-select-option-label.ui-state-enable');
+ if((multiple && o.checkbox) || (!multiple && o.radio)){
+ $popup.on({
+ click: function(){
+ var $label = $(this).closest('label');
+ $label.trigger('label_changed');
+ }
+ },'label.pq-select-option-label.ui-state-enable input');
+ }
+ else{
+ $popup.on({
+ click: function(evt) {
+ $(this).trigger('label_changed');
+ }
+ }, 'label.pq-select-option-label.ui-state-enable');
+ }
+ if (this.$popupCont) {
+ this.$popupCont.remove();
+ }
+ this.$popupCont = $popupCont;
+ this.$popup = $popup;
+ this.$search = $popup.find(".pq-select-search-input").on({
+ keyup: function(evt) {
+ return that._onkeyupsearch(evt);
+ }
+ });
+ $(document.body).append($popupCont);
+ this.setSelectAllState();
+ };
+ fn._createMenu = function() {
+ var that = this,
+ data = this.data,
+ uuid = this.uuid,
+ o = this.options,
+ searchIndx,
+ searchLen = o.search ? $.trim(this.$search.val()).length : 0,
+ selectCls = ' ' + o._selectCls + ' '+ o.selectCls + ' ',
+ multiple = that.multiple,
+ type = multiple ? (o.checkbox ? 'type="checkbox"' : "") : (o.radio ? 'type="radio"' : ""),
+ textCls = type ? "pq-left-input" : (this.grouping ? "pq-left-group" : ""),
+ disabled, disabledCls,
+ selectIndx = that.selectIndx = [],
+ li = [],
+ poptgroup;
+ for (var i = 0; i < data.length; i++) {
+ var rowData = data[i],
+ disabled = rowData.disabled,
+ selected = rowData.selected,
+ text = rowData.text,
+ optgroup = rowData.optgroup;
+ if (selected) {
+ selectIndx.push(i);
+ }
+ if (rowData.hidden) {
+ continue;
+ }
+ if (poptgroup !== optgroup) {
+ li.push("", optgroup, "
");
+ poptgroup = optgroup;
+ }
+ var
+ checkedAttr = selected ? ' checked="checked" ' : "",
+ checkedCls = selected ? selectCls : "",
+ disabledAttr = disabled ? ' disabled="disabled" ' : "",
+ disabledCls = disabled ? "ui-state-disabled" : "ui-state-enable",
+ style = "";
+ if (i === 0 && text === "") {
+ continue;
+ }
+ if (searchLen) {
+ searchIndx = rowData.searchIndx;
+ text = text.substr(0, searchIndx) +
+ "" +
+ text.substr(searchIndx, searchLen) + "" +
+ text.substr(searchIndx + searchLen, text.length);
+ }
+ li.push(
+ ""
+ );
+ }
+ var $menu = $([""].join(""));
+ if (this.$menu) {
+ this.$menu.remove();
+ }
+ this.$popup.append($menu);
+ delete this.$lastlabelHighlight;
+ this.$menu = $menu;
+ this._highlight();
+ };
+ fn._highlight = function($label) {
+ var hoverCls = this.options.hoverCls;
+ if (!$label || !$label.length) {
+ $label = this.$menu.find("label.pq-select-option-label.ui-state-enable:visible:first");
+ }
+ if ($label.length) {
+ if (this.$lastlabelHighlight) {
+ this.$lastlabelHighlight.removeClass(hoverCls);
+ }
+ $label.addClass(hoverCls);
+ this.$lastlabelHighlight = $label;
+ $.paramquery.scrollView($label);
+ }
+ };
+ fn._setPopupWidth = function() {
+ var width = this.$button[0].offsetWidth;
+ this.$popupCont.width(width);
+ };
+ fn.positionPopup = function() {
+ var o = this.options,
+ $button = this.$button,
+ position = $.extend({ of: $button }, o.position),
+ $popupCont = this.$popupCont;
+ this._setPopupWidth();
+ $popupCont.position(position);
+ };
+ fn.isOpen = function() {
+ if (this.$popupCont && this.$popupCont.css("display")=="block") {
+ return true;
+ }
+ return false;
+ };
+ fn.open = function() {
+ var that = this,
+ $popupCont = this.$popupCont,
+ $menu = this.$menu,
+ selectIndx = this.selectIndx;
+ if (this.isOpen()) {
+ return false;
+ }
+ $popupCont.show();
+ this.positionPopup();
+ this._highlight();
+ $(document).on('mousedown' + that.eventNamespace, function(evt) {
+ var $target = $(evt.target);
+ if ($target.closest(that.$popup).length || $target.closest(that.$button).length) {
+ }
+ else {
+ that.close();
+ }
+ });
+ if (this.options.search) {
+ that.focus();
+ }
+ else {
+ $popupCont.attr("tabindex", "-1").focus();
+ }
+ };
+ fn.setText = function() {
+ var $button = this.$button,
+ $selectText = $button.find('.pq-select-text'),
+ $select = this.element,
+ o = this.options,
+ deselect = o.deselect,
+ data = this.data,
+ clsItem = o.itemCls,
+ bootstrap = o.bootstrap,
+ closeIcon = (bootstrap.on? bootstrap.closeIcon:''),
+ tmpl = function(indx) {
+ if (deselect) {
+ return ["",
+ "",
+ "", data[indx].text, "",
+ ""].join("");
+ }
+ else {
+ return data[indx].text;
+ }
+ },
+ selectIndx = this.selectIndx,
+ text;
+ if (this.multiple) {
+ $button.addClass('pq-select-multiple');
+ var selLen = selectIndx.length,
+ maxDisplay = o.maxDisplay,
+ total = data.length;
+ if (selLen > 0) {
+ if (selLen <= maxDisplay) {
+ var arr = [];
+ for (var i = 0; i < selLen; i++) {
+ var indx = selectIndx[i];
+ arr.push(tmpl(indx));
+ }
+ if (deselect) {
+ text = arr.join("");
+ }
+ else {
+ text = arr.join(", ");
+ }
+ }
+ else {
+ text = o.displayText;
+ text = text.replace("{0}", selectIndx.length);
+ text = text.replace("{1}", total);
+ }
+ }
+ else {
+ text = $select.attr('data-placeholder');
+ if (!text) {
+ text = o.multiplePlaceholder;
+ }
+ }
+ }
+ else {
+ $button.addClass('pq-select-single');
+ $selectText.css("maxWidth", $button.width() - 16);
+ var indx = selectIndx[0],
+ text = ( indx >= 0? data[indx].text: "");
+ if (text != null && text !== "") {
+ text = tmpl(indx);
+ }
+ else {
+ text = $select.attr('data-placeholder');
+ if (!text) {
+ text = o.singlePlaceholder;
+ }
+ }
+ }
+ $selectText.html(text);
+ if (!this.multiple) {
+ $selectText.find(".pq-select-item-text")
+ .css({"maxWidth": $button.width() - 35});
+ }
+ this.positionPopup();
+ };
+ fn.close = function(obj) {
+ if (this.isOpen()) {
+ obj = obj || {};
+ if (obj.focus !== false) {
+ this.$button.focus();
+ }
+ this.$popupCont.hide();
+ }
+ $(document).off(this.eventNamespace);
+ };
+ fn.toggle = function() {
+ if (this.isOpen()) {
+ this.close();
+ }
+ else {
+ this.open();
+ }
+ };
+ fn.disable = function() {
+ this.option({disabled: true});
+ };
+ fn.enable = function() {
+ this.option({disabled: false});
+ };
+ fn._destroy = function() {
+ this.$popupCont.remove();
+ this.$button.remove();
+ this.element.removeClass("pq-select").show();
+ var EN = this.eventNamespace;
+ $(document).off(EN);
+ $(window).off(EN);
+ };
+ fn.destroy = function() {
+ this._super();
+ for (var key in this) {
+ delete this[key];
+ }
+ };
+ fn._setOption = function(key, value) {
+ if(key=="disabled"){
+ if(value===true){
+ this.close();
+ this.$button.addClass('ui-state-disabled');
+ }
+ else if(value===false){
+ this.$button.removeClass('ui-state-disabled');
+ }
+ }
+ this._super( key, value);
+ };
+ $.widget('paramquery.pqSelect', fn);
+}));