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
原文地址:https://www.cnblogs.com/chenxuming/p/9265159.html