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

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);
})
}
}); }

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)
}
}
})
}

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

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)
}
} }) }
**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); }
}) })
}

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); }
}) })
}

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)
}
})
})
}

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

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);}
}
})
})
}

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 {
}
}
})
}

这里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)
注意--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)
}
});
})}

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

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

后端代码:

    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('...')

因为前段用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); })
}

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>

Django之CURD插件2的更多相关文章

  1. Django之CURD插件

    什么是CURD? CURD顾名思义就是create,update,rearch,delete(所谓的增删改查). 当我们接到一个项目的时候,夸夸夸的就写完表结构,然后就一直写增删改查,增删改查,写了一 ...

  2. CURD插件(仿Django-admin版)

    前言 如何提升自己的开发效率? 每个新项目都是自己经做过的项目(经验所致),在项目开发过程中不断总结.封装属于自己的组件, 例如:每个web项目大部分都涉及增删改查,分页显示,搜素,CRM就是这样的组 ...

  3. django form 组件插件

    创建类: class RegForms(forms.Form): account = fields.CharField( required = True, #必填字段 max_length=12, m ...

  4. django admin后台插件:django-suit入门

    去年9月底开始用django来做公司内部项目,开始对django有了一些了解,感觉django真的蛮强大的(也有很多人推荐flask,将来有空的话我会试试).今天的话只是介绍一个小东西,django管 ...

  5. Django使用DataTables插件总结

    Django使用Datatables插件总结 文章中的例子已上传至github 基本使用 Datatables插件是一款方便简单的展示数据的列表插件.关于基本使用,官方网站上的已介绍的很详细,这里我再 ...

  6. CMDB (后台管理) CURD 插件

    查 a. 基本实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. Django admin美化插件suit应用[原创]

    前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...

  8. Django之前端插件定制之表头

    什么是插件? 插件只是辅助,是开发过程中的一个阶段.一般项目一期会用各种插件,迅速将功能.界面搭出来,二期时就改成自己的代码了.大点的公司都有自己的js库,自己开发类似jquery的库. 那接下来就写 ...

  9. 一个有趣的基于Django的调试插件--django-debug-toolbar

    django-debug-toolbar 介绍 django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息. git ...

随机推荐

  1. java 实体序列化的意义

    一.序列化的意义 客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间.如果在某一时间段内访 ...

  2. C#基于Socket的CS模式的完整例子

    基于Socket服务器端实现本例主要是建立多客户端与服务器之间的数据传输,首先设计服务器.打开VS2008,在D:\C#\ch17目录下建立名为SocketServer的Windows应用程序.打开工 ...

  3. java学习笔记——可用链表

    NO 链表方法名称 描述 1 public void add(数据类型 对象) 向链表中增加数据 2 public int size() 查看链表中数据个数 3 public boolean isEm ...

  4. Solidworks 如何快速完全定义草图

    工具-尺寸标注-完全定义草图

  5. Centos6.6 以rpm方式安装mysql5.6

    一.查看系统中有没有mysql的源 yum repolist all | grep mysql 二.配置源 1.配置源参考mysql官方给出的源配置,https://dev.mysql.com/doc ...

  6. Python命令行选项參数解析策略

    概述 在Python的项目开发过程中,我们有时须要为程序提供一些能够通过命令行进行调用的接口.只是,并非直接使用 command + 当前文件 就ok的,我们须要对其设置可选的各种各样的操作类型.所以 ...

  7. 键盘上所有键位的ascii值

    上次用的时候一直找,这次找到了,收藏起来. 0x1 鼠标左键 0x2 鼠标右键 0x3 CANCEL 键 0x4 鼠标中键 0x8 BACKSPACE 键 0x9 TAB 键 0xC CLEAR 键 ...

  8. C# : 资源文件(多用于处理国际化)

    1.建立Resource文件夹,添加资源文件 处理国际化的问题,我们可以添加多个资源文件,如下就是添加一个中文的,一个英文的. 2.向其中添加键值对. 3.取值 CultureInfo uiCultu ...

  9. PHP和Java的主要区别有哪些?哪个最适合Web开发语言?

    一.前言 PHP和Java都是现在比较流行的二种编程语言. 对于许多新手来说,都会思考如果学的时候,该学哪种语言呢?下面这篇文章给大家整理两者的区别以及一些选择建议,一起来看看吧. 二.简介 PHP与 ...

  10. svn client命令

    经常使用svn命令说明 1.从SVN仓库中检索出代码到工作拷贝: # svn checkout https://svn.sinaapp.com/appname [workcopy] 当中workcop ...