menuSel选择下拉框

/* style基础样式 */
.menuDownWarp{
    position: absolute;
    margin: 6px 0 0 -10px;
    background-color: #fff;
    border: 1px solid #e3e3e3;
    width: 160px;
}
.menuDownWarp .on{
    background-color: #f0f0f0;
}
.menuDownWarp li{
    padding: 0 5px;
    line-height: 30px;
    cursor: pointer;
}

// 可以指定skin参数,通过修改样式中的margin值来修正定位等一些样式
// 创建菜单示例
callback : function(msg){
    msg = msg || [];
    var htm = '<li class="on g-hidden">' + this.val() + '</li>';
    for( var i = 0,l = msg.length;i < l; i++ ){
        htm += '<li data-id="'+msg[i].brand_id+'">' + msg[i].brand_name + '</li>';
    }
    return htm;
}
// 创建的菜单项带有额外复杂数据示例
callback : function(msg){
    msg = msg || [];
    var htm = $('<li class="on g-hidden">' + this.val() + '</li>');
    for( var k in msg ) {
        htm = htm.add($('<li>' + k + '</li>').data('db',msg[k]));
    }
    return htm;
},
enterMenu : function($e){
    // 菜单项带的额外复杂数据
    $e.data('db');
}
/**
 * 【功能描述】
 * 下拉框选择
 * 插件参数是一个对象
 * html对象要添加自定义属性getdataurl,指定ajax获取数据的url
 * callback:方法返回li标签的html字符串菜单选项,第一个li标签要给class加上参数的active值并且隐藏,值为输入框的默认值(键盘上下键时可以选到默认值),函数上下文是输入框,参数可以是异步getdataurl获取回来的数据也可以是直接传递待处理的data参数
 * data:可以直接传递待处理的数据过来
 * toSelectListData:用户在下拉框中做选择更改输入框值时执行的函数,函数的上下文是输入框,参数是当前选择的那一个li标签对象
 * toUserInputData:当用户选择自己输入的数据时要执行的函数,函数上下文是输入框
 * enterMenu:当最终确认选择了一条数据后要执行的函数(不论选择哪一条数据),函数上下文是输入框,参数是当前选择的那一个li标签对象
 * enter:按回车键时是否自动触发提交表单动作,默认不触发提交
 * skin:用来用户自定义样式的class属性,默认menuDownWarp(注意都是class名,不带.)
 * active:激活选项的class属性,默认on(注意都是class名,不带.)
 */
$.fn.menuSel = function(option){
    var def = {
        skin : 'menuDownWarp',
        active : 'on',
        toSelectListData : function(){},
        toUserInputData : function(){},
        enterMenu : function(){},
        enter : false,
        data : null
    };
    var o = $.extend(def,option || {});
    var $wrap = $('<ul class="' + o.skin + '"></ul>').appendTo('body');


    this.each(function(){
        var $t = $(this);


        var $e;


        // 确保如果异步请求处理数据时,当网络速度慢时,失去焦点能够保证隐藏下拉框
        $t.posting = true;


        // 保证按键后值有变化才会触发下拉修改请求(中文输入多个拼音才会改变内容)
        $t.oldval = $.trim($t.val());


        $t.keydown(function(e){


            var keyCode = e.keyCode;
            var $child = $wrap.children();
            var $on = $child.filter('.'+o.active);
            var datalist = o.data;
            var execFn = {
                '40' : 'next',
                '38' : 'prev'
            };
            var $addon;
            var fixPosi = {
                '40' : ':first',
                '38' : ':last'
            };


            // 上下键
            if ( keyCode === 38 || keyCode === 40 ) {


                // 通过键盘操作找到要添加on的元素
                $addon = $on[execFn[keyCode]]();


                // 如果没找到,就根据键盘操作找直接定位到第一或最后一个
                if ( !$addon.length ) {
                    $addon = $on.siblings(fixPosi[keyCode])
                }


                $e = $addon;


                // 给找到的元素加上class
                _addActive();


                // 当更改输入框值时执行的函数
                _changeval();


                return false;
            } else if ( keyCode === 13 ) { // 回车
            
                // 隐藏下拉框
                $t.blur();
                if ( o.enter ) {
                    $t.closest('form').submit();
                }
                return false;
            }
        }).keyup(function(e){


            var keyCode = e.keyCode;
            var ajaxurl = $t.attr('getdataurl');
            function _addMenu(htm){


                $t.posting = true;


                htm = $(htm);
                // 如果只有一个默认值没有更多选项就直接隐藏下拉并退出函数
                if ( htm.length === 1 ) {
                    $wrap.hide();
                    return false;
                }


                // 第一个li隐藏,文本内容为用户输入的
                $wrap.html(htm);
                // 定位下拉框的位置并显示
                $wrap.css({
                    left : $t.offset().left,
                    top : $t.offset().top + $t.height()
                }).show().children().click(function(){


                    $e = $(this);
                    // 当更改输入框值时执行的函数
                    _changeval();


                }).mouseover(function(){
                    $e = $(this);
                    _addActive();
                });
            }


            // 当输入为非回车时,并且不是按的上下键,并且按键后与按键前的值不同
            if ( keyCode !== 13 && keyCode !== 38 && keyCode !== 40 && $t.oldval != $.trim($t.val()) ) {


                $t.oldval = $.trim($t.val());


                $t.posting = false;


                o.toUserInputData.call($t);


                // 如果直接传了待处理数据
                if ( o.data !== null ) {
                    _addMenu(o.callback.call($t,datalist));
                } else if ( ajaxurl ) { // 如果有异步请求数据地址
                    
                    $.ajax({
                        url : ajaxurl,
                        data : $t.serialize(),
                        dataType : 'json',
                        type : 'post',
                        success : function(msg){
                            _addMenu(o.callback.call($t,datalist = msg));
                        }
                    });
                }
            }
        }).blur(function(){
            // 隐藏下拉框
            var timer = setInterval(function(){
                if ( $t.posting ) {
                    $wrap.hide();
                    clearTimeout(timer);
                    // 如果选择了菜单项,输入后要执行的函数
                    $e && o.enterMenu.call($t,$e);
                }
            }, 100)
        });


        function _addActive(){
            var cname = o.active;
            $e.addClass(o.active).siblings().removeClass(o.active);
        }


        // 改变输入框值时执行的函数
        function _changeval(){


            var val = $.trim($e.text());


            // 从菜单中选择值
            if ( $e.index() > 0 ) {
                o.toSelectListData.call($t,$e);
            } else {
                // 如果是自己输入的值非菜单选择值
                o.toUserInputData.call($t);
            }


            // _changeval.item = $e;


            // 输入框的值与选择的记录同步
            $t.val(val);
        }
    })
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值