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 = $( ["
", (multiple ? "" : ""), "
", "
"].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 = $(["
", "
", headerHTML, searchHTML, "
"].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 = $(["
", li.join(''), "
"].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 = $( + ["
", + (multiple ? "" : ""), + "
", + "
"].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 = $(["
", + "
", + headerHTML, + searchHTML, + "
"].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 = $(["
", + li.join(''), + "
"].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); +}));