在select2中使用ajax获取数据


10102.png

在select2中使用ajax获取数据

demo测试

访问https://www.kningyuan.top/mydemo/,可以测试ajax拉取到的数据

官网

访问官网获取更多的用法

返回的数据

select2需要返回的数据是json格式,并且形式如下

{
"code": 200, 
"message": 36, 
"data": {
  "A1F": "A座1F", 
  "A2F": "A座2F", 
  "A3F": "A座3F", 
  "A4F": "A座4F", 
  "A5F": "A座5F", 
  "A6F": "A座6F", 
  "B1F": "B座1F", 
  "B2F": "B座2F", 
  "B3F": "B座3F", 
  "B4F": "B座4F", 
  "B5F": "B座5F",
   }
}

html页面设置

首先需要加载select2css,js,在加载select2.min.js之前,必须加载jquery.可以使用bootcdn中选择加载.

页面上非常简单只需要加入select2选择框

<select class="form-select form-select-sm" id="flour"></select>  

jQuery设置

<script>
    $(document).ready(function () {
        // select2
        const flour = $('#flour');
        flour.select2({
            placeholder: "位置",  //占位符
            // dropdownParent: ARM,  //modal 模态框选择器
            // width: "231.32px",  //宽度
            allowClear: true,  // 允许删除
            delay: 250,  // AJAX间隔时间
            //minimumInputLength: 1,
            ajax: {
                url: 'http://127.0.0.1:5000/api/v1/flour',
                type: 'get',
                dataType: "json",
                data: function (params) {
                    // /api/v1/flour?search={params.term}&page=1&pageSize=6
                    const query= {
                        search : params.term,
                        page: params.page || 1,
                        pageSize: 6
                        };
                        return query
                },
                processResults: function (data, params) {
                    // 默认返回data.items, 这里通过构造形成需要的 列表数据
                    // data 即为返回数据
                    if(data.code == 200){
                        //指定此值来判断是否需要分页
                        params.page = params.page || 1;
                        const rst = [];
                        // data是对象,此为取出value,正好可以用来循环判断多少
                        const value = Object.values(data.data);                       
                        for (var i=0; i < value.length; i++){
                            rst.push({
                            'id': i+1,
                            'text': value[i]
                            })
                        }
                        // 格式化成select2需要的格式
            //a = { "results": [{"id": 1,"text": "Option 1"},],"pagination": { "more": False}
                        return {
                            results : rst,
                            pagination : {
                                more : params.page * 6 < data.message
                            }
                        }
                        }
                }
                //cache: true     AJAX cache 只存在于get请求中,true请求缓存数据,false,拉取服务器最新数据
            }

        })

    })
</script>

按照select2要求的请求和分页的格式拆分数据.

dropdownParent:此选项非常重要,用于bootstrapmodal中,select2默认在modal中有问题,必须设置此选项指向modalid选择器.

后端实现分页查询

这里使用的是Python sqlAlchemy

orm映射

class Flour(BaseModel, db.Model):

    __tablename__ = "ums_flour"

    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(64))
    description = db.Column(db.String(128))
   
    def  __init__(self, name, description=None):
        self.name = name
        self.description = description

    @classmethod
    def getZone(cls):
        zone = {}
        for k in cls.query.all():
            zone.update({ k.name : k.description})
        return zone

Api返回

class FlourView(Resource):
    def get(self):
        # /api/flour?page=1&pageSize=5 HTTP/1.1" 200
        rst_search = request.args.get('search')
        rst_page = request.args.get('page')

        paginate_result = {}
        # 全部数据
        result = Flour.getZone()

        # 需求是当 rst_search 为None时,返回全部的数据,当不为None时查找数据

        if rst_search != None:
            # 返回分页数据,per_page 和前端对应
            paginate_flour = Flour.query.filter(Flour.description.ilike("%" + rst_search + "%")).paginate(page=int(rst_page), per_page=6)
            total = paginate_flour.total
            for i in paginate_flour.items:
                paginate_result.update({i.name: i.description})
            return  jsonify({
                "code": 200,
                "message" : total,
                "data": paginate_result
            })
        return jsonify({
            "code": 200,
            "message" : len(result),
            "data": result           
        })

sqlalchemy.paginate()方法.返回一个分页对象.

分页查询,这涉及到flask-sqlalchemy的分页查询函数

db.session.query(User).filter_by().paginate(page=None, per_page=None,
   error_out=True, max_per_page=None)
  • page 查询的页数

  • per_page 每页的条数

  • max_per_page 每页最大条数,有值时,per_page 受它影响

  • error_out当值为 True 时,下列情况会报错
    - 当 page 为 1 时,找不到任何数据
    - page 小于 1,或者 per_page 为负数
    - page 或 per_page 不是整数

该方法返回一个分页对象 Pagination:调用 paginate() 方法,会返回一个 Pagination 对象,它封装了当前页的各种数据和方法

  • has_next 如果下一页存在,返回 True
  • has_prev 如果上一页存在,返回 True
  • items 当前页的数据列表
  • next_num 下一页的页码
  • page 当前页码
  • pages 总页数
  • per_page 每页的条数
  • prev_num 上一页的页码
  • query 用于创建此分页对象的无限查询对象。
  • total 总条数
  • iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2)迭代分页中的页码,四个参数,分别控制了省略号左右两侧各显示多少页码
  • next(error_out=False) 返回下一页的分页对象
  • prev(error_out=False) 返回上一页的分页对象

select2获取数据

//可通过$("#normalSetting").val() 拿到选中的option的value.
$('#zone').val()
//通过$("#normalSetting").find("option:selected").text()拿到选中的option的text文本.
$('#zone').find("option:selected").text()

select2设置默认选项

select2数据是从后台请求过来的时候,比如用户点击编辑资料, 弹出的界面城市默认选中用户未修改之前的城市.

但是当页面刚刚加载时, 由于是ajax从后台请求option数据, select没有被点击, 不触发ajax请求,select2下方还没有option数据, 但此时就要设置上默认选中项了.

以上需要select默认传入一个option,可以使用append()方法.内容可以来源于其他数据处, 比如使用bootstrap-table,默认值可以直接来自于table的选中值.

访问https://www.kningyuan.top/mydemo/

设置一个方法用来接受一个默认值,这个方法会为select2构造一个option,包含基本的id,text

var defaultOption = function (source) {
    var data = {
        id: 10001,
        text: source
    };
    var newOption = new Option(data.text, data.id, true, true);
    return newOption
};

当需要设置默认值时,使用append方法把默认值传递过去.

<section id=myFlour></section>
/*
* 定义默认值
*/
var defaultOption = function (source) {
    var data = {
        id: 10001,
        text: source
    };
    var newOption = new Option(data.text, data.id, true, true);
    return newOption
};
var data = [
    {
        id: 1,
        text: 'A1F1'
    },
    {
        id: 2,
        text: 'A1F2'
    },
    {
        id: 3,
        text: 'A1F3'
    }
];
$('#myFlour').select2({
    placeholder: "位置",
    allowClear: true,  
    data: data,

})
$('#myFlour').append(defaultOption('E1F5')).trigger('change');

文章作者: 文彦
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 文彦 !
评论
  目录