jquery控制select控件升级 datalist, fastadmin和selectpage控件(由input优化而来) selectpage默认值

   HTML5中定义了一种input框很好看的下拉列表--datalist,然而目前它的支持性并不好(万恶的IE,好在你要渐渐退役了...)。于是最近更据需求写了一个小型datalist插件,兼容到IE8(IE7应该没多少人用了吧?)。实现的具体需求如下:

      当被选中的时候(触发blur焦点)(不管是鼠标还是tab键)清空input框并且显示自定义的下拉列表,然后可以用键盘的上下键选择(鼠标当然肯定没理由不可以啦),单击鼠标左键或者enter键将选中的列表的值输入到input框。

      具体的实现代码如下:

HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="robots" content="index, follow" />
<meta name="googlebot" content="index, follow" />
<meta name="author" content="codetker" />
    <title> 表单选中弹出框</title>
<link href="css/reset.css" type="text/css" rel="Stylesheet" /> 
<link href="css/master.css" type="text/css" rel="Stylesheet" /> 

<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
</head>

<body>
    <div class="wrap">
        <form class="center">
            <div class="input_wrap">
                <input name="input1" class="input input1" type="text"/>
                <ul class="input1_ul select_list">
                    <li>问题1</li>
                    <li>问题2</li>
                    <li>问题3</li>
                    <li>问题4</li>
                    <li>问题5</li>
                </ul>
            </div>
        </form>
    </div>
<script type="text/javascript" src="js/jquery.codetker.datalist.js"></script>
<script type="text/javascript">
$(document).ready(function(){
   $(".input_wrap").myDatalist({"bgcolor":"red","widths":1,"heights":1}); 
});
</script>
</body>
</html>

css

