《关键字选取三步走:第四步,控件 在一个页面多次使用封装

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" onclick="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>



2.selectDIV.js
// 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) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎

你可能感兴趣的:(《关键字选取三步走:第四步,控件 在一个页面多次使用封装)