], function (S, require, exports, module) { /** * @ignore * menu where items can be filtered based on user keyboard input * @author yiminghe@gmail.com */ var Menu = require('menu'); var FilterMenuTpl = require('./filter-menu/render-xtpl'); var HIT_CLS = 'menuitem-hit'; var ContentBox = require('component/extension/content-box'); var util = require('util'); /** * Filter Menu for KISSY. * xclass: 'filter-menu'. * @extends KISSY.Menu * @class KISSY.FilterMenu */ /** * Filter Menu for KISSY. * xclass: 'filter-menu'. * @extends KISSY.Menu * @class KISSY.FilterMenu */ module.exports = Menu.extend([ContentBox], { bindUI: function () { var self = this, filterInput = self.get('filterInput'); /*监控键盘事件*/ /*监控键盘事件*/ filterInput.on('input', self.handleFilterEvent, self); }, handleMouseEnterInternal: function (e) { var self = this; self.callSuper(e); // 权益解决,filter input focus 后会滚动到牌聚焦处,select 则不会 // 如果 filtermenu 的菜单项被滚轮滚到后面,点击触发不了,会向前滚动到 filter input // 权益解决,filter input focus 后会滚动到牌聚焦处,select 则不会 // 如果 filtermenu 的菜单项被滚轮滚到后面,点击触发不了,会向前滚动到 filter input self.getKeyEventTarget()[0].select(); }, handleFilterEvent: function () { var self = this, str, filterInput = self.get('filterInput'), highlightedItem = self.get('highlightedItem'); /* 根据用户输入过滤 */ /* 根据用户输入过滤 */ self.set('filterStr', filterInput.val()); str = filterInput.val(); if (self.get('allowMultiple')) { str = str.replace(/^.+,/, ''); } if (!str && highlightedItem) { highlightedItem.set('highlighted', false); } else if (str && (!highlightedItem || !highlightedItem.get('visible'))) { // 尽量保持原始高亮 // 如果没有高亮项或者高亮项因为过滤被隐藏了 // 默认选择符合条件的第一项 highlightedItem = self._getNextEnabledHighlighted(0, 1); if (highlightedItem) { highlightedItem.set('highlighted', true); } } }, _onSetFilterStr: function (v) { // 过滤条件变了立即过滤 this.filterItems(v); }, _onSetPlaceholder: function (v) { this.get('placeholderEl').html(v); }, getKeyEventTarget: function () { return this.get('filterInput'); }, /** * Specify how to filter items. * @param {String} str User input. */ filterItems: function (str) { var self = this, prefixCls = self.get('prefixCls'), _placeholderEl = self.get('placeholderEl'), filterInput = self.get('filterInput'); // 有过滤条件提示隐藏,否则提示显示 // 有过滤条件提示隐藏,否则提示显示 _placeholderEl[str ? 'hide' : 'show'](); if (self.get('allowMultiple')) { var enteredItems = [], lastWord; // \uff0c => , // \uff0c => , var match = str.match(/(.+)[,\uff0c]\s*([^\uff0c,]*)/); // 已经确认的项 // , 号之前的项必定确认 // 已经确认的项 // , 号之前的项必定确认 var items = []; if (match) { items = match[1].split(/[,\uff0c]/); } // 逗号结尾 // 如果可以补全,那么补全最后一项为第一个高亮项 // 逗号结尾 // 如果可以补全,那么补全最后一项为第一个高亮项 if (/[,\uff0c]$/.test(str)) { enteredItems = []; if (match) { enteredItems = items; //待补全的项 //待补全的项 lastWord = items[items.length - 1]; var item = self.get('highlightedItem'), content = item && item.get('content'); // 有高亮而且最后一项不为空补全 // 有高亮而且最后一项不为空补全 if (content && content.indexOf(lastWord) > -1 && lastWord) { enteredItems[enteredItems.length - 1] = content; } filterInput.val(enteredItems.join(',') + ','); } str = ''; } else { // 需要菜单过滤的过滤词,在最后一个 , 后面 if (match) { str = match[2] || ''; } // 没有 , 则就是当前输入的 // else{ str=str} //记录下 // 没有 , 则就是当前输入的 // else{ str=str} //记录下 enteredItems = items; } var oldEnteredItems = self.get('enteredItems'); // 发生变化,长度变化和内容变化等同 // 发生变化,长度变化和内容变化等同 if (oldEnteredItems.length !== enteredItems.length) { // S.log('enteredItems : '); // S.log(enteredItems); self.set('enteredItems', enteredItems); } } var children = self.get('children'), strExp = str && new RegExp(util.escapeRegExp(str), 'ig'); // 过滤所有子组件 // 过滤所有子组件 util.each(children, function (c) { var content = c.get('content'); if (!str) { // 没有过滤条件 // 恢复原有内容 // 显示出来 c.get('el').html(content); c.set('visible', true); } else { if (content.indexOf(str) > -1) { // 如果符合过滤项 // 显示 c.set('visible', true); // 匹配子串着重 input-wrap // 匹配子串着重 input-wrap c.get('el').html(content.replace(strExp, function (m) { return '<span class="' + prefixCls + HIT_CLS + '">' + m + '<' + '/span>'; })); } else { // 不符合 // 隐藏 c.set('visible', false); } } }); }, /** * Reset user input. */ reset: function () { var self = this; self.set('filterStr', ''); self.set('enteredItems', []); self.get('filterInput').val(''); } }, { ATTRS: { handleGestureEvents: { value: true }, focusable: { value: true }, allowTextSelection: { value: true }, contentTpl: { value: FilterMenuTpl }, filterInput: { selector: function () { return '.' + this.getBaseCssClass('input'); } }, filterInputWrap: { selector: function () { return '.' + this.getBaseCssClass('input-wrap'); } }, /** * Hit info string * @cfg {String} placeholder */ /** * @ignore */ placeholder: { render: 1, sync: 0, parse: function () { var placeholderEl = this.get('placeholderEl'); return placeholderEl && placeholderEl.html(); } }, placeholderEl: { selector: function () { return '.' + this.getBaseCssClass('placeholder'); } }, /** * Filter string * @cfg {String} filterStr */ /** * @ignore */ filterStr: {}, /** * user entered string list when allowMultiple. * @type {String[]} * @ignore */ enteredItems: { value: [] }, /** * Whether to allow input multiple. * @cfg {Boolean} allowMultiple */ /** * @ignore */ allowMultiple: { value: false } }, xclass: 'filter-menu' }); });
KISSY.add("filter-menu", ["menu", "filter-menu/render"], function(S, require) { var Menu = require("menu"); var FilterMenuRender = require("filter-menu/render"); var HIT_CLS = "menuitem-hit"; return Menu.extend({bindUI:function() { var self = this, filterInput = self.get("filterInput"); filterInput.on("input", self.handleFilterEvent, self) }, handleMouseEnterInternal:function(e) { var self = this; self.callSuper(e); self.view.getKeyEventTarget()[0].select() }, handleFilterEvent:function() { var self = this, str, filterInput = self.get("filterInput"), highlightedItem = self.get("highlightedItem"); self.set("filterStr", filterInput.val()); str = filterInput.val(); if(self.get("allowMultiple")) { str = str.replace(/^.+,/, "") } if(!str && highlightedItem) { highlightedItem.set("highlighted", false) }else { if(str && (!highlightedItem || !highlightedItem.get("visible"))) { highlightedItem = self._getNextEnabledHighlighted(0, 1); if(highlightedItem) { highlightedItem.set("highlighted", true) } } } }, _onSetFilterStr:function(v) { this.filterItems(v) }, filterItems:function(str) { var self = this, prefixCls = self.get("prefixCls"), _placeholderEl = self.get("placeholderEl"), filterInput = self.get("filterInput"); _placeholderEl[str ? "hide" : "show"](); if(self.get("allowMultiple")) { var enteredItems = [], lastWord; var match = str.match(/(.+)[,\uff0c]\s*([^\uff0c,]*)/); var items = []; if(match) { items = match[1].split(/[,\uff0c]/) } if(/[,\uff0c]$/.test(str)) { enteredItems = []; if(match) { enteredItems = items; lastWord = items[items.length - 1]; var item = self.get("highlightedItem"), content = item && item.get("content"); if(content && content.indexOf(lastWord) > -1 && lastWord) { enteredItems[enteredItems.length - 1] = content } filterInput.val(enteredItems.join(",") + ",") } str = "" }else { if(match) { str = match[2] || "" } enteredItems = items } var oldEnteredItems = self.get("enteredItems"); if(oldEnteredItems.length !== enteredItems.length) { self.set("enteredItems", enteredItems) } } var children = self.get("children"), strExp = str && new RegExp(S.escapeRegExp(str), "ig"); S.each(children, function(c) { var content = c.get("content"); if(!str) { c.get("el").html(content); c.set("visible", true) }else { if(content.indexOf(str) > -1) { c.set("visible", true); c.get("el").html(content.replace(strExp, function(m) { return'<span class="' + prefixCls + HIT_CLS + '">' + m + "<" + "/span>" })) }else { c.set("visible", false) } } }) }, reset:function() { var self = this; self.set("filterStr", ""); self.set("enteredItems", []); self.get("filterInput").val("") }}, {ATTRS:{allowTextSelection:{value:true}, placeholder:{view:1}, filterStr:{}, enteredItems:{value:[]}, allowMultiple:{value:false}, xrender:{value:FilterMenuRender}}, xclass:"filter-menu"}) });
KISSY.add(function(S, require) { _$jscoverage['/filter-menu.js'].functionData[0]++; _$jscoverage['/filter-menu.js'].lineData[7]++; var Menu = require('menu'); _$jscoverage['/filter-menu.js'].lineData[8]++; var FilterMenuRender = require('filter-menu/render'); _$jscoverage['/filter-menu.js'].lineData[10]++; var HIT_CLS = 'menuitem-hit'; _$jscoverage['/filter-menu.js'].lineData[18]++; return Menu.extend({ bindUI: function() { _$jscoverage['/filter-menu.js'].functionData[1]++; _$jscoverage['/filter-menu.js'].lineData[20]++; var self = this, filterInput = self.get('filterInput'); _$jscoverage['/filter-menu.js'].lineData[23]++; filterInput.on('input', self.handleFilterEvent, self); }, handleMouseEnterInternal: function(e) { _$jscoverage['/filter-menu.js'].functionData[2]++; _$jscoverage['/filter-menu.js'].lineData[27]++; var self = this; _$jscoverage['/filter-menu.js'].lineData[28]++; self.callSuper(e); _$jscoverage['/filter-menu.js'].lineData[31]++; self.view.getKeyEventTarget()[0].select(); }, handleFilterEvent: function() { _$jscoverage['/filter-menu.js'].functionData[3]++; _$jscoverage['/filter-menu.js'].lineData[35]++; var self = this, str, filterInput = self.get('filterInput'), highlightedItem = self.get('highlightedItem'); _$jscoverage['/filter-menu.js'].lineData[40]++; self.set('filterStr', filterInput.val()); _$jscoverage['/filter-menu.js'].lineData[41]++; str = filterInput.val(); _$jscoverage['/filter-menu.js'].lineData[42]++; if (visit6_42_1(self.get('allowMultiple'))) { _$jscoverage['/filter-menu.js'].lineData[43]++; str = str.replace(/^.+,/, ''); } _$jscoverage['/filter-menu.js'].lineData[46]++; if (visit7_46_1(!str && highlightedItem)) { _$jscoverage['/filter-menu.js'].lineData[47]++; highlightedItem.set('highlighted', false); } else { _$jscoverage['/filter-menu.js'].lineData[52]++; if (visit8_52_1(str && (visit9_52_2(!highlightedItem || !highlightedItem.get('visible'))))) { _$jscoverage['/filter-menu.js'].lineData[53]++; highlightedItem = self._getNextEnabledHighlighted(0, 1); _$jscoverage['/filter-menu.js'].lineData[54]++; if (visit10_54_1(highlightedItem)) { _$jscoverage['/filter-menu.js'].lineData[55]++; highlightedItem.set('highlighted', true); } } } }, '_onSetFilterStr': function(v) { _$jscoverage['/filter-menu.js'].functionData[4]++; _$jscoverage['/filter-menu.js'].lineData[62]++; this.filterItems(v); }, filterItems: function(str) { _$jscoverage['/filter-menu.js'].functionData[5]++; _$jscoverage['/filter-menu.js'].lineData[70]++; var self = this, prefixCls = self.get('prefixCls'), _placeholderEl = self.get('placeholderEl'), filterInput = self.get('filterInput'); _$jscoverage['/filter-menu.js'].lineData[76]++; _placeholderEl[str ? 'hide' : 'show'](); _$jscoverage['/filter-menu.js'].lineData[78]++; if (visit11_78_1(self.get('allowMultiple'))) { _$jscoverage['/filter-menu.js'].lineData[79]++; var enteredItems = [], lastWord; _$jscoverage['/filter-menu.js'].lineData[82]++; var match = str.match(/(.+)[,\uff0c]\s*([^\uff0c,]*)/); _$jscoverage['/filter-menu.js'].lineData[86]++; var items = []; _$jscoverage['/filter-menu.js'].lineData[88]++; if (visit12_88_1(match)) { _$jscoverage['/filter-menu.js'].lineData[89]++; items = match[1].split(/[,\uff0c]/); } _$jscoverage['/filter-menu.js'].lineData[94]++; if (visit13_94_1(/[,\uff0c]$/.test(str))) { _$jscoverage['/filter-menu.js'].lineData[95]++; enteredItems = []; _$jscoverage['/filter-menu.js'].lineData[96]++; if (visit14_96_1(match)) { _$jscoverage['/filter-menu.js'].lineData[97]++; enteredItems = items; _$jscoverage['/filter-menu.js'].lineData[99]++; lastWord = items[items.length - 1]; _$jscoverage['/filter-menu.js'].lineData[100]++; var item = self.get('highlightedItem'), content = visit15_101_1(item && item.get('content')); _$jscoverage['/filter-menu.js'].lineData[103]++; if (visit16_103_1(content && visit17_103_2(visit18_103_3(content.indexOf(lastWord) > -1) && lastWord))) { _$jscoverage['/filter-menu.js'].lineData[104]++; enteredItems[enteredItems.length - 1] = content; } _$jscoverage['/filter-menu.js'].lineData[106]++; filterInput.val(enteredItems.join(',') + ','); } _$jscoverage['/filter-menu.js'].lineData[108]++; str = ''; } else { _$jscoverage['/filter-menu.js'].lineData[111]++; if (visit19_111_1(match)) { _$jscoverage['/filter-menu.js'].lineData[112]++; str = visit20_112_1(match[2] || ''); } _$jscoverage['/filter-menu.js'].lineData[118]++; enteredItems = items; } _$jscoverage['/filter-menu.js'].lineData[120]++; var oldEnteredItems = self.get('enteredItems'); _$jscoverage['/filter-menu.js'].lineData[122]++; if (visit21_122_1(oldEnteredItems.length !== enteredItems.length)) { _$jscoverage['/filter-menu.js'].lineData[125]++; self.set('enteredItems', enteredItems); } } _$jscoverage['/filter-menu.js'].lineData[129]++; var children = self.get('children'), strExp = visit22_130_1(str && new RegExp(S.escapeRegExp(str), 'ig')); _$jscoverage['/filter-menu.js'].lineData[133]++; S.each(children, function(c) { _$jscoverage['/filter-menu.js'].functionData[6]++; _$jscoverage['/filter-menu.js'].lineData[134]++; var content = c.get('content'); _$jscoverage['/filter-menu.js'].lineData[135]++; if (visit23_135_1(!str)) { _$jscoverage['/filter-menu.js'].lineData[139]++; c.get('el').html(content); _$jscoverage['/filter-menu.js'].lineData[140]++; c.set('visible', true); } else { _$jscoverage['/filter-menu.js'].lineData[142]++; if (visit24_142_1(content.indexOf(str) > -1)) { _$jscoverage['/filter-menu.js'].lineData[145]++; c.set('visible', true); _$jscoverage['/filter-menu.js'].lineData[147]++; c.get('el').html(content.replace(strExp, function(m) { _$jscoverage['/filter-menu.js'].functionData[7]++; _$jscoverage['/filter-menu.js'].lineData[148]++; return '<span class="' + prefixCls + HIT_CLS + '">' + m + '<' + '/span>'; })); } else { _$jscoverage['/filter-menu.js'].lineData[153]++; c.set('visible', false); } } }); }, reset: function() { _$jscoverage['/filter-menu.js'].functionData[8]++; _$jscoverage['/filter-menu.js'].lineData[163]++; var self = this; _$jscoverage['/filter-menu.js'].lineData[164]++; self.set('filterStr', ''); _$jscoverage['/filter-menu.js'].lineData[165]++; self.set('enteredItems', []); _$jscoverage['/filter-menu.js'].lineData[166]++; self.get('filterInput').val(''); }}, { ATTRS: { allowTextSelection: { value: true}, placeholder: { view: 1}, filterStr: {}, enteredItems: { value: []}, allowMultiple: { value: false}, xrender: { value: FilterMenuRender}}, xclass: 'filter-menu'}); });