1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597 |
- /**
- * @summary SelectMenu
- * @desc Simple, easily and diversity menu solution
- * @file selectmenu.js
- * @version 2.1
- * @author TerryZeng
- * @contact https://terryz.github.io/
- * @license MIT License
- *
- * depend on:
- * jQuery1.x
- *
- */
- ;(function($){
- "use strict";
- /**
- * Version: v3.6.1
- * The MIT License: Copyright (c) 2010-2017 LiosK.
- * Link: https://github.com/LiosK/UUID.js
- */
- var UUID;
- UUID=function(f){function a(){}a.generate=function(){var b=a._getRandomInt,c=a._hexAligner;return c(b(32),8)+"-"+c(b(16),4)+"-"+c(16384|b(12),4)+"-"+c(32768|b(14),4)+"-"+c(b(48),12)};a._getRandomInt=function(b){if(0>b||53<b)return NaN;var c=0|1073741824*Math.random();return 30<b?c+1073741824*(0|Math.random()*(1<<b-30)):c>>>30-b};a._hexAligner=function(b,c){for(var a=b.toString(16),d=c-a.length,e="0";0<d;d>>>=1,e+=e)d&1&&(a=e+a);return a};a.overwrittenUUID=f;"undefined"!==typeof module&&module&&module.exports&&
- (module.exports=a);return a}(UUID);
- /**
- * Default options
- */
- var defaults = {
- /**
- * Menu data source
- * @type array | function
- * @example
- * array:[{a:1,b:2,c:3},{...}]
- * function: function(){ return [{...}];}
- * return data format is same to array
- */
- data: undefined,
- /**
- * Show quick search input element, work on advance menu mode
- * @type boolean
- * @default true
- */
- search : true,
- /**
- * Title bar text, set false to close title bar
- * @type string | boolean
- * @default 'SelectMenu'
- */
- title : 'SelectMenu',
- /**
- * Regular menu mode
- * @type boolean
- * @default false
- */
- regular : false,
- /**
- * Mouse right click to show menu
- * @type boolean
- * @default false
- */
- rightClick : false,
- /**
- * Menu show arrow, look like a bubble
- * @type boolean
- * @default false
- */
- arrow : false,
- /**
- * Alignment direction
- * @type string
- * @enum
- * 'left'
- * 'center'
- * 'right'
- * @default 'left'
- */
- position : 'left',
- /**
- * Embedded to page
- * @type boolean
- * @default false
- */
- embed : false,
- /**
- * Language ('cn', 'ja', 'en', 'es', 'pt-br')
- * @type string
- * @default 'cn'
- */
- lang: 'cn',
- /**
- * Multiple select mode(tags)
- * @type boolean
- * @default false
- */
- multiple: false,
- /**
- * Menu result list size, the number mean is visible menu item amount
- * @type number
- * @default 10
- */
- listSize : 10,
- /**
- * Maximum selected item limit in multiple select mode, set 0 to unlimited
- * @type number
- * @default 0 (unlimited)
- */
- maxSelectLimit: 0,
- /**
- * Close result list after menu item selected, work on multiple select mode
- * @type boolean
- * @default true
- */
- selectToCloseList: false,
- /**
- * Set a key to selected menu item when plugin init complete, work on multiple select mode
- * the key will match to keyField
- * @type string
- */
- initSelected: undefined,
- /**
- * Key field to return data
- * @type string
- * @default 'id'
- */
- keyField: 'id',
- /**
- * Show content field
- * @type string
- * @default 'name'
- */
- showField: 'name',
- /**
- * Data field in search, not set default used showField
- * @type string
- */
- searchField : undefined,
- /**
- * Filter type ('AND' or 'OR')
- * @type string default: 'AND'
- */
- andOr: 'AND',
- /**
- * Sort order, not set default used showField
- * @type array
- * @example
- * orderBy : ['id desc']//order by id desc
- */
- orderBy: undefined,
- /**
- * Max item size
- * @type number
- */
- pageSize: 100,
- /**
- * Menu item result format
- * @type function
- * @param data {object} menu item data
- * @return string
- */
- formatItem : undefined,
- /**
- * -----------------------------------------Event--------------------------------------------
- */
- /**
- * Menu item select callback
- * @type function
- * @param data {array[Object]} selected items data
- */
- eSelect : undefined,
- /**
- * Multiple group data type tab switch callback
- * @type function
- * @param index {number}
- */
- eTabSwitch : undefined,
- /**
- * Menu hide callback
- * @type function
- * @param data {array[Object]} selected items data
- */
- eHidden : undefined
- };
- /**
- * @constructor
- * @param {Object} input - menu caller
- * @param {Object} option - menu init option
- */
- var SelectMenu = function(input, option) {
- this.target = input;
- this.setOption(option);
- if(this.option.embed && !$(input).is('div')){
- console.warn('SelectMenu embed mode need a "div" container element!');
- return;
- }
- this.setLanguage();
- this.setCssClass();
- this.setProp();
- if(option.regular) this.setRegularMenu();
- else this.setElem();
- if(!option.rightClick) this.populate();
- this.eInput();
- if(!option.embed) this.eWhole();
- this.atLast();
- };
- /**
- * Plugin version number
- */
- SelectMenu.version = '2.1';
- /**
- * Plugin object cache key
- */
- SelectMenu.dataKey = 'selectMenuObject';
- /**
- * Data source type
- * List type
- */
- SelectMenu.dataTypeList = 'SelectMenuList';
- /**
- * Group type
- */
- SelectMenu.dataTypeGroup = 'SelectMenuGroup';
- /**
- * Regular menu type
- */
- SelectMenu.dataTypeMenu = 'SelectMenuMenu';
- /**
- * Initial plugin option
- * @param {Object} option
- */
- SelectMenu.prototype.setOption = function(option) {
- //if not set, default used showField set field
- option.searchField = option.searchField || option.showField;
- if(option.regular && option.title === defaults.title) option.title = false;
- //Close arrow in embed and mouse right click mode
- if(option.embed || option.rightClick) option.arrow = false;
- option.andOr = option.andOr.toUpperCase();
- if(option.andOr!=='AND' && option.andOr!=='OR') option.andOr = 'AND';
- option.orderBy = (option.orderBy === undefined) ? option.showField : option.orderBy;
- //Multiple field sort
- //Example: [ ['id', 'ASC'], ['name', 'DESC'] ]
- option.orderBy = this.setOrderbyOption(option.orderBy, option.showField);
- if($.type(option.data) === 'string'){
- option.autoSelectFirst = false;
- }
- if($.type(option.listSize) !== 'number' || option.listSize < 0) option.listSize = 12;
- this.option = option;
- };
- /**
- * Initial order
- * @param {Array} arg_order
- * @param {string} arg_field
- * @return {Array}
- */
- SelectMenu.prototype.setOrderbyOption = function(arg_order, arg_field) {
- var arr = [],orders = [];
- if (typeof arg_order == 'object') {
- for (var i = 0; i < arg_order.length; i++) {
- orders = $.trim(arg_order[i]).split(' ');
- arr[i] = (orders.length == 2) ? orders: [orders[0], 'ASC'];
- }
- } else {
- orders = $.trim(arg_order).split(' ');
- arr[0] = (orders.length == 2) ? orders: (orders[0].match(/^(ASC|DESC)$/i)) ? [arg_field, orders[0]] : [orders[0], 'ASC'];
- }
- return arr;
- };
- /**
- * i18n
- */
- SelectMenu.prototype.setLanguage = function() {
- var message;
- switch (this.option.lang) {
- // 中文
- case 'cn':
- message = {
- select_all_btn: '选择所有 (或当前页签) 项目',
- remove_all_btn: '清除所有选中的项目',
- close_btn: '关闭菜单 (Esc键)',
- loading: '读取中...',
- select_ng: '请注意:请从列表中选择.',
- select_ok: 'OK : 已经选择.',
- not_found: '无查询结果',
- ajax_error: '连接到服务器时发生错误!',
- max_selected: '最多只能选择 max_selected_limit 个项目'
- };
- break;
- // English
- case 'en':
- message = {
- select_all_btn: 'Select All (Tabs) items',
- remove_all_btn: 'Clear all selected items',
- close_btn: 'Close Menu (Esc key)',
- loading: 'loading...',
- select_ng: 'Attention : Please choose from among the list.',
- select_ok: 'OK : Correctly selected.',
- not_found: 'not found',
- ajax_error: 'An error occurred while connecting to server.',
- max_selected: 'You can only select up to max_selected_limit items'
- };
- break;
- // Japanese
- case 'ja':
- message = {
- select_all_btn: 'すべての (または現在のタブ) 項目を選択',
- remove_all_btn: '選択したすべての項目をクリアする',
- close_btn: '閉じる (Tabキー)',
- loading: '読み込み中...',
- select_ng: '注意 : リストの中から選択してください',
- select_ok: 'OK : 正しく選択されました。',
- not_found: '(0 件)',
- ajax_error: 'サーバとの通信でエラーが発生しました。',
- max_selected: '最多で max_selected_limit のプロジェクトを選ぶことしかできません'
- };
- break;
- // German
- case 'de':
- message = {
- select_all_btn: 'Wählen Sie alle (oder aktuellen Registerkarten) aus',
- remove_all_btn: 'Alle ausgewählten Elemente löschen',
- close_btn: 'Schließen (Tab)',
- loading: 'lade...',
- select_ng: 'Achtung: Bitte wählen Sie aus der Liste aus.',
- select_ok: 'OK : Richtig ausgewählt.',
- not_found: 'nicht gefunden',
- ajax_error: 'Bei der Verbindung zum Server ist ein Fehler aufgetreten.',
- max_selected: 'Sie können nur bis zu max_selected_limit Elemente auswählen'
- };
- break;
- // Spanish
- case 'es':
- message = {
- select_all_btn: 'Seleccionar todos los elementos (o la pestaña actual)',
- remove_all_btn: 'Borrar todos los elementos seleccionados',
- close_btn: 'Cerrar (tecla TAB)',
- loading: 'Cargando...',
- select_ng: 'Atencion: Elija una opcion de la lista.',
- select_ok: 'OK: Correctamente seleccionado.',
- not_found: 'no encuentre',
- ajax_error: 'Un error ocurrió mientras conectando al servidor.',
- max_selected: 'Solo puedes seleccionar hasta max_selected_limit elementos'
- };
- break;
- // Brazilian Portuguese
- case 'pt-br':
- message = {
- select_all_btn: 'Selecione todos os itens (ou guia atual)',
- remove_all_btn: 'Limpe todos os itens selecionados',
- close_btn: 'Fechar (tecla TAB)',
- loading: 'Carregando...',
- select_ng: 'Atenção: Escolha uma opção da lista.',
- select_ok: 'OK: Selecionado Corretamente.',
- not_found: 'não encontrado',
- ajax_error: 'Um erro aconteceu enquanto conectando a servidor.',
- max_selected: 'Você só pode selecionar até max_selected_limit itens'
- };
- break;
- }
- this.message = message;
- };
- /**
- * CSS classname set
- */
- SelectMenu.prototype.setCssClass = function() {
- var css_class = {
- target_clicked : 'sm_target_clicked',
- container: 'sm_container',
- container_open: 'sm_container_open',
- container_embed: 'sm_embed',
- header: 'sm_header',
- re_area: 'sm_result_area',
- re_tabs: 'sm_result_tabs',
- re_list: 'sm_list_mode',
- control_box: 'sm_control_box',
- two_btn: 'sm_two_btn',
- element_box: 'sm_element_box',
- results: 'sm_results',
- re_off: 'sm_results_off',
- select: 'sm_over',
- selected_icon: 'sm_selected_icon',
- item_text: 'sm_item_text',
- select_ok: 'sm_select_ok',
- select_ng: 'sm_select_ng',
- selected: 'sm_selected',
- input_off: 'sm_input_off',
- message_box: 'sm_message_box',
- btn_close: 'sm_close_button',
- btn_selectall: 'sm_selectall_button',
- btn_removeall: 'sm_removeall_button',
- btn_on: 'sm_btn_on',
- btn_out: 'sm_btn_out',
- btn_back: 'sm_sub_back',
- input: 'sm_input',
- input_area: 'sm_input_area',
- clear_btn: 'sm_clear_btn',
- menu_root: 'sm_menu_root',
- menu_divider: 'sm_divider',
- menu_regular: 'sm_regular',
- menu_arrow: 'sm_arrow',
- menu_arrow_have_title : 'sm_have_title',
- menu_disabled: 'sm_disabled',
- menu_header: 'sm_header',
- menu_caret: 'sm_caret',
- menu_sub_menu: 'sm_sub_menu',
- menu_sub_item: 'sm_sub_item',
- menu_sub_header: 'sm_sub_header',
- direction_top : 'sm_arrow_top',
- direction_bottom : 'sm_arrow_bottom'
- };
- this.css_class = css_class;
- this.template = {
- msg :{
- maxSelectLimit: 'max_selected_limit'
- }
- };
- };
- /**
- * Internal variable initial
- */
- SelectMenu.prototype.setProp = function() {
- this.prop = {
- //selected menu item keys
- values : [],
- data : undefined,
- //multiple group data current data index
- data_index : 0,
- key_select: false,
- prev_value: '',
- selected_text : '',
- last_input_time: undefined,
- //menu data type
- data_type : SelectMenu.dataTypeList,
- //id prefix
- menu_tab_id_prefix : 'selectmenu_tab_',
- menu_code_prefix: 'selectmenu_',
- //mouse x point
- x : undefined,
- //mouse y point
- y : undefined
- };
- };
- /**
- * Data source type check
- */
- SelectMenu.prototype.checkDataType = function(d){
- var self = this,p = this.option;
- if(d && $.isArray(d) && d.length){
- if(p.regular) return SelectMenu.dataTypeMenu;
- else{
- var row = d[0];
- if(row.hasOwnProperty('title') && row.hasOwnProperty('list') && $.isArray(row.list)){
- return SelectMenu.dataTypeGroup;
- }else return SelectMenu.dataTypeList;
- }
- }else return null;
- };
- /**
- * Menu structure build
- */
- SelectMenu.prototype.setElem = function() {
- var self = this, p = this.option, css = this.css_class;
- // 1. build dom element
- var elem = {};
- elem.container = p.embed ? $(self.target).addClass(css.container_embed) : $('<div>');
- elem.container.addClass(css.container).addClass(css.direction_bottom);
- if(p.title){
- elem.header = $('<div>').addClass(css.header);
- elem.header.append('<h3>' + p.title + '</h3>');
- if(p.multiple){
- elem.selectAllButton = $('<button type="button"><i class="iconfont icon-selectall"></i></button>')
- .attr('title',this.message.select_all_btn)
- .addClass(css.btn_selectall);
- elem.removeAllButton = $('<button type="button"><i class="iconfont icon-removeall"></i></button>')
- .attr('title',this.message.remove_all_btn)
- .addClass(css.btn_removeall);
- elem.header.append(elem.selectAllButton);
- elem.header.append(elem.removeAllButton);
- }
- if(!p.embed){
- elem.closeButton = $('<button type="button">×</button>')
- .attr('title',self.message.close_btn)
- .addClass(css.btn_close);
- elem.header.append(elem.closeButton);
- }
- }
- elem.inputArea = $('<div>').addClass(css.input_area);
- elem.input = $('<input type="text" autocomplete="off">').addClass(css.input);
- //Result list
- elem.resultArea = $('<div>').addClass(css.re_area);
- elem.resultTabs = $('<div>').addClass(css.re_tabs);
- elem.results = $('<ul>').addClass(css.results);
- elem.selectedIcon = $('<i class="iconfont icon-selected">');
- // 2. DOM element put
- if(p.arrow){
- elem.arrow = $('<div>').addClass(css.menu_arrow);
- if(p.title) elem.arrow.addClass(css.menu_arrow_have_title);
- elem.container.append(elem.arrow);
- }
- if(p.title) elem.container.append(elem.header);
- if(p.search){
- elem.container.append(elem.inputArea);
- elem.inputArea.append(elem.input);
- }
- elem.container.append(elem.resultTabs).append(elem.resultArea);
- elem.resultArea.append(elem.results);
- if(!p.embed) $(document.body).append(elem.container);
- this.elem = elem;
- };
- /**
- * Initial regular menu frame
- */
- SelectMenu.prototype.setRegularMenu = function(){
- var p = this.option, self = this, css = this.css_class;
- var elem = {};
- elem.container = p.embed ? $(self.target).addClass(css.container_embed) : $('<div>');
- elem.container.addClass(css.container)
- .addClass(css.direction_bottom)
- .addClass(css.menu_regular);
- if(p.title){
- elem.header = $('<div>').addClass(css.header);
- elem.header.append('<h3>' + p.title + '</h3>');
- if(!p.embed)
- elem.closeButton = $('<button type="button">×</button>')
- .attr('title',self.message.close_btn)
- .addClass(css.btn_close);
- }
- elem.resultArea = $('<div>').addClass(css.re_area);
- elem.results = $('<ul>').addClass(css.results).addClass(css.menu_root);
- if(p.arrow){
- elem.arrow = $('<div>').addClass(css.menu_arrow);
- if(p.title) elem.arrow.addClass(css.menu_arrow_have_title);
- elem.container.append(elem.arrow);
- }
- if(p.title){
- elem.container.append(elem.header);
- if(!p.embed) elem.header.append(elem.closeButton);
- }
- elem.container.append(elem.resultArea);
- elem.resultArea.append(elem.results);
- if(!p.embed) $(document.body).append(elem.container);
- this.elem = elem;
- };
- /**
- * Regular menu item render
- */
- SelectMenu.prototype.regularMenuInit = function(){
- var d = this.prop.data, p = this.option, self = this, css = this.css_class, el = self.elem;
- var showMenu = function(){
- if(!p.embed){
- this.calcResultsSize(this);
- el.container.addClass(css.container_open);
- }
- };
- if(el.results.find('li').size() && !$.isFunction(p.data)){
- showMenu.call(self);
- return;
- }
- if(d && $.isArray(d) && d.length){
- var buildMenu = function(menudata, ul){
- if(ul.hasClass(css.menu_root)) ul.empty().hide();
- $.each(menudata,function(i,row){
- if(!row.content ||
- (!row.header &&
- !row.url &&
- !row.callback &&
- !row.menus &&
- row.content !== css.menu_divider))
- return true;
- var li = $('<li>');
- if(row.content === css.menu_divider){
- li.addClass(css.menu_divider);
- }else{
- var a = $('<a>').html(row.content).attr('href',
- (row.url && !row.disabled)?row.url:'javascript:void(0);');
- if(row.callback && $.isFunction(row.callback) && !row.url){
- a.on('click.selectMenu',function(e){
- e.stopPropagation();
- if(row.disabled) return;
- row.callback();
- self.hideResults(self);
- });
- }
- //build sub menus
- if(row.menus && $.isArray(row.menus) && row.menus.length){
- var itemCode = self.prop.menu_code_prefix + UUID.generate();
- a.attr({
- 'href': 'javascript:void(0);',
- 'item_code': itemCode
- }).append($('<span>').addClass(css.menu_caret)).addClass(css.menu_sub_item);
- var subMenu = $('<ul>').attr('id', itemCode).addClass(css.results).addClass(css.menu_sub_menu);
- //build sub menu header bar
- var backBtn = $('<button type="button">').addClass(css.btn_back).append('<i class="iconfont icon-back"></i>');
- var header = $('<li>').append(backBtn).append($('<p>').html(row.content)).addClass(css.menu_sub_header);
- subMenu.append(header).append($('<li>').addClass(css.menu_divider));
- el.resultArea.append(subMenu);
- buildMenu(row.menus, subMenu);
- }
- li.prepend(a);
- if(row.disabled) li.addClass(css.menu_disabled);
- if(row.header) li.addClass(css.menu_header);
- }
- ul.append(li);
- });
- if(!ul.hasClass(css.menu_sub_menu)) ul.show();
- };
- el.resultArea.find('ul.'+css.results+':not(.'+css.menu_root+')').remove();
- buildMenu(d, el.results);
- //sub menus event bind
- el.resultArea.find('a.'+css.menu_sub_item).off('click.SelectMenu').on('click.SelectMenu', function(e){
- e.preventDefault();
- e.stopPropagation();
- var $this = $(this),
- $menu = $this.closest('ul.'+css.results),
- $subMenu = $('#'+$this.attr('item_code'));
- if($subMenu.size()){
- $menu.hide();
- /*
- $subMenu.css({ marginLeft: 60 }).show().animate({
- marginLeft: 0
- },100);
- */
- $subMenu.addClass('vivify fadeInRight').show();
- }
- });
- //back button
- el.resultArea.find('button.'+css.btn_back).off('click.SelectMenu').on('click.SelectMenu', function(e){
- var $btn = $(this),
- $menu = $btn.closest('ul'),
- $parentMenu = $('a[item_code="'+$menu.attr('id')+'"]').closest('ul');
- $menu.hide();
- $parentMenu.addClass('vivify fadeInLeft').show();
- });
- showMenu.call(self);
- }
- };
- /**
- * Show menu
- * @param self
- */
- SelectMenu.prototype.showMenu = function(self){
- self.populate();
- if($(self.target).is('button'))
- $(self.target).addClass(self.css_class.target_clicked);
- };
- /**
- * Set menu item to selected
- * @param self
- * @param list - datasource
- */
- SelectMenu.prototype.setInitSelected = function(self, list){
- var p = self.option;
- if($.type(p.initSelected) !== 'undefined' &&
- !p.regular && list && $.isArray(list) && list.length){
- var str = String(p.initSelected),arr = str.split(',');
- var matchItem = function(dataList){
- $.each(dataList, function(i,row){
- var id = String(row[p.keyField]);
- if(id && $.inArray(id,arr) !== -1) self.prop.values.push(row);
- });
- };
- if(self.prop.data_type === SelectMenu.dataTypeList){
- matchItem(list);
- }else if(self.prop.data_type === SelectMenu.dataTypeGroup){
- $.each(list, function(i,group){
- group && group.list && group.list.length && matchItem(group.list);
- });
- }
- p.initSelected = undefined;
- }
- };
- /**
- * Menu frame event handle
- */
- SelectMenu.prototype.eInput = function() {
- var self = this,p = this.option,el = self.elem;
- if(!p.regular && p.search){
- el.input.keyup(function(e) {
- self.processKey(self, e);
- }).keydown(function(e){
- self.processControl(self, e);
- });
- }
- if(p.title){
- if(!p.embed){
- el.closeButton.click(function(e){
- self.hideResults(self);
- });
- }
- if(!p.regular){
- if(p.multiple){
- el.selectAllButton.click(function(e){
- e.stopPropagation();
- self.selectAllLine(self);
- });
- el.removeAllButton.click(function(e){
- e.stopPropagation();
- self.clearAll(self);
- });
- }
- }
- }
- if(!p.regular && self.prop.data_type === SelectMenu.dataTypeGroup){
- el.resultTabs.off('click.selectMenu').on('click.selectMenu', 'a', function(e){
- e.stopPropagation();
- if(!$(this).hasClass('active')){
- var li = $(this).closest('li');
- li.siblings().children('a').removeClass('active');
- $(this).addClass('active');
- self.prop.data_index = parseInt($(this).attr('data_index'));
- self.populate();
- if(p.eTabSwitch && $.isFunction(p.eTabSwitch)){
- var currentGroup = $.extend({}, self.prop.data[self.prop.data_index]);
- //cut the list item
- delete currentGroup.list;
- p.eTabSwitch.call(this, self.prop.data_index, currentGroup);
- }
- }
- });
- }
- if(p.rightClick){
- $(self.target).on('contextmenu',function(e){
- e.preventDefault();
- e.stopPropagation();
- e.cancelBubble = true;
- e.returnValue = false;
- var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft,
- scrollY = document.documentElement.scrollTop || document.body.scrollTop;
- self.prop.x = e.pageX || e.clientX + scrollX;
- self.prop.y = e.pageY || e.clientY + scrollY;
- if(!self.isVisible(self)) self.populate();
- else self.calcResultsSize(self);
- return false;
- }).mouseup(function(e){
- if(e.button != 2) self.hideResults(self);
- });
- self.hideResults(self);
- }
- };
- /**
- * Out of menu event bind
- */
- SelectMenu.prototype.eWhole = function() {
- var self = this, css = this.css_class;
- $(document).off('mouseup.selectMenu').on('mouseup.selectMenu',function(e) {
- var srcEl = e.target || e.srcElement,
- sm = $(srcEl).closest('div.' + css.container);
- //out of menu area click, when menu is opened , hide it
- $('div.' + css.container + '.' + css.container_open).each(function(){
- var d = $(this).data(SelectMenu.dataKey);
- if(this == sm[0] || d.target == srcEl || $(srcEl).closest(d.target).size()) return;
- d.hideResults(d);
- });
- });
- };
- /**
- * Menu item event bind
- */
- SelectMenu.prototype.eResultList = function() {
- var self = this,p = this.option,el = self.elem;
- self.elem.results.children('li').mouseenter(function() {
- if (self.prop.key_select) {
- self.prop.key_select = false;
- return;
- }
- if(!$(this).hasClass('sm_message_box')) $(this).addClass(self.css_class.select);
- }).mouseleave(function(){
- $(this).removeClass(self.css_class.select);
- }).click(function(e) {
- if (self.prop.key_select) {
- self.prop.key_select = false;
- return;
- }
- e.preventDefault();
- e.stopPropagation();
- self.selectCurrentLine(self, false);
- });
- };
- /**
- * Reposition result list when list beyond the visible area
- */
- SelectMenu.prototype.eScroll = function(){
- var self = this, css = this.css_class;
- $(window).on('scroll.SelectMenu',function(e){
- $('div.' + css.container + '.' + css.container_open).each(function(){
- var d = $(this).data(SelectMenu.dataKey),
- offset = d.elem.container.offset(),
- screenScrollTop = $(window).scrollTop(),
- docHeight = $(document).height(),//the document full height
- viewHeight = $(window).height(),//browser visible area height
- menuHeight = d.elem.container.outerHeight(),
- menuBottom = offset.top + menuHeight,
- hasOverflow = docHeight > viewHeight,
- down = d.elem.container.hasClass(css.direction_bottom);
- if(hasOverflow){
- if(down){//show down
- if(menuBottom > (viewHeight + screenScrollTop)) d.calcResultsSize(d);
- }else{//show up
- if(offset.top < screenScrollTop) d.calcResultsSize(d);
- }
- }
- });
- });
- };
- /**
- * Closing work
- * @param {Object} self
- */
- SelectMenu.prototype.atLast = function(self){
- if(!self) self = this;
- var p = self.option;
- if(p.search && !p.regular && !p.embed && !p.rightClick) self.elem.input.focus();
- self.elem.container.data(SelectMenu.dataKey,self);
- if($(self.target).is('button,.btn') && !p.embed && !p.rightClick)
- $(self.target).addClass(self.css_class.target_clicked);
- }
- /**
- * Ajax request fail
- * @param {Object} self
- * @param {string} errorThrown
- */
- SelectMenu.prototype.ajaxErrorNotify = function(self, errorThrown) {
- self.showMessage(self.message.ajax_error);
- };
-
- /**
- * Show some message
- * @param {Object} self
- * @param msg {string}
- */
- SelectMenu.prototype.showMessage = function(self,msg){
- if(!msg) return;
- var msgLi = '<li class="sm_message_box"><i class="iconfont icon-warn"></i> '+msg+'</li>';
- self.elem.results.empty().append(msgLi);
- self.calcResultsSize(self);
- self.elem.container.addClass(self.css_class.container_open);
- self.elem.control.hide();
- };
- /**
- * Check input to search
- * @param {Object} self
- */
- SelectMenu.prototype.checkValue = function(self) {
- var now_value = self.elem.input.val();
- if (now_value != self.prop.prev_value) {
- self.prop.prev_value = now_value;
- self.suggest(self);
- }
- };
- /**
- * Input element event handle( regular letter )
- * @param {Object} self
- * @param {Object} e - event
- */
- SelectMenu.prototype.processKey = function(self, e){
- if($.inArray(e.keyCode, [38, 40, 27, 9, 13]) === -1){
- //if(e.keyCode != 16) self.setCssFocusedInput(self); // except Shift(16)
- if($.type(self.option.data) === 'string'){
- self.prop.last_input_time = e.timeStamp;
- setTimeout(function(){
- if((e.timeStamp - self.prop.last_input_time) === 0)
- self.checkValue(self);
- },self.option.inputDelay * 1000);
- }else{
- self.checkValue(self);
- }
- }
- }
- /**
- * Input element event handle( control key )
- * @param {Object} self
- * @param {Object} e - event
- */
- SelectMenu.prototype.processControl = function(self, e) {
- if (($.inArray(e.keyCode, [38, 40, 27, 9]) > -1 && self.elem.container.is(':visible')) ||
- ($.inArray(e.keyCode, [13, 9]) > -1 && self.getCurrentLine(self))) {
- e.preventDefault();
- e.stopPropagation();
- e.cancelBubble = true;
- e.returnValue = false;
- switch (e.keyCode) {
- case 38:// up
- self.prop.key_select = true;
- self.prevLine(self);
- break;
- case 40:// down
- if (self.elem.results.children('li').length) {
- self.prop.key_select = true;
- self.nextLine(self);
- } else self.suggest(self);
- break;
- case 9: // tab
- self.selectCurrentLine(self, true);
- //self.hideResults(self);
- break;
- case 13:// return
- self.selectCurrentLine(self, true);
- break;
- case 27:// escape
- self.hideResults(self);
- break;
- }
- }
- };
- /**
- * Populate menu data
- */
- SelectMenu.prototype.populate = function() {
- var self = this, p = this.option;
- if(!p.regular) self.elem.input.val('');
- /**
- * 1.Process data source
- */
- if(p.data){
- if($.type(p.data) === 'array'){
- self.prop.data = p.data;
- }else if($.type(p.data) === 'function'){
- self.prop.data = p.data();
- }
- }
- //Check data type
- if($.type(self.prop.data) === 'array')
- this.prop.data_type = this.checkDataType(self.prop.data);
- /**
- * 2.Set menu init selected
- */
- if($.type(p.data) !== 'string') self.setInitSelected(self, self.prop.data);
- /**
- * 3.Show data
- */
- if(p.regular) self.regularMenuInit();
- else self.suggest(self);
- //scrolling listen
- if(!p.embed) self.eScroll();
- };
- /**
- * Search suggest
- * @param {Object} self
- */
- SelectMenu.prototype.suggest = function(self) {
- var q_word, p = self.option,
- val = $.trim(self.elem.input.val());
- if(p.multiple) q_word = val;
- else{
- if(val && val === self.prop.selected_text) q_word = '';
- else q_word = val;
- }
- q_word = q_word.split(/[\s ]+/);
- self.setLoading(self);
- if ($.type(p.data) === 'array' || $.type(p.data) === 'function') self.search(self, q_word);
- };
- /**
- * Loading
- * @param {Object} self
- */
- SelectMenu.prototype.setLoading = function(self) {
- if (self.elem.results.html() === '') {
- //self.calcResultsSize(self);
- if(!self.option.embed) self.elem.container.addClass(self.css_class.container_open);
- }
- };
- /**
- * Search / load menu data
- * @param {Object} self
- * @param {Array} q_word - query keywords
- */
- SelectMenu.prototype.search = function(self, q_word) {
- var p = self.option, innerData = self.prop.data,
- matched = [], esc_q = [], sorted = [], json = {}, i = 0, arr_reg = [];
- do {
- //'/\W/g'正则代表全部不是字母,数字,下划线,汉字的字符
- //将非法字符进行转义
- esc_q[i] = q_word[i].replace(/\W/g, '\\$&').toString();
- arr_reg[i] = new RegExp(esc_q[i], 'gi');
- i++;
- } while ( i < q_word.length );
- var d = [];
- if(self.prop.data_index > (innerData.length-1) || self.prop.data_index < 0) self.prop.data_index = 0;
- if(self.prop.data_type === SelectMenu.dataTypeGroup){
- d = innerData[self.prop.data_index].list;
- }else d = innerData;
- // SELECT * FROM data WHERE field LIKE q_word;
- for (i = 0; i < d.length; i++) {
- var flag = false;
- var row = d[i];
- for (var j = 0; j < arr_reg.length; j++) {
- var itemText = row[p.searchField];
- if(p.formatItem && $.isFunction(p.formatItem))
- itemText = p.formatItem(row);
- if (itemText.match(arr_reg[j])) {
- flag = true;
- if (p.andOr == 'OR') break;
- } else {
- flag = false;
- if (p.andOr == 'AND') break;
- }
- }
- if (flag) matched.push(row);
- }
-
- // (CASE WHEN ...) then く order some field
- var reg1 = new RegExp('^' + esc_q[0] + '$', 'gi'),
- reg2 = new RegExp('^' + esc_q[0], 'gi'),
- matched1 = [], matched2 = [], matched3 = [];
- for (i = 0; i < matched.length; i++) {
- var orderField = p.orderBy[0][0],
- orderValue = String(matched[i][orderField]);
- if (orderValue.match(reg1)) {
- matched1.push(matched[i]);
- } else if (orderValue.match(reg2)) {
- matched2.push(matched[i]);
- } else {
- matched3.push(matched[i]);
- }
- }
- if (p.orderBy[0][1].match(/^asc$/i)) {
- matched1 = self.sortAsc(self, matched1);
- matched2 = self.sortAsc(self, matched2);
- matched3 = self.sortAsc(self, matched3);
- } else {
- matched1 = self.sortDesc(self, matched1);
- matched2 = self.sortDesc(self, matched2);
- matched3 = self.sortDesc(self, matched3);
- }
- sorted = sorted.concat(matched1).concat(matched2).concat(matched3);
- /*
- if (sorted.length === undefined || sorted.length === 0 ) {
- self.notFoundSearch(self);
- return;
- }
- */
- //json.cnt_whole = sorted.length;
- //Cache original row data
- json.originalResult = [];
- if(json.keyField === undefined) json.keyField = [];
- if(json.candidate === undefined) json.candidate = [];
- $.each(sorted, function(i,row){
- if(row === undefined || $.type(row) !== 'object') return true;
- json.originalResult.push(row);
- if(row.hasOwnProperty(p.keyField) && row.hasOwnProperty(p.showField)){
- json.keyField.push(row[p.keyField]);
- json.candidate.push(row[p.showField]);
- }
- });
- //json.cnt_page = json.candidate.length;
- self.prepareResults(self, json, q_word);
- };
- /**
- * Sort ascending
- * @param {Object} self
- * @param {Array} arr
- */
- SelectMenu.prototype.sortAsc = function(self, arr) {
- arr.sort(function(a, b) {
- var valA = a[self.option.orderBy[0][0]],
- valB = b[self.option.orderBy[0][0]];
- return $.type(valA) === 'number' ? valA - valB : String(valA).localeCompare(String(valB));
- });
- return arr;
- };
- /**
- * Sort descending
- * @param {Object} self
- * @param {Array} arr
- */
- SelectMenu.prototype.sortDesc = function(self, arr) {
- arr.sort(function(a, b) {
- var valA = a[self.option.orderBy[0][0]],
- valB = b[self.option.orderBy[0][0]];
- return $.type(valA) === 'number' ? valB - valA : String(valB).localeCompare(String(valA));
- });
- return arr;
- };
- /**
- * No result handle
- * @param {Object} self
- */
- SelectMenu.prototype.notFoundSearch = function(self) {
- self.elem.results.empty();
- self.calcResultsSize(self);
- self.elem.container.addClass(self.css_class.container_open);
- self.setCssFocusedInput(self);
- };
- /**
- * Prepare data to render menu item
- * @param {Object} self
- * @param {Object} json
- * @param {Array} q_word - query keywords
- */
- SelectMenu.prototype.prepareResults = function(self, json, q_word) {
- if (!json.keyField) json.keyField = false;
- if (self.option.selectOnly &&
- json.candidate.length === 1 &&
- json.candidate[0] == q_word[0]) {
- self.elem.hidden.val(json.keyField[0]);
- this.setButtonAttrDefault();
- }
- var is_query = false;
- if (q_word && q_word.length && q_word[0]) is_query = true;
- //self.setInitSelected(self,json.originalResult);
- self.displayResults(self, json, is_query);
- };
- /**
- * Render menu item
- * @param {Object} self
- * @param {Object} json
- * @param {boolean} is_query
- */
- SelectMenu.prototype.displayResults = function(self, json, is_query) {
- var p = self.option, el = self.elem, css = self.css_class;
- el.results.hide().empty();
- // build tabs
- if(self.prop.data_type === SelectMenu.dataTypeGroup) {
- var ul = $('<ul>');
- $.each(self.prop.data,function(i,row){
- var a = $('<a href="javascript:void(0);">').html(row.title).attr({
- 'tab_id' : self.prop.menu_tab_id_prefix + (i+1),
- 'data_index' : i
- });
- if(i === self.prop.data_index) a.addClass('active');
- var li = $('<li>').append(a);
- ul.append(li);
- });
- el.resultTabs.empty().append(ul);
- }else{
- el.resultTabs.hide();
- if(p.title || p.search) el.resultArea.addClass(this.css_class.re_list);
- }
- if(p.multiple && $.type(p.maxSelectLimit) === 'number' && p.maxSelectLimit){
- var selectedSize = self.prop.results.length;
- if(selectedSize && selectedSize >= p.maxSelectLimit){
- var msg = self.message.max_selected;
- self.showMessage(self, msg.replace(self.template.msg.maxSelectLimit, p.maxSelectLimit));
- return;
- }
- }
- if(json.candidate.length){
- var arr_candidate = json.candidate, arr_primary_key = json.keyField;
- for (var i = 0; i < arr_candidate.length; i++) {
- var itemText = '', custom = false, row = json.originalResult[i];
- if(p.formatItem && $.isFunction(p.formatItem)){
- try {
- itemText = p.formatItem(row);
- custom = true;
- } catch (e) {
- console.error('formatItem 内容格式化函数内容设置不正确!');
- itemText = arr_candidate[i];
- }
- }else itemText = arr_candidate[i];
- var icon = $('<div>').html('<i class="iconfont icon-selected">').addClass(css.selected_icon),
- text = $('<div>').html(itemText).addClass(css.item_text),
- li = $('<li>').append(icon).append(text).attr('pkey' , arr_primary_key[i]);
- if(!custom) li.attr('title',itemText);
- //set selected item to highlight
- if ($.inArray(row,self.prop.values) !== -1) {
- li.addClass(css.selected);
- }
- //cache item data
- li.data('dataObj',row);
- el.results.append(li);
- }
- }else{
- var li = '<li class="sm_message_box"><i class="iconfont icon-warn"></i> ' + self.message.not_found + '</li>';
- el.results.append(li);
- }
- el.results.show();
- self.calcResultsSize(self);
- if(!p.embed) el.container.addClass(css.container_open);
- //menu item event bind
- self.eResultList();
- //auto highlight first item in search, in have result and set autoSelectFirst to true situation
- //if (is_query && json.candidate.length > 0 && p.autoSelectFirst) self.nextLine(self);
- self.atLast(self);
- };
- /**
- * Calculate menu position and size
- * @param {Object} self
- */
- SelectMenu.prototype.calcResultsSize = function(self) {
- var p = self.option, el = self.elem, css = self.css_class,
- hasScroll = function(){
- return $(document).height() > $(window).height();
- };
- var setListHeight = function(){
- if(!p.regular){
- //result list height
- var itemHeight = el.results.find('li:first').outerHeight(),
- listHeight = itemHeight * p.listSize;
- el.results.css({
- 'max-height':listHeight
- });
- }
- };
- var scrollFlag = hasScroll();
- var rePosition = function(){
- var menuHeight = el.container.outerHeight(),
- screenScrollTop = $(window).scrollTop(),
- viewHeight = $(window).height();
- if(p.rightClick){
- var top = self.prop.y;
- if((self.prop.y + menuHeight) > (screenScrollTop + viewHeight))
- top = self.prop.y - menuHeight;
- return {top : top, left : self.prop.x};
- }
- var boxoffset = $(self.target).offset(),
- t = boxoffset.top,
- menuWidth = el.container.outerWidth(),
- targetWidth = Math.round($(self.target)[0].getBoundingClientRect().width),
- dist = 5;
- t += $(self.target).outerHeight() + dist;
- if(p.arrow && !p.embed) t += el.arrow.outerHeight(true);
- if((t + menuHeight) > (screenScrollTop + viewHeight)){
- t = boxoffset.top - dist - menuHeight;
- if(p.arrow && !p.embed) t -= el.arrow.outerHeight(true);
- el.container.removeClass(css.direction_bottom).addClass(css.direction_top);
- }else{
- if(el.container.hasClass(css.direction_top))
- el.container.removeClass(css.direction_top).addClass(css.direction_bottom);
- }
- var l = boxoffset.left;
- switch (p.position){
- case 'right':
- l = l + targetWidth - menuWidth;
- if(p.arrow) el.arrow.css('left',menuWidth - (targetWidth / 2));
- break;
- case 'center':
- l = l + (targetWidth / 2) - (menuWidth / 2);
- break;
- case 'left':
- default:
- if(p.arrow) el.arrow.css('left',targetWidth / 2);
- break;
- }
- return {top : t,left : l};
- }
- if(el.container.is(':visible')){
- setListHeight();
- if(!p.embed) el.container.offset(rePosition());
- }else{
- el.container.show(1,function(){
- setListHeight();
- $(this).offset(rePosition());
- });
- }
- if(scrollFlag !== hasScroll()) el.container.offset(rePosition());
- };
- /**
- *
- */
- SelectMenu.prototype.subMenuPosition = function(parent, menu){
- var pOffset = $(parent).offset();
- var t = pOffset.top,l = pOffset.left + $(parent).outerWidth() + 5;
- };
- /**
- * Hide menu
- * @param {Object} self
- */
- SelectMenu.prototype.hideResults = function(self) {
- var p = self.option;
- if (p.autoFillResult) {
- //self.selectCurrentLine(self, true);
- }
- if(!p.regular) self.elem.results.empty();
- if(!p.embed){
- self.elem.container.removeClass(self.css_class.container_open).hide();
- if($(self.target).is('button,.btn')) $(self.target).removeClass(self.css_class.target_clicked);
- }
- self.elem.resultArea.find('ul.'+self.css_class.results).not('.'+self.css_class.menu_root).hide();
- //remove animate class
- self.elem.results.removeClass('vivify').removeClass('fadeInLeft').show();
- $(window).off('scroll.SelectMenu');
- if(!p.regular && p.eHidden && $.isFunction(p.eHidden)) p.eHidden.call(self, self.prop.values.concat());
- };
- /**
- * do something after select/unSelect action
- * @param {Object} self
- */
- SelectMenu.prototype.afterAction = function(self){
- //$(self.elem.input).change();
- if(self.option.multiple){
- if(self.option.selectToCloseList){
- self.hideResults(self);
- self.elem.input.blur();
- }else{
- //self.suggest(self);
- self.elem.input.focus();
- }
- }else{
- self.hideResults(self);
- self.elem.input.blur();
- }
- };
- /**
- * Get current menu item
- * @param {Object} self
- */
- SelectMenu.prototype.getCurrentLine = function(self) {
- if (self.elem.container.is(':hidden')) return false;
- var obj = self.elem.results.find('li.' + self.css_class.select);
- if (obj.size()) return obj;
- else return false;
- };
- /**
- * Get selected menu item
- * @param self
- * @returns {*}
- */
- SelectMenu.prototype.getSelectedLine = function(self) {
- if (self.elem.container.is(':hidden')) return false;
- var obj = self.elem.results.find('li.' + self.css_class.selected);
- if (obj.size()) return obj;
- else return false;
- };
- /**
- * Selected menu item and trigger select callback
- * @param {Object} self
- * @param {boolean} is_enter_key
- */
- SelectMenu.prototype.selectCurrentLine = function(self, is_enter_key) {
- var current = self.getCurrentLine(self), p = self.option;
- if (current) {
- var rowData = current.data('dataObj'),
- id = String(rowData[p.keyField]);
- if($.inArray(rowData,self.prop.values) === -1){
- if(!p.multiple) self.prop.values.splice(0,self.prop.values.length);
- self.prop.values.push(rowData);
- if(!p.multiple)
- self.elem.results.find('li.' + self.css_class.selected).removeClass(self.css_class.selected);
- current.addClass(self.css_class.selected);
- } else{
- self.prop.values.splice($.inArray(rowData,self.prop.values),1);
- current.removeClass(self.css_class.selected);
- }
- //trigger callback
- if(p.eSelect && $.isFunction(p.eSelect)){
- if(p.multiple){
- p.eSelect.call(self, self.prop.values.concat());
- }else p.eSelect.call(self, [rowData]);
- }
- self.prop.prev_value = self.elem.input.val();
- self.prop.selected_text = self.elem.input.val();
- }
- if(!p.embed) self.afterAction(self);
- };
- /**
- * Select all menu item
- * @param {Object} self
- */
- SelectMenu.prototype.selectAllLine = function(self){
- self.elem.results.find('li').each(function(i,row){
- var d = $(row).data('dataObj');
- if($.inArray(d,self.prop.values) === -1) self.prop.values.push(d);
- $(this).addClass(self.css_class.selected);
- //limited max select items
- /*
- if($.type(self.option.maxSelectLimit) === 'number' &&
- self.option.maxSelectLimit > 0 &&
- self.option.maxSelectLimit === $('li.selected_tag',self.elem.element_box).size()){
- return false;
- }
- */
- });
- if(self.option.eSelect && $.isFunction(self.option.eSelect))
- self.option.eSelect.call(self, self.prop.values.concat());
- self.afterAction(self);
- };
- /**
- * Clear all selected menu items
- * @param {Object} self
- */
- SelectMenu.prototype.clearAll = function(self){
- var p = self.option, el = self.elem;
- el.input.val('');
- el.results.find('li').each(function(i,row){
- $(this).removeClass(self.css_class.selected);
- });
- self.prop.values.splice(0,self.prop.values.length);
- self.afterAction(self);
- if (p.eSelect && $.isFunction(p.eSelect)) p.eSelect.call(self, []);
- };
- /**
- * Select next menu item
- * @param {Object} self
- */
- SelectMenu.prototype.nextLine = function(self) {
- var obj = self.getCurrentLine(self), el = self.elem, idx;
- if (!obj) idx = -1;
- else {
- idx = el.results.children('li').index(obj);
- obj.removeClass(self.css_class.select);
- }
- idx++;
- var size = el.results.find('li').size();
- if(idx === size) idx = size - 1;
- if (idx < size) {
- var next = el.results.children('li').eq(idx);
- next.addClass(self.css_class.select);
- var itemHeight = el.results.find('li:first').outerHeight(),
- curTop = next.position().top,
- curScrollTop = el.resultArea.scrollTop(),
- listHeight = el.resultArea.outerHeight(),
- dist = curTop + itemHeight - listHeight;
- if((curTop + itemHeight) > listHeight)
- el.resultArea.scrollTop(curScrollTop + dist);
- }
- };
- /**
- * Select previous menu item
- * @param {Object} self
- */
- SelectMenu.prototype.prevLine = function(self) {
- var el = self.elem, idx, obj = self.getCurrentLine(self);
- if (!obj) idx = el.results.children('li').length;
- else {
- idx = el.results.children('li').index(obj);
- obj.removeClass(self.css_class.select);
- }
- idx--;
- if(idx < 0) idx = 0;
- if (idx > -1) {
- var prev = el.results.children('li').eq(idx),
- itemHeight = el.results.find('li:first').outerHeight(),
- curTop = prev.position().top,
- curScrollTop = el.resultArea.scrollTop(),
- listHeight = el.resultArea.outerHeight();
- prev.addClass(self.css_class.select);
- if((curTop > (curScrollTop + listHeight)) || (curTop < curScrollTop))
- el.resultArea.scrollTop(curScrollTop - (0 - curTop));
- }
- };
- /**
- * Check menu visible
- * @param self
- */
- SelectMenu.prototype.isVisible = function(self){
- return self.elem.container.hasClass(self.css_class.container_open);
- }
- /**
- * Init plugin entrance
- * @global
- * @memberof jQuery
- * @param option {Object} init parameters
- */
- function Plugin(option) {
- return this.each(function(){
- var $this = $(this),
- data = $this.data(SelectMenu.dataKey),
- params = $.extend({}, defaults, $this.data(), data && data.option ,typeof option === 'object' && option);
- if(!data) $this.data(SelectMenu.dataKey,(data = new SelectMenu(this,params)));
- else{
- if(data.isVisible(data)) data.hideResults(data);
- else data.showMenu(data);
- }
- });
- }
- /**
- * Hide menu
- */
- function HideMenu(){
- return this.each(function(){
- var $this = $(this),
- data = $this.data(SelectMenu.dataKey);
- if(data) data.hideResults(data);
- });
- }
- /**
- * Clear all menu selected item
- */
- function ClearSelected(){
- return this.each(function(){
- var $this = $(this),
- data = $this.data(SelectMenu.dataKey);
- if(data) data.clearAll(data);
- });
- }
- /**
- * Get selected item data
- */
- function GetSelected(){
- var results = new Array();
- this.each(function(){
- var $this =$(this),
- data = $this.data(SelectMenu.dataKey);
- if(data) results = data.prop.values.concat();
- });
- return results;
- }
- var old = $.fn.selectMenu;
- $.fn.selectMenu = Plugin;
- $.fn.selectMenu.Constructor = SelectMenu;
- $.fn.selectMenuHide = HideMenu;
- $.fn.selectMenuClear = ClearSelected;
- $.fn.selectMenuValues = GetSelected;
- // SelectMenu no conflict
- // =================
- $.fn.selectMenu.noConflict = function () {
- $.fn.selectMenu = old;
- return this;
- };
- })(window.jQuery);
|