• Django之CURD插件2


    目标:达到下图拥有功能的实现

    1.绑定编辑按钮

    ************思路****************

    1.为编辑按钮添加样式,可以根据样式来进行判断在什么状态.

    2.进入编辑模式,将可编辑的字段修改为input框,或者select框.退出时变为文本框.

      我们这里只对配置文件中.拥有editEnable='true'的属性的标签进行编辑(因为进出编辑模式经常使用,所以写成两个函数)

    3.做到双向选择,可以先进入编辑状态再选择checkbox也可反之.

      a.如果先选择checkbox 则在编辑按钮里可以进入编辑模式

      b.如果先选择编辑按钮,再选择checkbox,那么就给checkebox绑定事件.(进出编辑模式)

    下面是绑定编辑按钮的js代码

    function bindMenus() {
    //         {#    绑定编辑按钮,           #}
    // {#      进入编辑模式,修改文本内容为input框或者下拉框#}
    // {#      退出编辑模式,将修改的input框和下拉框的值修改到文本到没更新数据库#}
            $('#EditMode').click(function () {
               var editing = $('#EditMode').hasClass('btn-warning');
               if (editing){
                   //退出编辑模式
                   $('#table_tb').find(':checked').each(function () {
                       var $CurrentTr = $(this).parent().parent();
                        trOutEditMode($CurrentTr);
                   });
                   $('#EditMode').removeClass('btn-warning');
                   $('#EditMode').text('进入编辑模式')
               }
               else {
                   $('#EditMode').addClass('btn-warning');
                   $('#EditMode').text('退出编辑模式');
                   //进入编辑模式
                   $('#table_tb').find(':checked').each(function () {
                       var $CurrentTr = $(this).parent().parent();
                       trInEditMode($CurrentTr);
                   })
               }
            });
    
        }
    View Code

    2.进出编辑模式修改文本框模式

    *******进入编辑模式思路********
    1.遍历被选中checkbox框找到每一个checkbox的tr标签传进函数

    2.遍历tr标签里的td便签,判断是否可编辑,是什么编辑框.

    3.根据不同的编辑框进行操作

      a.创建select框,则去全局变量里找到相应的数据,提取choice的id和文本内容放进option标签里

      b.创建input框,将该文本的内容放进input框里

    下面是实例代码

    $tr.addClass('success');这里的success是bootstrap样式,进入编辑后修改样式
     function trInEditMode($tr) {
            $tr.addClass('success');
            $tr.attr('has-eidt','true');
            $tr.children().each(function () {
                var editEnable = $(this).attr('edit-enalbe');
                var editType = $(this).attr('edit-type');
                if (editEnable == 'true'){
                    // 可以进入编辑模式
                    //<select>
                    //  <options value='1'></options>
                    //  <options value='2'></options>
                    // </select>
                    if (editType=='select'){
                       var  $sel = $('<select class="form-control"></select>');
                       var GlobalName = $(this).attr('global-name');
                       var origin =$(this).attr('origin');
                       $.each(window[GlobalName],function (k1,v1) {
                           var $op = $('<option></option>');
                           $op.attr('value',v1[0]);
                           $op.html(v1[1]);
                           $sel.append($op);
                           $sel.val(origin);
                       });
                    $(this).html($sel)}
    
                    else if(editType=='input'){
                        var content = $(this).text();
                        var current_input = $('<input class="form-control">');
                        current_input.val(content);
                        $(this).html(current_input)
                    }
                }
            })
        }
    View Code

    ******退出编辑模式思路*****

    1.遍历被选中checkbox框找到每一个checkbox的tr标签传进函数

    2.遍历tr标签里的td便签,判断是否可编辑,是什么编辑框.

    3.根据不同的编辑框进行操作

      a.如果是select框,则去全局变量里找到选中的option对应的value值和文本并且增加new-val属性(为后面的保存数据做铺垫)

      b.如果是input框,则把input里的val值放在html里即可.同时也增加new-val属性

    function trOutEditMode($tr) {
            $tr.removeClass('success');
            $tr.children().each(function () {
                var editEnable = $(this).attr('edit-enalbe');
                var editType = $(this).attr('edit-type');
                if (editEnable == 'true'){
                    //可以退出编辑模式
                    if (editType =='select'){
                        var $select= $(this).children().first();
                        var NewId = $select.val();
                        var NewText = $select[0].selectedOptions[0].innerHTML;
                        $(this).html(NewText);
                        $(this).attr('new-val',NewId)
                    }else if(editType == 'input'){
                        var $input = $(this).children().first();
                        var inputval = $input.val();
                        $(this).html(inputval);
                        $(this).attr('new-val',inputval)
                    }
                }
    
            })
    
        }
    View Code
    **var NewId = $select.val(); option里面的value值可以通过select.val()取到
    **var NewText = $select[0].selectedOptions[0].innerHTML;
    ------$select[0]将jQuery对象变位document对象
    ------selectedOptions该代码是select选中的option 内部是一个列表

    3.绑定checkbox

    ****思路****

    1.找到所有的checkbox遍历.

    2.每次都进行判断是否进入编辑状态:

      a.如果是,则执行trInEditMode($current_tr)该tr进入编辑状态

      b.如果否,则选中即可

    通过这里就实现了标题1的双向选择

    function bindCheckAll() {
            $('#CheckAll').click(function () {
                $('#table_tb').find(':checkbox').each(function () {
                    //判断是否进入编辑模式
                    if ($('#EditMode').hasClass('btn-warning')) {
                        var if_checked = $(this).prop('checked');
                        if (if_checked) {
                            //进入模式点击全选 被选中不操作
                        }
                        else {
                            $(this).prop('checked', true);
                            var $current_tr = $(this).parent().parent();
                            trInEditMode($current_tr);
                        }
                    }
                    else {
                        $(this).prop('checked', true);
    
                    }
                })
    
            })
        }
    View Code

    4.绑定全选

    ****思路*****

    1.判断是否进入了编辑模式

      a.如果是,让每一个tr都进入编辑模式

      b.如果否,则全部选中即可

    $('#CheckAll').click(function () {
                $('#table_tb').find(':checkbox').each(function () {
                    //判断是否进入编辑模式
                    if ($('#EditMode').hasClass('btn-warning')) {
                        var if_checked = $(this).prop('checked');
                        if (if_checked) {
                            //进入模式点击全选 被选中不操作
                        }
                        else {
                            $(this).prop('checked', true);
                            var $current_tr = $(this).parent().parent();
                            trInEditMode($current_tr);
                        }
                    }
                    else {
                        $(this).prop('checked', true);
    
                    }
                })
    
            })
        }
    View Code

    var if_checked = $(this).prop('checked');
    if (if_checked) 判断是否选中

    5.绑定取消

    ***思路***

    1.判断是否已经进入了编辑模式

    2.遍历已经被选中的checkbox

      a.如果进入编辑模式,则退出

      b.如果没有,则取消选中

    function bindCheckCancleAll() {
            $('#CheckCancleAll').click(function () {
                $('#table_tb').find(':checked').each(function () {
                    if ($('#EditMode').hasClass('btn-warning')){
                        var $current_tr = $(this).parent().parent();
                        trOutEditMode($current_tr);
                        $(this).prop('checked',false)
                    }
                    else {
                        $(this).prop('checked',false)
                    }
                })
            })
        }
    View Code

    反选的思路都一样,这里直接贴代码

    function bindOppositeCheck() {
            $('#OppositeCheck').click(function () {
                $('#table_tb').find(':checkbox').each(function () {
                    if($('#EditMode').hasClass('btn-warning')){
                        //进入编辑模式
                        var $current_tr=$(this).parent().parent();
                        if ($(this).prop('checked')){
                            $(this).prop('checked',false);
                            trOutEditMode($current_tr)
                        }else {
                            $(this).prop('checked',true);
                            trInEditMode($current_tr)
                        }
                    }else {
                        if($(this).prop('checked')){
                            $(this).prop('checked',false);
                        }else {$(this).prop('checked',true);}
                    }
                })
            })
        }
    View Code

    6.批量删除

    ***思路***

    1.这里的删除也是双向的,在进入或者退出编辑模式都可以进行删除,

      原理:在进行编辑模式的时候退出编辑模式,获取数据通过ajax提交给后台

    2.拿到放置该checkbox的tr标签里的id值(在创建tr标签的时候生成),放在列表里传给后台

    function DeleteconfirmAll() {
                if($('#EditMode').hasClass('btn-warning')){
                   $('#EditMode').removeClass('btn-warning');
                   $('#EditMode').text('进入编辑模式');
                    $('#table_tb').find(':checked').each(function () {
                        var $CurrentTr = $(this).parent().parent();
                        trOutEditMode($CurrentTr);
                    })
                }
                var del_list =[];
                $("#table_tb").find(':checked').each(function () {
                    //$(this)--->input
                    var $tr = $(this).parent().parent();
                    var RodId= parseInt($tr.attr('row-id'));
                    del_list.push(RodId);
                });
            $.ajax({
                url:requestUrl,
                type:'DELETE',
                data:{del_list:del_list},
                traditional: true,
                dataType:'JSON',
                success:function (arg) {
                    if(arg.status){
                        $("#delModal").modal("hide");
                        bindShowStatus();
                        $.each(arg.msg,function (k,v) {
                            $('tr[row-id="'+v+'"]').remove()
                        })
                    }
                    else {
                    }
                }
            })
        }
    View Code

    这里Ajax用的是type是delete,因为写django的时候用了cbv的模式.

    *******用Ajax传列表的时候需要traditional: true代表只进行浅序列化.

    ******     $('tr[row-id=" '+v+' "]').remove()  前端删除数据.....这里用到了字符串的拼接

    后端拿数据的代码:

    response={'status':False,'error':None,'msg':None}
            req_del = QueryDict(request.body,encoding='utf-8')
            del_list = req_del.getlist('del_list')
            print(del_list)
            try:
                if del_list:
                    models.UserInfo.objects.filter(id__in=del_list).delete()
                    response['status']=True
                    response['msg']=del_list
            except Exception as e:
                response['error']=str(e)
            return  JsonResponse(response)
    View Code
    注意--del_list = req_del.getlist('del_list') 用getlist拿列表数据

     7.保存数据

    **思路**

    1.同上,双向提交数据.

    2.在每次进入编辑模式的时候都添加has-eidt="true",那么在遍历提交数据的时候可以用该属性进行筛选

    3.将可以编辑的td获取,标签中新的数据new-val,还有原来的数据origin(原来的数据在配置文件中设置)

      如果新的数据和老的数据相同则不需要写入字典.

      再用列表将push字典传装着多个字典的列表给后端

        function bindSaveAll() {
            $('#SaveAll').click(function () {
                if($('#EditMode').hasClass('btn-warning')){
                   $('#EditMode').removeClass('btn-warning');
                   $('#EditMode').text('进入编辑模式');
                    $('#table_tb').find(':checked').each(function () {
                        var $CurrentTr = $(this).parent().parent();
                        trOutEditMode($CurrentTr);
                    })
                }
                var Data_list = [];
            $("#table_tb").find('[has-eidt="true"]').each(function () {
                //$(this) -->tr
                var RowId = $(this).attr('row-id');
                var Data_dict = {};
                Data_dict['id']=parseInt(RowId);
                $(this).children('[edit-enalbe="true"]').each(function () {
                    //$(this)-->td
                    var Name = $(this).attr('name');
                    var Origin = $(this).attr('origin');
                    var NewVal = $(this).attr('new-val');
                    if(Origin!=NewVal && NewVal!= undefined){
                        Data_dict[Name]=NewVal
                    }
                });
                Data_list.push(Data_dict);
            });
            $.ajax({
                url:requestUrl,
                type:'PUT',
                data:{'Data_list':JSON.stringify(Data_list)},
                success:function (arg) {
                    bindShowStatus();
                    console.log(arg)
                }
            });
            })}
    View Code

    成功提交数据以后,回调函数自动调用了bindShowStatus()函数,这里面主要是增加保存成功的按钮,5秒后自动关闭

    function bindShowStatus() {
            var $ShowStatus = $('#SaveSuccess');
            $ShowStatus.empty().addClass('btn btn-success').html('操作成功');
            setTimeout(function () {
                $ShowStatus.empty().removeClass('btn btn-success')
            },5000)
        }
    View Code

    后端代码:

        def put(self,request,*args,**kwargs):
            data_list =QueryDict(request.body,encoding='utf-8')
            print(data_list)
            data_list = json.loads(data_list.get('Data_list'))
            for row in data_list:
                 nid = row.pop('id')
                 if not row:
                     continue
                 models.UserInfo.objects.filter(id=nid).update(**row)
            return  HttpResponse('...')
    View Code

    因为前段用ajax的时候 data:{'Data_list':JSON.stringify(Data_list)},进行了序列化

    后端获取的时候:

    data_list =QueryDict(request.body,encoding='utf-8')
    data_list = json.loads(data_list.get('Data_list'))

    需要注意的是:用put delete方法提交和get post提交获取的数据方式不一样

    8.分页功能

    **思路**

    1.每次初始化数据的时候init,向后台获取数据时将该页的页码传给后端....第一次传为null

    2.根据前端传的页码数值,用分页插件生成li标签放在配置文件中.

    3.前端根据配置文件生成数据,用事件委托绑定页码标签,当页码被点击时将该执行函数获取该页码值,后执行init(page)方法重新获取数值.

    注意

    1.通过ajax在重新初始化内容的时候需要把内容empty()

    2.用事件委托的时候考虑是否会事件累积.(如果是重复绑定标签,需要在委托之前off('click')清空上一次的事件)

    function initPager(pager_list) {
            var $page_ul = $('#page_ul');
            $page_ul.empty();
            $page_ul.append(pager_list);
            $page_ul.off('click');
            $page_ul.on('click','a',function () {
                //$(this) --><a>
                var page = $(this).attr('page');
                init(page);
    
            })
        }
    View Code

    9.组件

    将已经写好的JS代码生成组件

    用自执行函数来存放js代码

    1.自执行函数里的代码不可被外面的代码调用,保证了组件无污染.

    2.通过extend进行扩展,和外面的代码交互

    ///  js组件
    (function(){
    //自执行函数
    var requestUrl =null;局部变量,作用域是自执行函数
    .........
    })
     //加载完成执行该方法:
    
        jQuery.extend({
            'CURD':function (url) {
                requestUrl =url;
    //url会赋值给上面的requestUrl从而进行获取数据
        
                init();
                bindMenusFunc();
    //bindMenusFunc封装了对click事件的加载.
        
            }
        })
    
    ()    
    
    
    
    非组件
    <script>
        $(function () {
           $.CURD('/get_msg/'); 
    //可以调用CURD将url传进来....
        });
    </script>    
    View Code
  • 相关阅读:
    基础DP背包
    哲学思絮01
    Vue使用ElementUI
    Vue-Mock数据
    Vue生命周期
    Vue实战之CURD
    读《间客》有感
    ASP.Net Core网站发布
    Cycling之 标签化
    Vue环境搭建
  • 原文地址:https://www.cnblogs.com/chenxuming/p/9265159.html
Copyright © 2020-2023  润新知