1.页面上多个集成的控件同时使用。出现 数组的操作 无法传递,和操作无效。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>告警标准规范解释录入</title> <link href="/Styles/main.css" rel="stylesheet" type="text/css" /> <script charset="gb2312" type="text/javascript" src="Scripts/jquery-1.8.0.js"></script> <script type="text/javascript"> var jQuery = $.noConflict(true); //jquery重命名 var SaveArrayObj = new Array(); var SaveArrayObjtest=new Array(); </script> <%--多选--%> <link rel="stylesheet" type="text/css" href="Scripts/mutiselect/multiselectSrc/jquery.multiselect.css" /> <link rel="stylesheet" type="text/css" href="Scripts/mutiselect/assets/style.css" /> <link rel="stylesheet" type="text/css" href="Scripts/mutiselect/assets/prettify.css" /> <link rel="stylesheet" type="text/css" href="Scripts/mutiselect/ui/jquery-ui.css" /> <script type="text/javascript" src="Scripts/mutiselect/ui/jquery.ui.core.js"></script> <script type="text/javascript" src="Scripts/mutiselect/ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="Scripts/mutiselect/assets/prettify.js"></script> <script type="text/javascript" src="Scripts/mutiselect/multiselectSrc/jquery.multiselect.js" ></script> <%--关键字--%> <link rel="stylesheet" type="text/css" href="Scripts/KeyTab/KeyTab.css" /> <script type="text/javascript" src="Scripts/KeyTab/tabControl.js" charset="gb2312" ></script> <script type="text/javascript" src="Scripts/KeyTab/selectDIV.js" charset="gb2312" ></script> <script type="text/javascript"> jQuery(function () { jQuery("#sela").multiselect({ selectedList: 4, StorageArray:"SaveArrayObj", targetID:"tag", tipID:"tip", mulsel:"sela" }); jQuery("#sel").selectText({StorageArray:"SaveArrayObj",targetID:"tag",tipID:"tip"}); jQuery("#tag").tabControl({ maxTabCount: 8, tabW: 80,StorageArray:"SaveArrayObj", targetID:"tag",tipID:"tip" }, "Jquery插件,Jquery插件1");//多设置一个. //test jQuery("#selatest").multiselect({ selectedList: 4, StorageArray:"SaveArrayObjtest", targetID:"tagtest", tipID:"tiptest", mulsel:"selatest" }); jQuery("#seltest").selectText({StorageArray:"SaveArrayObjtest",targetID:"tagtest",tipID:"tiptest"}); jQuery("#tagtest").tabControl({ maxTabCount: 8, tabW: 80,StorageArray:"SaveArrayObjtest", targetID:"tagtest",tipID:"tiptest" }, "test,test1");//多设置一个. }); function showValues() { var valuestr = jQuery("#sela").multiselect("MyValues"); alert(valuestr); } function ArrayText() { jQuery("#ArrayText").val(SaveArrayObj.join(',')+SaveArrayObjtest.join(',')); } </script> </head> <body > <div id="tip" style="display:none;position:absolute;z-index:10"><img src="/images/tick.png" width="30px" height="30px"/></div> <div id="tiptest" style="display:none;position:absolute;z-index:10"><img src="/images/tick.png" width="30px" height="30px"/></div> <p> <select id ="sela" multiple="multiple" name="example-basic" size="5" > <option value="V1">Option 1</option> <option value="V2">Option 2</option> <option value="V3">Option 3</option> </select> </p> <div id="tag"></div> <textarea id="sel" style="width:600px;overflow-x:hidden; height: 150px; text-align: left; padding: 10px; border: 2px #E0E0E0 inset; line-height: 25px;"></textarea> <input type="button" οnclick="javascript:ArrayText();"/> <textarea id="ArrayText" style="Width:1050px; height:100px"></textarea> <p> <select id ="selatest" multiple="multiple" name="example-basic" size="5" > <option value="V1">Option 1</option> <option value="V2">Option 2</option> <option value="V3">Option 3</option> </select> </p> <div id="tagtest"></div> <textarea id="seltest" style="width:600px;overflow-x:hidden; height: 150px; text-align: left; padding: 10px; border: 2px #E0E0E0 inset; line-height: 25px;"></textarea> <textarea id="ArrayTexttest" style="Width:1050px; height:100px"></textarea> </body> </html> |
// JavaScript Document var SWord = { text: '', Start: 0, End: 0 }; var rect = { left: -1, top: -1, width: -1, height: -1, start_left: -1 }; function ptInRect(rect, pt) { if (pt.x > rect.left && pt.x < rect.left + rect.width && pt.x > rect.start_left) if (pt.y > rect.top && pt.y < rect.top + rect.height) return true; return false; } //得到鼠标的位置 function getMouse(ev) { // if (ev.pageX || ev.pageY) { // return { // x: ev.pageX, // y: ev.pageY // }; // } return { x: ev.clientX + document.body.scrollLeft - document.body.clientLeft, y: ev.clientY + document.body.scrollTop - document.body.clientTop }; } var isin = true; (function($) { $.fn.extend({ "selectText": function(options) { //初始化参数变量 var defOpt = { delays: 800, StorageArray:"", targetID:"", tipID:"" }; var value = jQuery.extend(defOpt, options); var $this = $(this); $this.keydown(function(event) { SWord.Start = 0; SWord.End = 0; SWord.word = ''; jQuery("#"+value.tipID).hide(); rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; }); //鼠标抬起进,获取选择文字的字数。并根据字数,是否显示弹出层 $this.mouseup(function(event) { var str = ""; if (document.selection) { // IE 用简单的方式,记录坐标 var str = document.selection.createRange(); var position = getMouse(event); if (ptInRect(rect, position)) { jQuery("#"+value.tipID).hide(); rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; } else { if (str.text.length > 1) { isin = false; rect.left = str.boundingLeft;//对象左距离 rect.top = str.boundingTop; rect.width = str.boundingWidth; rect.height = str.boundingHeight; rect.start_left = str.offsetLeft;//版面左 rect.end_left = str.offsetTop;//版面顶 jQuery("#"+value.tipID).css({ "top": event.pageY + 10, "left": event.pageX + 10 }).delay(value.delays).show(); SWord.word = str.text; } else { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; jQuery("#"+value.tipID).hide(); } } } else { var p1 = this.selectionStart; var p2 = this.selectionEnd; if (p1 || p1 == '0') { if (p1 != p2) { //选中 if (p1 >= SWord.Start && p2 <= SWord.End) { SWord.Start = 0; SWord.End = 0; SWord.word = ''; jQuery("#"+value.tipID).hide(); }else { p1=p1<p2?p1:p2; p2=p2>p1?p2:p1; SWord.Start = p1; SWord.End = p2; SWord.word = this.value.substring(p1, p2); jQuery("#"+value.tipID).css({ "top": event.pageY + 10, "left": event.pageX + 10 }).delay(value.delays).show(); } } else //点击 { SWord.Start = 0; SWord.End = 0; SWord.word = ''; jQuery("#"+value.tipID).hide(); } } } }); //点击文档任何位置,让显示的层消失 $(document).click(function() { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; jQuery("#"+value.tipID).hide(); }); jQuery("#"+value.tipID).click(function() { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; alert(SWord.word); window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); var arrayP=eval(value.StorageArray); alert(arrayP.length); var n = arrayP.findStrinArray(SWord.word); if (-1===n) { var inputObj=jQuery("#"+value.targetID+" input[type='text'][name='tabinput']:last"); inputObj.val(SWord.word); inputObj.data("isModify", false) inputObj.blur(); }else { alert("此内容已经存在,请重新输入."); return; } }); //阻止冒泡,防止第一次选中文字时,由于冒泡,而触发了$(document).click事件 $this.click(function(event) { event.stopPropagation(); }); return $this; } }) })(jQuery) |
3.tabControl.js
Array.prototype.findStrinArray = function (str) {//查找 for (var i in this) { if (str === this[i]) return i; } return -1; } Array.prototype.del = function (n) {//n表示第几项,从0开始算起。--删除 if (n < 0)//如果n<0,则不进行任何操作。 return this; else if(parseInt(n)===0){ return this.shift(); }else { //return this.slice(0, n).concat(this.slice(parseInt(n) + 1, this.length)); return this.splice(parseInt(n), 1); } } Array.prototype.finddel = function (str) {//--查找并删除 var n = this.findStrinArray(str); return this.del(n); } /** *标签控件 *功能:按Enter或Tab或失去焦点确定标签输入完毕,双击文字可以编辑该标签,单击叉叉(×)表示删除该标签 *tabControl:function *参数说明: *initTabCount:int 一开始初始化标签输入框的数量; *maxTabCount:int 容器可接受最大的标签数量; *tabMaxLen:int 每个标签允许接受最大的字符长度; *tabW:int 标签输入框的宽度; *tabH:int 标签输入框的高度; *tipTOffset:int 提示信息与标签输入框的top偏移量; *tipLOffset:int 提示信息与标签输入框的left偏移量; *tags:string 初始化的标签内容,以逗号为间隔; **/ jQuery.fn.extend({ tabControl: function (options, tags) { //初始化参数变量 var defOpt = { initTabCount: 0, maxTabCount: 100, tabMaxLen: 25, tabW: 150, tabH: 15, tipTOffset: 5, tipLOffset: 0, StorageArray:"", targetID:"", tipID:"" }; //初始化构造函数 var opts = jQuery.extend(defOpt, options); //参数变量,用户设置变量值。 合并:用户设置值替换初始参数值。 //初始化标签内容。用户填写。 var _tags= new Array(); //当前录入关键字集合。 if (tags) { tags = tags.replace(/^,+|,+$/gi, "").replace(/,,+/gi, ",").replace(/[^A-Za-z0-9_,\u4E00-\u9FA5]+/gi, ""); //将非中英文、数字、下划、逗号的其他字符都去掉,且不能以逗号开头与结束 _tags = tags.split(','); } //初始标签过多省略处理。 _tags = _tags.length > opts.maxTabCount ? _tags.slice(0, opts.maxTabCount - 1) : _tags; var arrayP=eval(opts.StorageArray); for (var i=0;i<_tags.length;i++) { arrayP.push(_tags[i]); } opts.initTabCount = _tags.length; var checkReg = /[^A-Za-z0-9_\u4E00-\u9FA5]+/gi; //只有数字,英文,中文 var initTab = function (obj, index) {//初始化标签输入 div,index索引 var textHtml = "<input class='tabinput' name='tabinput' style='width:" + opts.tabW + "px;height:" + opts.tabH + "px;' type='text'/>"; obj.append(textHtml); if (_tags[index]) {//值 var __inputobj = jQuery("input[type='text'][name='tabinput']", obj).eq(index); __inputobj.val(_tags[index].substr(0, opts.tabMaxLen)).css("display", "none"); //输入,隐藏input compTab(obj, __inputobj, _tags[index].substr(0, opts.tabMaxLen)); } jQuery("input[type='text'][name='tabinput']:last", obj).bind("keydown blur click", function (event) { if (event.type == "click") {//阻止(浏览器)默认行为。 return false; } if (event.keyCode == 13 || event.keyCode == 9 || event.type == "blur") { event.preventDefault(); //不失去焦點(即阻止(浏览器)默认的行为) event.stopPropagation(); //阻止事件起泡 var inputObj = jQuery(this); var value = jQuery(this).val().replace(/\s+/gi, ""); //空格替换 if ((event.keyCode == 13 || event.keyCode == 9) && value != "")//IE inputObj.data("isIEKeyDown", true); if (event.type == "blur" && inputObj.data("isIEKeyDown")) { inputObj.removeData("isIEKeyDown"); return; } if (value != "") { if (value.length > opts.tabMaxLen) { showMes(jQuery(this), "请输入1到" + opts.tabMaxLen + "个字符长度的标签"); return; } var _match = value.match(checkReg); if (!_match) { compTab(obj, inputObj, value); //先隐藏掉input,显示span if (jQuery("input[type='text'][name='tabinput']", obj).length < opts.maxTabCount) { if (!inputObj.data("isModify")) { arrayP=eval(opts.StorageArray); var n = arrayP.findStrinArray(value); if (-1 === n) { initTab(obj); arrayP.push(value); } else { showMes(inputObj, "此内容已经存在,请重新输入."); showErr(); return; } } else //if (!jQuery("input[type='text'][name='tabinput']", obj).is(":hidden")) //{ { arrayP=eval(opts.StorageArray); var n = arrayP.findStrinArray(value); if (-1 === n) { //initTab(obj); arrayP.push(value); } else { showMes(inputObj, "此内容已经存在,请重新输入."); showErr(); return; } } //} } inputObj.data("isModify", false); hideErr(); jQuery("input[type='text']:last", obj).focus(); } else { showMes(inputObj, "內容不能包含非法字符「{0}」!".replace("{0}", _match.join(" "))); } } else { if (inputObj.data("isModify") || event.type != "blur")//初始的和错误提示的都是false //showMes(inputObj, "內容不為空"); 我先修改错了。 然后再修改为空。 { arrayP=eval(opts.StorageArray); //删除当前input和span --数组值 inputObj.next("span").remove(); arrayP.finddel(inputObj.val()); inputObj.remove(); hideErr(); } } } }).bind("focus", function () { var t = jQuery(this); if (t.css("display") != "none" && t.val() != "") { showErr(); } else { hideErr(); } }); } //完成标签编写 var compTab = function (obj, inputObj, value) {//div input text var tt = inputObj.next("span"); inputObj.next("span").remove(); //删除紧跟input元素後的span var _span = "<span name='tab' id='radius'><b>" + value + "</b><a id='deltab'>×</a></span>"; inputObj.after(_span).hide(); //元素之后插入。--inputObj隐藏 inputObj.next("span").find("a").click(function () { if (confirm("确定删除该标签?")) { inputObj.next("span").remove(); inputObj.remove(); arrayP=eval(opts.StorageArray); arrayP.finddel(value); if (jQuery("span[name='tab']", obj).length == opts.maxTabCount - 1)//span的个数如果等于最大值-1,则建立新的。 initTab(obj); } }); inputObj.next("span").dblclick(function () { inputObj.data("isModify", true).next("span").remove(); //修改时,设置为true。 arrayP=eval(opts.StorageArray); arrayP.finddel(value); inputObj.show().focus(); }); } //构造返回对象。 --每一个tag元素都执行,这里就一个div。 return this.each(function () { var jqObj = jQuery(this); for (var i = 0; i < opts.initTabCount; i++) { initTab(jqObj, i); } initTab(jqObj); jqObj.data("isInit", true); jqObj.click(function () { jQuery("input[type='text'][name='tabinput']", jqObj).each(function () { if (jQuery(this).val() == "") { jQuery(this).focus(); return false; } }); }); }); function showMes(inputObj, mes) { var kkk=jQuery("#errormes"+opts.targetID); jQuery("#errormes"+opts.targetID).remove(); inputObj.next("span").remove(); //设置为修改--false inputObj.show(); var _offset = inputObj.offset(); var _mesHtml = "<div id='errormes"+opts.targetID+"' class='radius_shadow' style='zoom:1;position:absolute;left:" + (_offset.left + opts.tipLOffset) + "px;top:" + (_offset.top + opts.tabH + opts.tipTOffset) + "px;'>" + mes + "</div>"; jQuery("body").append(_mesHtml); //inputObj.focus(); } function hideErr() { var kkk=jQuery("#errormes"+opts.targetID); jQuery("#errormes"+opts.targetID).remove(); //jQuery("#errormes"+opts.targetID).hide(); var t = jQuery("#"+opts.targetID+" input[type='text'][name='tabinput']:visible:first"); if (t && t.val() != "") { t.blur(); } } function showErr() { var kkk=jQuery("#errormes"+opts.targetID); jQuery("#errormes"+opts.targetID).show(); } }, getTabVals: function () {//获取当前容器所生成的tab值,结果是一维数组 var obj = jQuery(this); var values = []; obj.children("span[name=\"tab\"][id^=\"radius\"]").find("b").text(function (index, text) { //alert(index);0.1.2 var checkReg = /[^A-Za-z0-9_\u4E00-\u9FA5]+/gi; values.push(text.replace(checkReg, "")); }); return values; }, SetTabVal: function (val) { //单个选中插入 //选中, 第一要看已存在。 }, SetTabVals: function (val) {//多个选中插入 //选中, 第一每个都要看已存在。 然后插入。 }, AllDelete: function () {//全部删除 //单个删除中,并没有对数量的操作。 //全部删除,好办。 } }); |
4.jquery.multiselect.js
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */ /* * jQuery MultiSelect UI Widget 1.14pre * Copyright (c) 2012 Eric Hynds * * http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/ * * Depends: * - jQuery 1.4.2+ * - jQuery UI 1.8 widget factory * * Optional: * - jQuery UI effects * - jQuery UI position utility * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ (function ($, undefined) { var multiselectID = 0; var $doc = $(document); var multiValues = ""; $.widget("ech.multiselect", { // default options options: { header: false, height: 175, minWidth: 225, classes: '', checkAllText: '全选', uncheckAllText: '全不选', noneSelectedText: '==请选择==', selectedText: '# selected', selectedList: 0, show: null, hide: null, autoOpen: false, multiple: true, position: {}, appendTo: "body", StorageArray:"", targetID:"", tipID:"", mulsel:"" }, _create: function () { var el = this.element.hide(); var o = this.options; this.speed = $.fx.speeds._default; // default speed for effects this._isOpen = false; // assume no // create a unique namespace for events that the widget // factory cannot unbind automatically. Use eventNamespace if on // jQuery UI 1.9+, and otherwise fallback to a custom string. this._namespaceID = this.eventNamespace || ('multiselect' + multiselectID); var button = (this.button = $('<button type="button"><span class="ui-icon ui-icon-triangle-1-s"></span></button>')) .addClass('ui-multiselect ui-widget ui-state-default ui-corner-all') .addClass(o.classes) .attr({ 'title': el.attr('title'), 'aria-haspopup': true, 'tabIndex': el.attr('tabIndex') }) .insertAfter(el), buttonlabel = (this.buttonlabel = $('<span />')) .html(o.noneSelectedText) .appendTo(button), menu = (this.menu = $('<div />')) .addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all') .addClass(o.classes) .appendTo($(o.appendTo)), header = (this.header = $('<div />')) .addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix') .appendTo(menu), headerLinkContainer = (this.headerLinkContainer = $('<ul />')) .addClass('ui-helper-reset') .html(function () { if (o.header === true) { return '<li><a class="ui-multiselect-all" href="#"><span class="ui-icon ui-icon-check"></span><span>' + o.checkAllText + '</span></a></li><li><a class="ui-multiselect-none" href="#"><span class="ui-icon ui-icon-closethick"></span><span>' + o.uncheckAllText + '</span></a></li>'; } else if (typeof o.header === "string") { return '<li>' + o.header + '</li>'; } else { return ''; } }) .append('<li class="ui-multiselect-close"><a href="#" class="ui-multiselect-close"><span class="ui-icon ui-icon-circle-close"></span></a></li>') .appendTo(header), checkboxContainer = (this.checkboxContainer = $('<ul />')) .addClass('ui-multiselect-checkboxes ui-helper-reset') .appendTo(menu); // perform event bindings this._bindEvents(); // build menu this.refresh(true); // some addl. logic for single selects if (!o.multiple) { menu.addClass('ui-multiselect-single'); } // bump unique ID multiselectID++; }, _init: function () { if (this.options.header === false) { this.header.hide(); } if (!this.options.multiple) { this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').hide(); } if (this.options.autoOpen) { this.open(); } if (this.element.is(':disabled')) { this.disable(); } }, refresh: function (init) { var el = this.element; var o = this.options; var menu = this.menu; var checkboxContainer = this.checkboxContainer; var optgroups = []; var html = ""; var id = el.attr('id') || multiselectID++; // unique ID for the label & option tags // build items el.find('option').each(function (i) { var $this = $(this); var parent = this.parentNode; var description = this.innerHTML; var title = this.title; var value = this.value; var inputID = 'ui-multiselect-' + (this.id || id + '-option-' + i); var isDisabled = this.disabled; var isSelected = this.selected; var labelClasses = ['ui-corner-all']; var liClasses = (isDisabled ? 'ui-multiselect-disabled ' : ' ') + this.className; var optLabel; // is this an optgroup? if (parent.tagName === 'OPTGROUP') { optLabel = parent.getAttribute('label'); // has this optgroup been added already? if ($.inArray(optLabel, optgroups) === -1) { html += '<li class="ui-multiselect-optgroup-label ' + parent.className + '"><a href="#">' + optLabel + '</a></li>'; optgroups.push(optLabel); } } if (isDisabled) { labelClasses.push('ui-state-disabled'); } // browsers automatically select the first option // by default with single selects if (isSelected && !o.multiple) { labelClasses.push('ui-state-active'); } html += '<li class="' + liClasses + '">'; // create the label html += '<label for="' + inputID + '" title="' + title + '" class="' + labelClasses.join(' ') + '">'; html += '<input id="' + inputID + '" name="multiselect_' + id + '" type="' + (o.multiple ? "checkbox" : "radio") + '" value="' + value + '" title="' + title + '"'; // pre-selected? if (isSelected) { html += ' checked="checked"'; html += ' aria-selected="true"'; } // disabled? if (isDisabled) { html += ' disabled="disabled"'; html += ' aria-disabled="true"'; } // add the title and close everything off html += ' /><span>' + description + '</span></label></li>'; }); // insert into the DOM checkboxContainer.html(html); // cache some moar useful elements this.labels = menu.find('label'); this.inputs = this.labels.children('input'); // set widths this._setButtonWidth(); this._setMenuWidth(); // remember default value this.button[0].defaultValue = this.update(); // broadcast refresh event; useful for widgets if (!init) { this._trigger('refresh'); } }, MyValues: function () { return multiValues; }, // updates the button text. call refresh() to rebuild update: function () { var o = this.options; var $inputs = this.inputs; var $checked = $inputs.filter(':checked'); var numChecked = $checked.length; var value; if (numChecked === 0) { value = o.noneSelectedText; multiValues = ''; } else { if ($.isFunction(o.selectedText)) { value = o.selectedText.call(this, numChecked, $inputs.length, $checked.get()); } else if (/\d/.test(o.selectedList) && o.selectedList > 0 && numChecked <= o.selectedList) { value = $checked.map(function () { return $(this).next().html(); }).get().join(', '); } else { value = o.selectedText.replace('#', numChecked).replace('#', $inputs.length); } multiValues = $checked.map(function () { return $(this).val(); }).get().join(', '); } this._setButtonValue(value); //alert(multiValues); return value; }, // this exists as a separate method so that the developer // can easily override it. _setButtonValue: function (value) { this.buttonlabel.text(value); }, // binds events _bindEvents: function () { var self = this; var button = this.button; function clickHandler() { self[self._isOpen ? 'close' : 'open'](); return false; } // webkit doesn't like it when you click on the span :( button .find('span') .bind('click.multiselect', clickHandler); // button events button.bind({ click: clickHandler, keypress: function (e) { switch (e.which) { case 27: // esc case 38: // up case 37: // left self.close(); break; case 39: // right case 40: // down self.open(); break; } }, mouseenter: function () { if (!button.hasClass('ui-state-disabled')) { $(this).addClass('ui-state-hover'); } }, mouseleave: function () { $(this).removeClass('ui-state-hover'); }, focus: function () { if (!button.hasClass('ui-state-disabled')) { $(this).addClass('ui-state-focus'); } }, blur: function () { $(this).removeClass('ui-state-focus'); } }); // header links this.header.delegate('a', 'click.multiselect', function (e) { // close link if ($(this).hasClass('ui-multiselect-close')) { self.close(); // check all / uncheck all } else { self[$(this).hasClass('ui-multiselect-all') ? 'checkAll' : 'uncheckAll'](); } e.preventDefault(); }); // optgroup label toggle support this.menu.delegate('li.ui-multiselect-optgroup-label a', 'click.multiselect', function (e) { e.preventDefault(); var $this = $(this); var $inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible:not(:disabled)'); var nodes = $inputs.get(); var label = $this.parent().text(); // trigger event and bail if the return is false if (self._trigger('beforeoptgrouptoggle', e, { inputs: nodes, label: label }) === false) { return; } // toggle inputs self._toggleChecked( $inputs.filter(':checked').length !== $inputs.length, $inputs ); self._trigger('optgrouptoggle', e, { inputs: nodes, label: label, checked: nodes[0].checked }); }) .delegate('label', 'mouseenter.multiselect', function () { if (!$(this).hasClass('ui-state-disabled')) { self.labels.removeClass('ui-state-hover'); $(this).addClass('ui-state-hover').find('input').focus(); } }) .delegate('label', 'keydown.multiselect', function (e) { e.preventDefault(); switch (e.which) { case 9: // tab case 27: // esc self.close(); break; case 38: // up case 40: // down case 37: // left case 39: // right self._traverse(e.which, this); break; case 13: // enter $(this).find('input')[0].click(); break; } }) .delegate('input[type="checkbox"], input[type="radio"]', 'click.multiselect', function (e) { var $this = $(this); var val = this.value; var checked = this.checked; if(checked) { var arrayP=eval(self.options.StorageArray); var n = arrayP.findStrinArray(val); if (-1===n) { var inputObj=jQuery("#"+self.options.targetID+" input[type='text'][name='tabinput']:last"); inputObj.val(val); inputObj.data("isModify", false) inputObj.blur(); }else { alert("此内容已经存在,请重新输入."); return; } }else { var arrayP=eval(self.options.StorageArray); var n = arrayP.findStrinArray(val); if (-1!=n) { var inputObj=jQuery("#"+self.options.targetID+" input[type='text'][name='tabinput']").eq(n); inputObj.next("span").remove(); inputObj.remove(); arrayP.finddel(val); } } var tags = self.element.find('option'); // bail if this input is disabled or the event is cancelled if (this.disabled || self._trigger('click', e, { value: val, text: this.title, checked: checked }) === false) { e.preventDefault(); return; } // make sure the input has focus. otherwise, the esc key // won't close the menu after clicking an item. $this.focus(); // toggle aria state $this.attr('aria-selected', checked); // change state on the original option tags tags.each(function () { if (this.value === val) { this.selected = checked; } else if (!self.options.multiple) { this.selected = false; } }); // some additional single select-specific logic if (!self.options.multiple) { self.labels.removeClass('ui-state-active'); $this.closest('label').toggleClass('ui-state-active', checked); // close menu self.close(); } // fire change on the select box self.element.trigger("change"); // setTimeout is to fix multiselect issue #14 and #47. caused by jQuery issue #3827 // http://bugs.jquery.com/ticket/3827 setTimeout($.proxy(self.update, self), 10); }); // close each widget when clicking on any other element/anywhere else on the page $doc.bind('mousedown.' + this._namespaceID, function (event) { var target = event.target; if (self._isOpen && target !== self.button[0] && target !== self.menu[0] && !$.contains(self.menu[0], target) && !$.contains(self.button[0], target) ) { self.close(); } }); // deal with form resets. the problem here is that buttons aren't // restored to their defaultValue prop on form reset, and the reset // handler fires before the form is actually reset. delaying it a bit // gives the form inputs time to clear. $(this.element[0].form).bind('reset.multiselect', function () { setTimeout($.proxy(self.refresh, self), 10); }); }, // set button width _setButtonWidth: function () { var width = this.element.outerWidth(); var o = this.options; if (/\d/.test(o.minWidth) && width < o.minWidth) { width = o.minWidth; } // set widths this.button.outerWidth(width); }, // set menu width _setMenuWidth: function () { var m = this.menu; m.outerWidth(this.button.outerWidth()); }, // move up or down within the menu _traverse: function (which, start) { var $start = $(start); var moveToLast = which === 38 || which === 37; // select the first li that isn't an optgroup label / disabled var $next = $start.parent()[moveToLast ? 'prevAll' : 'nextAll']('li:not(.ui-multiselect-disabled, .ui-multiselect-optgroup-label)').first(); // if at the first/last element if (!$next.length) { var $container = this.menu.find('ul').last(); // move to the first/last this.menu.find('label')[moveToLast ? 'last' : 'first']().trigger('mouseover'); // set scroll position $container.scrollTop(moveToLast ? $container.height() : 0); } else { $next.find('label').trigger('mouseover'); } }, // This is an internal function to toggle the checked property and // other related attributes of a checkbox. // // The context of this function should be a checkbox; do not proxy it. _toggleState: function (prop, flag) { return function () { if (!this.disabled) { this[prop] = flag; } if (flag) { this.setAttribute('aria-selected', true); } else { this.removeAttribute('aria-selected'); } }; }, _toggleChecked: function (flag, group) { if(flag){ alert("全选"); }else{ alert("全不选"); } var $inputs = (group && group.length) ? group : this.inputs; var self = this; // toggle state on inputs $inputs.each(this._toggleState('checked', flag)); // give the first input focus $inputs.eq(0).focus(); // update button text this.update(); // gather an array of the values that actually changed var values = $inputs.map(function () { return this.value; }).get(); // toggle state on original option tags this.element .find('option') .each(function () { if (!this.disabled && $.inArray(this.value, values) > -1) { self._toggleState('selected', flag).call(this); } }); // trigger the change event on the select if ($inputs.length) { this.element.trigger("change"); } }, _toggleDisabled: function (flag) { this.button.attr({ 'disabled': flag, 'aria-disabled': flag })[flag ? 'addClass' : 'removeClass']('ui-state-disabled'); var inputs = this.menu.find('input'); var key = "ech-multiselect-disabled"; if (flag) { // remember which elements this widget disabled (not pre-disabled) // elements, so that they can be restored if the widget is re-enabled. inputs = inputs.filter(':enabled').data(key, true) } else { inputs = inputs.filter(function () { return $.data(this, key) === true; }).removeData(key); } inputs .attr({ 'disabled': flag, 'arial-disabled': flag }) .parent()[flag ? 'addClass' : 'removeClass']('ui-state-disabled'); this.element.attr({ 'disabled': flag, 'aria-disabled': flag }); }, // open the menu open: function (e) { var self = this; var button = this.button; var menu = this.menu; var speed = this.speed; var o = this.options; var args = []; // bail if the multiselectopen event returns false, this widget is disabled, or is already open if (this._trigger('beforeopen') === false || button.hasClass('ui-state-disabled') || this._isOpen) { return; } var $container = menu.find('ul').last(); var effect = o.show; // figure out opening effects/speeds if ($.isArray(o.show)) { effect = o.show[0]; speed = o.show[1] || self.speed; } // if there's an effect, assume jQuery UI is in use // build the arguments to pass to show() if (effect) { args = [effect, speed]; } // set the scroll of the checkbox container $container.scrollTop(0).height(o.height); // positon this.position(); // show the menu, maybe with a speed/effect combo $.fn.show.apply(menu, args); // select the first not disabled option // triggering both mouseover and mouseover because 1.4.2+ has a bug where triggering mouseover // will actually trigger mouseenter. the mouseenter trigger is there for when it's eventually fixed this.labels.filter(':not(.ui-state-disabled)').eq(0).trigger('mouseover').trigger('mouseenter').find('input').trigger('focus'); button.addClass('ui-state-active'); this._isOpen = true; this._trigger('open'); }, // close the menu close: function () { if (this._trigger('beforeclose') === false) { return; } var o = this.options; var effect = o.hide; var speed = this.speed; var args = []; // figure out opening effects/speeds if ($.isArray(o.hide)) { effect = o.hide[0]; speed = o.hide[1] || this.speed; } if (effect) { args = [effect, speed]; } $.fn.hide.apply(this.menu, args); this.button.removeClass('ui-state-active').trigger('blur').trigger('mouseleave'); this._isOpen = false; this._trigger('close'); }, enable: function () { this._toggleDisabled(false); }, disable: function () { this._toggleDisabled(true); }, checkAll: function (e) { this._toggleChecked(true); this._trigger('checkAll'); }, uncheckAll: function () { this._toggleChecked(false); this._trigger('uncheckAll'); }, getChecked: function () { return this.menu.find('input').filter(':checked'); }, destroy: function () { // remove classes + data $.Widget.prototype.destroy.call(this); // unbind events $doc.unbind(this._namespaceID); this.button.remove(); this.menu.remove(); this.element.show(); return this; }, isOpen: function () { return this._isOpen; }, widget: function () { return this.menu; }, getButton: function () { return this.button; }, position: function () { var o = this.options; // use the position utility if it exists and options are specifified if ($.ui.position && !$.isEmptyObject(o.position)) { o.position.of = o.position.of || this.button; this.menu .show() .position(o.position) .hide(); // otherwise fallback to custom positioning } else { var pos = this.button.offset(); this.menu.css({ top: pos.top + this.button.outerHeight(), left: pos.left }); } }, // react to option changes after initialization _setOption: function (key, value) { var menu = this.menu; switch (key) { case 'header': menu.find('div.ui-multiselect-header')[value ? 'show' : 'hide'](); break; case 'checkAllText': menu.find('a.ui-multiselect-all span').eq(-1).text(value); break; case 'uncheckAllText': menu.find('a.ui-multiselect-none span').eq(-1).text(value); break; case 'height': menu.find('ul').last().height(parseInt(value, 10)); break; case 'minWidth': this.options[key] = parseInt(value, 10); this._setButtonWidth(); this._setMenuWidth(); break; case 'selectedText': case 'selectedList': case 'noneSelectedText': this.options[key] = value; // these all needs to update immediately for the update() call this.update(); break; case 'classes': menu.add(this.button).removeClass(this.options.classes).addClass(value); break; case 'multiple': menu.toggleClass('ui-multiselect-single', !value); this.options.multiple = value; this.element[0].multiple = value; this.refresh(); break; case 'position': this.position(); } $.Widget.prototype._setOption.apply(this, arguments); } }); })(jQuery); |
OK。 到现在为止,功能全部完成,
唯一的问题就是, 标签显示的部分需要把输入的要求设置成足够大。 因为,此框架在逻辑上有点问题。
特别是最后一个的时候, 我已经想到方法去改进。 但是暂时不再花费时间。
本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