.wrap{ margin:0 auto; font-family: "微软雅黑";font-size: 14px;}
.center{ margin: 0 auto; width:500px;}
.input{ margin: 0; padding: 0; /*border:none;*/ width:140px; height: 24px; float:left;}
.select_list{display: none; position:absolute; z-index: 100;}
.select_list li{ height:24px; margin: 0; padding: 0; background-color: #fff; cursor: pointer; list-style: none; position:relative;}
.select_list li:hover{ background-color: red;}
.input_wrap{ position:relative; }

js

/*
    datalist 0.1 
    自定义datalist插件,实现html5中input元素datalist的效果
    兼容IE8+,Firefox,Chrome等常见浏览器
*/

;(function($,window,document,undefined){ //undefinde是真实的undefined,并非参数
    //将可选择的变量传递给方法

    //定义构造函数
    var Datalist=function(ele,opt){
        this.$element=ele;
        this.defaults={
            'bgcolor':'green',
            'widths':1,
            'heights':1
        },
        this.options=$.extend({}, this.defaults, opt);
    }
    //定义方法
    Datalist.prototype={
        showList:function(){
            var color=this.options.bgcolor;
            var width=this.options.widths;
            var height=this.options.heights; //属性值

            var obj=this.$element; //obj为最外层包裹的div之类的元素,应该拥有positive:relative属性,方便datalist定位。
            var input=$(obj).children().eq(0); //input元素
            var inputUl=$(obj).children().eq(1); //datalist元素
            //设置弹出datalist的大小和样式
            $(inputUl).css({
                "top":$(input).outerHeight()+"px",
                "width":$(input).outerWidth()*width+"px"
            });
            $(inputUl).children().css({
                "width":$(input).outerWidth()*width+"px",
                "height":$(input).outerHeight()*height+"px"
            });

            $(inputUl).children('li').mouseover(function() {
                $(this).css("background-color",color);
                $(this).siblings().css("background-color","#fff");
            });
            $(inputUl).children('li').mouseout(function() {
                $(this).css("background-color","#fff");
            });
            //再次focus变为空,也可以改为某个默认值
            //datalist的显示和隐藏
            $(input).focus(function() {
                if($(this).val()!=""){
                    $(this).val("");
                }
                $(inputUl).slideDown(500);

                var n=-1;  //记录位置,-1表示未选中。当n=-1时直接按enter浏览器默认为倒数第一个
                $(document).keydown(function(event) {
                    /* 点击键盘上下键,datalist变化 */
                    stopDefaultAndBubble(event);
                    if(event.keyCode==38){//向上按钮
                        if(n==0||n==-1){
                            n=4;
                        }else{
                            n--;
                        }
                        $(inputUl).children('li').eq(n).siblings().mouseout();
                        $(inputUl).children('li').eq(n).mouseover();
                    }else if(event.keyCode==40){//向上按钮
                        if(n==4){
                            n=0;
                        }else{
                            n++;
                        }
                        $(inputUl).children('li').eq(n).siblings().mouseout();
                        $(inputUl).children('li').eq(n).mouseover();
                    }else if(event.keyCode==13){//enter键
                        $(inputUl).children('li').eq(n).mouseout();
                        $(input).val( $(inputUl).children('li').eq(n).text() );
                        n=-1;
                    }
                });


                //去掉浏览器默认
                function stopDefaultAndBubble(e){
                    e=e||window.event;
                    //阻止默认行为
                    if (e.preventDefault) {
                        e.preventDefault();
                    }
                    e.returnValue=false;

                    //阻止冒泡
                    if (e.stopPropagation) {
                        e.stopPropagation();
                    }
                    e.cancelBubble=true;
                }

            });
            $(input).blur(function() {
                $(inputUl).slideUp(500);
            });
            $(inputUl).delegate('li', 'click', function() {
                    $(input).val( $(this).text() );
            });

            return this;
        }
    }
    //在插件中使用Datalist对象
    $.fn.myDatalist=function(options){
        //创建实体
        var datalist=new Datalist(this,options);
        //调用其方法
        return datalist.showList();
    }
 
})(jQuery,window,document);

 这里用ul li列表模拟datalist options。实现逻辑非常简单,稍微需要注意点的是div.input_wrap是用相对定位的,方便ul.input1_ul相对进行定位。由于需求有很多的输入框且相互之间不影响,因此这里是input1。好歹是我自己开发的第一个插件,mark一记。

      需要代码的可以戳https://github.com/codetker/myDatalist。

以上资料是 摘自 jQuery插件开发之datalist - codetker - 博客园

jQuery插件开发之datalist - codetker - 博客园HTML5中定义了一种input框很好看的下拉列表--datalist,然而目前它的支持性并不好(万恶的IE,好在你要渐渐退役了...)。于是最近更据需求写了一个小型datalist插件,兼容到IE8https://www.cnblogs.com/codetker/p/4643782.html

==================================

下面是fastadmin selectpage的效果

 是这种效果是input的升级优化而来,

默认值

selectpage不被选中?默认值
 
赋值后需要刷新selectPage

$('#mz-topic-id').val(data.id);
$('#mz-topic-id').selectPageRefresh();

HTML

<input id="c-name" class="form-control selectpage" name="TEST" type="text" value="">

js 第一步,引入 selectpage控件

define(['jquery', 'bootstrap', 'backend', 'table', 'form','selectpage'], function ($, undefined, Backend, Table, Form, selectpage) {

第二步

$('#c-name').selectPage({
                showField : 'product',
                keyField : 'id',
                data : [
                    {"id":3,"product":"华为P40 Pro"},
                    {"id":4,"product":"小米10 Pro"}
                ]
            });

这样就能显示了。当然官方提供更多属性和控制方法

动态下拉(SelectPage)

FastAdmin中的动态下拉列表使用的是优秀强大的Selectpage插件,FastAdmin对其进行了二次开发。

常规用法

下面介绍一个基础的动态下拉列表示例,如下

<input id="c-name" data-rule="required" data-source="category/selectpage" class="form-control selectpage" name="row[name]" type="text" value="">

其中需要给元素class添加一个selectpage,其次需要增加一个data-source="category/selectpage"这个属性,category/selectpage为我们控制器提交列表的方法

FastAdmin的Selectpage列表中显示字段默认读取的是name字段,如果我们返回的列表中不包含name字段,将无法展现下拉列表数据。此时我们需要添加使用data-field="你要显示的字段"即可,例如data-field="title"

FastAdmin的Selectpage列表中主键字段默认读取的是id字段,如果我们的主键不是id字段,则我们可以添加并使用data-primary-key="你的主键ID字段"来修改,例如data-primary-key="productid"

常用属性

属性                    功能          示例                                    
data-source          提供数据源的URL地址或JSON数据data-source="category/index"          
data-field            列表显示读取的字段  data-field="username"                
data-primary-key      列表选中后渲染的字段  data-primary-key="uid"                
data-pagination      是否开启分页      data-pagination="true"                
data-page-size        分页大小        data-page-size="10"                  
data-multiple        是否支持多选      data-multiple="true"                  
data-max-select-limit最多可选择数量    data-max-select-limit="3"            
data-order-by        排序字段        data-order-by="id"                    
data-params          自定义扩展参数    data-params='{"custom[type]":"test"}'
data-select-only      是否为只读模式    data-select-only="true"              
data-format-item      列表行模板    data-format-item="{title} - {author}"    
disabled      禁用SelectPage组件    disabled    

附加请求参数

如果需要简单的进行搜索筛选过滤,可以使用

//筛选status为normal,type为1的数据
data-params='{"custom[status]":"normal","custom[type]":"1"}'

data-params支持function类型,如果需要动态传参(例如联动查询),则可以在JS中将data-params添加一个function处理即可,请在表单初始化Form.api.bindevent之前使用,例如传递动态选择的类型

$("#c-name").data("params", function (obj) {
    return {custom: {type: $("#c-type").val()}};
});

自定义行模板

SelectPagedata-format-item1.2.0之前的版本只支持使用JS赋值function来实现格式化模板功能,如:

$("#c-category").data("format-item", function(row){
    return row.title + " - " + row.author;
});

从FastAdmin1.2.0版本开始,同时还支持占位符和模板,如:
占位符模式

<input type="text" ... data-format-item="{title} - {author}" />

模板模式

<input type="text" ... data-format-item="#titletpl" />

<script type="text/html" id="titletpl">
<%=title%> - <%=id%>
</script>

温馨提示:
默认由于data-field="name"只能指定一个显示的字段,如果需要调用显示多个字段值时,必须在控制器指定

protected $selectpageFields = "id,name,title,author";

数据源

data-source支持Object远程URL返回两种方式,如:

data-source='[{"id":"1","title":"标题1"},{"id":"2","title":"标题2"}]'

data-source="category/index"

当使用远程数据源的方式时需要远程返回JSON数据,如:

{
    "list":[{"id":4,"username":"FastAdmin","nickname":"快速后台","avatar":"","pid":0},{"id":6,"username":"CRUD","nickname":"一键CRUD","avatar":"","pid":0}],
    "total":30
}

其中list为数据列表,total为总记录数,总记录数将用于前端显示分页使用。

事件监听

如果你需要对SelectPage组件值变更以后的事件进行监听,可以直接监听文本框的change事件即可,如:

$(document).on("change", "#c-title", function(){
    //后续操作
});

也可使用

$("#c-title").data("eSelect", function(){
    //后续操作
});

来实现,注意以上代码需要放在元素初始化Form.api.bindevent之前。

常用方法

//刷新SelectPage
$('#category_id').selectPageRefresh();
//清除SelectPage数据
$('#category_id').selectPageClear();
//设置SelectPage数据
$('#category_id').selectPageData(数据源);
//禁用或启用SelectPage
$('#category_id').selectPageDisabled(状态);
//获取SelectPage的选中的文本
$('#category_id').selectPageText();

常用示例

//动态修改SelectPage选中项
$('#category_id').val(3);
$('#category_id').selectPageRefresh();

//设置SelectPage数据
var data = [
    {id:1 ,name:'分类一'},{id:2 ,name:'分类二'}
];
$('#category_id').selectPageData(data);

//禁用
$('#category_id').selectPageDisabled(true);
//启用
$('#category_id').selectPageDisabled(false);

常见问题

1、FastAdmin在生成CRUD时会对包含下划线的字段默认生成动态下拉列表,比如user_id将自动生成data-source="user/index",默认读取的是idname字段,如果需要修改,请修改对应参数data-primary-keydata-field来重新赋值。
2、如果你在开发时遇到SelectPage组件在编辑时总是返回第一行返回所有行的数据时,请参考以下文档进行检查你的代码:
为什么Selectpage下拉列表在编辑时总是返回第一行的值? - FastAdmin问答社区 
为什么Selectpage下拉列表在编辑时总是返回所有行的数据? - FastAdmin问答社区

更多的使用方法请参考Selectpage官方教程

文档最后更新时间:2022-03-04 17:24:03

=========================================

为什么Selectpage下拉列表在编辑时总是返回第一行的值?

有很多小伙伴都遇到过这个问题,那到底为什么会这样呢?是Selectpage的BUG,还是FastAdmin的BUG?其实都不是,这是因为你采用了自定义数据源导致未处理编辑时的数据导致的。
我们都知道在FastAdmin中可以给input添加selectpageclassdata-source属性值后就可以使用动态下拉列表,但往往我们会忽略对编辑时的特殊处理。
例如:
通常情况下我们的数据源data-source="category/selectpage",当我们点击selectpage文本框时,请求的参数为:

q_word[]: 名称
pageNumber: 1
pageSize: 10
andOr: AND
orderBy[0][]: name
orderBy[0][]: ASC
searchTable: tbl
showField: name
keyField: id
searchField[]: name
name: 名称

服务器返回的数据数据如下:

{
    "total": 2,
    "list": [
        {
            "id": "1",
            "name": "名称1"
        },
        {
            "id": "2",
            "name": "名称2"
        }
    ]
}

我们的list数据是一个二维数组,返回以上数据在添加时使用时没有任何问题的。但是我们在进入编辑页面时,Selectpage会首先向category/selectpage这个链接请求一次当前编辑项所对应的数据。
我们通过Chrome的开发者控制台中的Network中可以看到请求的参数是

searchTable: tbl
searchKey: id
searchValue: 2
orderBy[0][]: name
orderBy[0][]: ASC
showField: name
keyField: id
keyValue: 2
searchField[]: name

比我们正常请求多了个keyValue,我们可以在我们的数据源data-source="category/selectpage"中判断下如果存在keyValue值时只返回与keyValue值有关联的数据,例如我们在category/selectpage中加个判断如下:

if($this->request->request("keyValue")){
  return ['total'=>1, 'list'=>[
        ['id'=>2, 'name'=>'名称2']
    ]
  ];
}

通过以上判断后我们在编辑时就不会始终显示的是列表中的第一项数据了。
同理如果我们启用了data-multiple="true"时,此时我们判断keyValue时应该只返回与之关联的多个数据。

参考资料

动态下拉(SelectPage) - FastAdmin框架文档 - FastAdmin开发文档https://doc.fastadmin.net/doc/178.html

selectPage - FastAdmin问答社区https://ask.fastadmin.net/search.html?order=&type=docs&q=selectPage

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值