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);
})
}
}); }
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)
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的更多相关文章
- Django之CURD插件
什么是CURD? CURD顾名思义就是create,update,rearch,delete(所谓的增删改查). 当我们接到一个项目的时候,夸夸夸的就写完表结构,然后就一直写增删改查,增删改查,写了一 ...
- CURD插件(仿Django-admin版)
前言 如何提升自己的开发效率? 每个新项目都是自己经做过的项目(经验所致),在项目开发过程中不断总结.封装属于自己的组件, 例如:每个web项目大部分都涉及增删改查,分页显示,搜素,CRM就是这样的组 ...
- django form 组件插件
创建类: class RegForms(forms.Form): account = fields.CharField( required = True, #必填字段 max_length=12, m ...
- django admin后台插件:django-suit入门
去年9月底开始用django来做公司内部项目,开始对django有了一些了解,感觉django真的蛮强大的(也有很多人推荐flask,将来有空的话我会试试).今天的话只是介绍一个小东西,django管 ...
- Django使用DataTables插件总结
Django使用Datatables插件总结 文章中的例子已上传至github 基本使用 Datatables插件是一款方便简单的展示数据的列表插件.关于基本使用,官方网站上的已介绍的很详细,这里我再 ...
- CMDB (后台管理) CURD 插件
查 a. 基本实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Django admin美化插件suit应用[原创]
前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...
- Django之前端插件定制之表头
什么是插件? 插件只是辅助,是开发过程中的一个阶段.一般项目一期会用各种插件,迅速将功能.界面搭出来,二期时就改成自己的代码了.大点的公司都有自己的js库,自己开发类似jquery的库. 那接下来就写 ...
- 一个有趣的基于Django的调试插件--django-debug-toolbar
django-debug-toolbar 介绍 django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息. git ...
随机推荐
- hdu4671 思维构造
pid=4671">http://acm.hdu.edu.cn/showproblem.php? pid=4671 Problem Description Makomuno has N ...
- Java千百问_03基本的语法(005)_二进制是如何做位运算的
点击进入_很多其它_Java千百问 二进制是如何做位运算的 程序中的全部数在计算机内存中都是以二进制的形式储存的.位运算说白了,就是直接对整数在内存中的二进制位进行操作. 其它运算符看这里:java种 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程4.1 TwinCAT如何读写TXT文件
TwinCAT提供了FB_FileRead等一系列读写文件的方法,本小程序演示的是多个贝福自带的FBD功能块连起来用的方法,跟前面讲的一样,建议在初始化的时候把所有FBD都复位,准备使用 真正的读 ...
- mac查看端口占用
Mac OS/Linux命令查询网络端口占用情况 netstat命令 netstat -an | grep 3306 3306替换成需要grep的端口号 lsof命令 通过list open fi ...
- 《Android源代码设计模式解析与实战》读书笔记
1.定义 将对象组合成树形结构以表示"部分-总体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.使用场景 (1)表示对象的部分-总体层次结构时. (2)从一个总体 ...
- Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana (分块)
题目地址:http://codeforces.com/contest/551/problem/E 将n平均分成sqrt(n)块,对每一块从小到大排序,并设置一个总体偏移量. 改动操作:l~r区间内,对 ...
- 基于bootstrsp的jquery富文本编辑器的手冊说明
重点:当在页面插入文本编辑器后.无法用js/jq的方式去将某些值写入到文本编辑器.如:$("textarea").val("111");$("text ...
- SSH项目web.xml文件的常用配置【struts2的过滤器、spring监听器、解决Hibernate延迟加载问题的过滤器、解决中文乱码的过滤器】
配置web.xml(struts2的过滤器.spring监听器.解决Hibernate延迟加载问题的过滤器.解决中文乱码的过滤器) <!-- 解决中文乱码问题 --> <filter ...
- automaticallyAdjustsScrollViewInsets(UITextView文字顶部留有空白)
iOS7新添加的UIViewController的属性automaticallyAdjustsScrollViewInsets 此属性默认为YES,这样UIViewController下如果只有一个U ...
- php匿名函数和闭包函数及use关键字传参及Closure匿名函数类
php闭包函数用use传参有什么意义?答:use引用外层变量,比如全局变量 Closure,匿名函数,是php5.3的时候引入的,又称为Anonymous functions.字面意思也就是没有定义名 ...