一个小小的tag标签输入插件

40 篇文章 0 订阅

设计

这里写图片描述
这里写图片描述

核心代码

css

.tag-clearFix{}
.tag-clearFix:after{
    clear: both;
    content:"";
    display: block;

}
/* tag */
.default-tag a,.default-tag a span,.plus-tag a,.plus-tag a em,.plus-tag-add a{background:url(images/tagbg.png) no-repeat;}
.tagbtn a{color:#333333;display:block;float:left;height:22px;line-height:22px;overflow:hidden;margin:0 10px 10px 0;padding:0 10px 0 5px;white-space:nowrap;}
/* default-tag */
.default-tag{padding:16px 0 0 0;}
.default-tag a{background-position:100% 0;}
.default-tag a:hover{background-position:100% -22px;}
.default-tag a span{padding:0 0 0 11px;background-position:0 -60px;}
.default-tag a:hover span{background-position:0 -98px;}
.default-tag a.selected{opacity:0.6;filter:alpha(opacity=60);}
.default-tag a.selected:hover{background-position:100% 0;cursor:default;}
.default-tag a.selected:hover span{background-position:0 -60px;}
/* plus-tag */
.plus-tag{padding:0 0 10px 0;}
.plus-tag a{background-position:100% -22px;}
.plus-tag a span{float:left;}
.plus-tag a em{display:block;float:left;margin:5px 0 0 8px;width:13px;height:13px;overflow:hidden;background-position:-165px -100px;cursor:pointer;}
.plus-tag a:hover em{background-position:-168px -64px;}
/* plus-tag-add */
.plus-tag-add li{height:56px;position:relative;}
.plus-tag-add li .label{position:absolute;left:-110px;top:7px;display:block;}
.plus-tag-add button{float:left;}
.plus-tag-add a{float:left;margin:12px 0 0 20px;display:inline;font-size:18px;background-position:-289px -59px;padding:0 0 0 16px;}
.plus-tag-add a.plus{background-position:-289px -96px;}

js


var CustomTagErrorCode={
    OVERLIMIT:"OVERLIMIT"//超过可选择的最大限制数量
    ,DUPLICATE:"DUPLICATE"//重复value。
};

var CustomTag=function(_opts){
    var defaults={
        options:[
            {value:"1",name:"我是默认的1啊",checked:true}
            ,{value:"2",name:"我是默认的2啊",checked:true}
            ,{value:"3",name:"我是默认的3啊",checked:false}
            ,{value:"4",name:"我是默认的4444啊",checked:true}
            ,{value:"5",name:"我是默认的55啊",checked:false}
        ] //所有选项
        ,limit:9999 //默认限制选中多少个。。。
        ,tpl_option:'<a ui="tag-option" selected="false" value="{{=d.value}}" val="{{=d.value}}" title="{{=d.name}}" href="javascript:void(0);" class=""><span>{{=d.name}}</span><em></em></a>' //可以提供选择的区域
        ,tpl_selected:'<a ui="tag-selected-option" value="{{=d.value}}" val="{{=d.value}}" title="{{=d.name}}" href="javascript:void(0);"><span>{{=d.name}}</span><em ui="btn-close"></em></a>'//选中以后渲染到选中列表的模板

        //--这是当可选择区域的选项状态发生变化时候的动作,譬如,默认的处理方式是:样式选中以后+selected,没有选中-selected
        ,optionSelectedChange:function(trueOrFalse,currentOptionElement){
            if(trueOrFalse){
                if($(currentOptionElement).hasClass("selected")==false){
                    $(currentOptionElement).addClass("selected");
                }
            }
            else{
                $(currentOptionElement).removeClass("selected");
            }
        }
        ,onWarning:function(ErrorCode){
            if(ErrorCode==CustomTagErrorCode.DUPLICATE){
                alert("不能插入重复键值。");
            }
            else if(ErrorCode==CustomTagErrorCode.OVERLIMIT){
                alert("最多只能选中三个标签");
            }
            else{
                alert("未定义错误");
            }
        }//这是自定义错误显示方式。你可以用自定义提示插件的。

        ,selectedContainer:""//这是显示已经选中的选项的容器。必须要有。
        ,optionContainer:null //这是待选择选项的容器,默认为null。

        ,onInit:function(){} //初始化成功以后执行该方法。
    };

    $.extend(defaults,_opts);


    var container_select="";
    var container_option=null;
    var tpl_selected={};
    var tpl_option={};

    var appData={
        dataMap:{} //这是将标签数据转换成为obj map的存储形式。
        ,hasOptionPanel:false //是否有选择区域。
        //,dataList:[] //当前的数组形式的值。

    };



    var app={
        init:function(){
            var me=this;
            me.initData();
            me.initUI();
            defaults.onInit();
        }
        ,initData:function(){
            if(defaults.optionContainer!=undefined&&defaults.optionContainer!=null&&$(defaults.optionContainer).length>0){
                appData.hasOptionPanel=true;
                container_option=$(defaults.optionContainer);
                tpl_option=laytpl(defaults.tpl_option);
            }
            container_select=$(defaults.selectedContainer);
            tpl_selected=laytpl(defaults.tpl_selected);

//        for(var i=0;i<defaults.options.length;i++){
//          var _item={};
//          $.extend(_item,defaults.options[i]);
//          appData.dataMap[_item.value]=_item;
//        }

        }//转换数据存储形式。
        ,initUI:function(){
            var me=this;
            container_select.empty();
            if(appData.hasOptionPanel){
                container_option.empty();
            }
            for(var i=0;i<defaults.options.length;i++){
                var item=defaults.options[i];
                me.addOption(item);
            }

        }

        //--错了,改用统一接口,直接addOption

        //--初始化相关列表。
        ,addOption:function(optionInfo,checkLimit){
            var me=this;
            if(checkLimit==true){
                var _arr=me.getSelectedArray();
                if(_arr.length>=defaults.limit){
                    defaults.onWarning(CustomTagErrorCode.OVERLIMIT);
                    return;
                }
            }
            if(appData.dataMap[optionInfo["value"]]!=undefined){
                defaults.onWarning(CustomTagErrorCode.DUPLICATE);
                return;
            }

            appData.dataMap[optionInfo["value"]]= $.extend({},optionInfo);
            if(optionInfo["checked"]==true){
                var _select_html=tpl_selected.render(optionInfo);
                var _select_el=$(_select_html);

                me._initSelectedItemEvents(_select_el);
                container_select.append(_select_el);
            }
            if(appData.hasOptionPanel){
                var _option_html=tpl_option.render(optionInfo);
                var _option_el=$(_option_html);
                me._initOptionItemEvents(_option_el);
                if(optionInfo["checked"]==true){
                    defaults.optionSelectedChange(true,_option_el);
                }
                else{
                    defaults.optionSelectedChange(false,_option_el);
                }
                container_option.append(_option_el);
            }
        }
        //--设置某个元素为选中或者不选中状态。
        ,setSelected:function(val,trueOrFalse,checkLimit){
            var me=this;
            if(appData.dataMap[val]==undefined){
                me.delOption(val);
                return;
            }
            if(checkLimit==true&&trueOrFalse==true){
                var _arr=me.getSelectedArray();
                if(_arr.length>=defaults.limit){
                    defaults.onWarning(CustomTagErrorCode.OVERLIMIT);
                    return;
                }
            }
            var _item=appData.dataMap[val];
            if(trueOrFalse){
                _item.checked=true;
                var _select_el=container_select.find('[ui="tag-selected-option"][val="'+val+'"]');
                if(_select_el.length>0){
                    //_select_el.remove();已经有了那就不继续了。

                }
                else{
                    var _select_html=tpl_selected.render(_item);
                    var _select_el=$(_select_html);

                    me._initSelectedItemEvents(_select_el);
                    container_select.append(_select_el);
                }
                if(appData.hasOptionPanel){
                    var _option_el=container_option.find('[ui="tag-option"][val="'+val+'"]');
                    if(_option_el.length>0){
                        //_option_el.remove();
                        defaults.optionSelectedChange(true,_option_el);
                    }
                    else{
                        var _option_html=tpl_option.render(_item);
                        _option_el=$(_option_html);
                        me._initOptionItemEvents(_option_el);
                        if(_item["checked"]==true){
                            defaults.optionSelectedChange(true,_option_el);
                        }
                        else{
                            defaults.optionSelectedChange(false,_option_el);
                        }
                        container_option.append(_option_el);
                    }
                }


            }
            else{
                _item.checked=false;
                var _select_el=container_select.find('[ui="tag-selected-option"][val="'+val+'"]');
                if(_select_el.length>0){
                    _select_el.remove();
                }

                if(appData.hasOptionPanel){
                    var _option_el=container_option.find('[ui="tag-option"][val="'+val+'"]');
                    if(_option_el.length>0){
                        //_option_el.remove();
                        defaults.optionSelectedChange(false,_option_el);
                    }
                    else{
                        var _option_html=tpl_option.render(_item);
                        _option_el=$(_option_html);
                        me._initOptionItemEvents(_option_el);
                        if(_item["checked"]==true){
                            defaults.optionSelectedChange(true,_option_el);
                        }
                        else{
                            defaults.optionSelectedChange(false,_option_el);
                        }
                        container_option.append(_option_el);
                    }
                }

            }

        }


        //--删除某个元素。
        ,delOption:function(val){
            if(appData.dataMap[val]!=undefined){
                delete appData.dataMap[val];
            }
            var _select_el=container_select.find('[ui="tag-selected-option"][val="'+val+'"]');
            if(_select_el.length>0){
                _select_el.remove();
            }
            if(appData.hasOptionPanel){
                var _option_el=container_option.find('[ui="tag-option"][val="'+val+'"]');
                if(_option_el.length>0){
                    _option_el.remove();
                }
            }

        }
        ,getSelectedArray:function(){
            var arr=[];
            for(var key in appData.dataMap){
                var _item=appData.dataMap[key];
                if(_item["value"]!=undefined){
                    if(_item["checked"]==true){
                        arr.push(_item);
                    }
                }
            }

            return arr;
        }

        ,_initOptionItemEvents:function(el){
            var me=this;
            $(el).click(function(){
                var _val=$(this).attr("val");
                if(appData.dataMap[_val]==undefined){
                    me.delOption(_val);
                    return;
                }
                var _item=appData.dataMap[_val];
                if(_item.checked==true){
                    console.log("已经选中了,不需要继续。");
                    return;
                }
                else{
                    me.setSelected(_val,true,true);
                }

            });
        }//初始化该选择框的方法。
        ,_initSelectedItemEvents:function(el){
            var me=this;
            $(el).find('[ui="btn-close"]').click(function(){
                console.log("点击我了。");
                var select_el={};
                select_el=$(this).closest('[ui="tag-selected-option"]');
                var _val=select_el.attr("val");
                me.setSelected(_val,false);
            });
        }//初始化该选择框的方法。.
        ,clear:function(){
            appData.dataMap={};
            container_select.empty();
            if(appData.hasOptionPanel){
                container_option.empty();
            }
        }
    };

    app.init();
    var returnObj={
        addOption:function(name,value,checked){
            var _option={
                name:name
                ,value:value
                ,checked:checked?true:false
            };
            app.addOption(_option,true);
        }
        ,delOption:function(val){
            app.delOption(val);

        }
        ,setSelect:function(val,trueOrFalse){
            app.setSelected(val,trueOrFalse);
        }
        ,clear:function(){
            app.clear();
        }
    };
    return returnObj;
}

htmldemo

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2015/11/30
  Time: 10:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>自定义标签插件。</title>
  <script type="text/javascript" src="/static/lib/jquery-1.11.0.min.js"></script>
  <script type="text/javascript" src="/static/lib/util.min.js"></script>
  <script type="text/javascript" src="/static/vendor/laytpl/laytpl.js"></script>
  <script type="text/javascript" src="tag.js"></script>
  <link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>

<h1>自定义标签控件演示。</h1>
<h3>完全功能演示</h3>

<div><span>请输入插入的键值对</span><span>value:<input type="text" value="" id="txt-value"></span><span>name:<input type="text" value="" id="txt-name"></span></div>
<div><input type="button" value="插入" id="btn-insert"></div>

<h3>已经选择的区域</h3>
<div id="select-area" class="plus-tag tagbtn tag-clearFix">

</div>

<h3>可供选择的区域</h3>
<div id="option-area" class="nowtips tag-clearFix default-tag tagbtn">

</div>

<script type="text/javascript">

  $(function(){
    var _tagPlugin=CustomTag({
           selectedContainer:$("#select-area")//这是显示已经选中的选项的容器。必须要有。
            ,optionContainer:$("#option-area") //这是待选择选项的容器,默认为null。
    });
    var txt_name=$("#txt-name");
    var txt_value=$("#txt-value");
    var btn_insert=$("#btn-insert");
    btn_insert.click(function(){
      if(util.checkEmpty(txt_name.val())||util.checkEmpty(txt_value.val())){
        alert("value和name都必须填写");
        return;
      }
      _tagPlugin.addOption(txt_name.val(),txt_value.val(),true);
    });
  });

</script>

</body>
</html>

效果

这里写图片描述

丑就丑了,改改样式就好。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值