基于js的CURD插件
前言:
每个web程序对数据库的创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)操作都是必不可少的,于是我决定开发一个基于JavaScript和jQuery框架的插件,通过后端灵活配置,联动前端页面内容;即实现了前后端分离,也可以在后期项目中随时随地得快速应用;
day94
1、定制显示标签的属性属性
后端:
table_config=[
{
'q': None,
'title': '选择',
'display': True,
'text': {'tpl': '<input type="checkbox" value="{nid}" />', 'kwargs': {'nid': '@id'}},
'attr':{'class':'c1','nid':'@id'},
},
{
'q': 'id',
'title': 'ID',
'display':False,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@id'}},
'attr': {},
}, {'q':'hostname', #去数据库获取的字段
'title':'主机名',#table 种 th的标题内容
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1':'@hostname','a2':''}},#table中td 的内容
'attr': {'class': 'c1'},
}, {'q':'sn',
'title': '序列号',
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@sn'}},
'attr': {'class': 'c1'},
},
{'q':'os_platform',
'title': '系统',
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@os_platform'}},
'attr': {'class': 'c1'},
},
{'q': 'os_version',
'title': '系统版本',
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@os_version'}},
'attr': {'class': 'c1'},
},
{'q': 'business_unit__name',
'title': '业务线',
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@business_unit__name'}},
'attr': {'class': 'c1'},
},
{
'q': None,
'title': '操作',
'display': True,
'text': {'tpl': '<a href="/edit/{nid}/">编辑</a> | <a href="/del/{uid}/">删除</a> ',
'kwargs': {'nid': '@id', 'uid': '@id'}},
},
{'q': 'server_status_id',
'title': '服务器状态',
'display': True,
'text': {'tpl': '{a1}', 'kwargs': {'a1': '@@status_choices'}},
'attr': {'class': 'c1'},
#2个@的开头规则去global_choices_dict,获取status_choices对应的选择信息
},
]
前端
$.each(v.attr, function (attrname, attrvalue) {
if (attrvalue[0] == '@') {
attrvalue = row_dict[attrvalue.substring(1, attrvalue.length)]
}
td.setAttribute(attrname, attrvalue) //setAttribute设置td的属性
知识点:
0、str[0]
这种取值方式兼容性更好
1、attrvalue.substring(1, attrvalue.length)
js字符串按索引截取内容 str.substring(开始索引,结束索引)
2、td.setAttribute(属性名, 属性值) js对象
通过js给html设置标签属性
2、分页
后端:(扩展分页插件,支持点击页码,执行js函数事件)
def page_html_test(self):
page_list = [] if self.current_page == 1:
prev = ' <li><a href="#">上一页</a></li>'
else:
prev = ' <li><a num="%s">上一页</a></li>' %(self.current_page-1,)
page_list.append(prev) half_show_pager_count = int(self.show_pager_count / 2) # 数据特别少,15条数据=2页
if self.max_pager_num < self.show_pager_count:
# 页码小于11
pager_start = 1
pager_end = self.max_pager_num + 1
else:
if self.current_page <= half_show_pager_count:
pager_start = 1
pager_end = self.show_pager_count + 1
else:
if self.current_page + half_show_pager_count > self.max_pager_num:
pager_start = self.max_pager_num - self.show_pager_count + 1
pager_end = self.max_pager_num + 1
else:
pager_start = self.current_page - half_show_pager_count
pager_end = self.current_page + half_show_pager_count + 1 for i in range(pager_start, pager_end):
if i == self.current_page:
tpl = ' <li class="active"><a num="%s" >%s</a></li>' % (i,i,)
else:
tpl = ' <li><a num="%s" >%s</a></li>' % (i, i,)
page_list.append(tpl) if self.current_page == self.max_pager_num:
nex = ' <li><a href="#">下一页</a></li>'
else:
nex = ' <li><a num="%s">下一页</a></li>' %(self.current_page+1,)
page_list.append(nex) return ''.join(page_list)
前端:
/* 处理表分页 */
function initPageHtml(page_html) {
$('#pagination').empty().append(page_html);
} //扩展jquery的方法
jq.extend({
'nBlist': function (url) {
requesturl = url;
inint(1);
},
"changePage": function (pageNum) {
init(pageNum);
} })
知识点:
基于分页插件在后端返回页码给前端;
模板语言:通过a标签点点点想后端获取想要访问的数据库行数
js: 点击 通过jQuery的扩展方法,$.扩展方法 执行js函数,把访问的页码通过参数传入js函数,js函数发送ajax给后端获取数据数据;
3、组合搜素
组合搜素html讲解:
lable标签:显示+号右侧的内容
button 标签:用于生产下拉按钮,显示ul中li的内容
最右侧input或者select标签:是事件绑定生成的

<div class="input-group"> <!--input-group 引用的bootstarp -->
<div class="input-group-btn">
<label class="btn btn-default no-radius" type="button" style="width: 100px;"></label> lable标签:显示+号右侧的内容
<button type="button" class="btn btn-default dropdown-toggle no-border-r" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span></button>
button 标签用于生产下拉按钮,显示ul中li的内容
<ul class="change-search-condition dropdown-menu"> </ul>
</div> </div> <!--引用的bootstarp -->
1、处理搜素条件下拉框

前端html
<div class="search-area clearfix">
<!-- 组合搜索条件开始 -->
<div id="searchCondition" class="search-condition col-md-offset-2 col-md-8">
<!-- 单条搜索条件开始 -->
<div class="condition">
<!-- 单条搜索条件 + 图标区域开始 -->
<div class="icons">
<a class="btn btn-default">
<i class="fa fa-plus-square"></i>
</a>
</div>
<!-- 单条搜索条件 + 图标区域结束 -->
<!-- 单条搜索条件 + 图标右侧区域开始 -->
<div class="input-group">
<div class="input-group-btn">
<label class="btn btn-default no-radius" type="button" style="width: 100px;"></label>
<button type="button" class="btn btn-default dropdown-toggle no-border-r" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span></button>
<ul class="change-search-condition dropdown-menu"> </ul>
</div> </div>
<!-- 单条搜索条件 + 图标右侧区域开始 --> </div>
<!-- 单条搜索条件结束 -->
<!-- 组合搜索条件开始 -->
</div> <div class="search-btn col-md-offset-10 col-md-2">
<a class="btn btn-primary">搜索</a>
</div>
</div>
前端js
生成 input 或者 select
/* 处理搜素条件 第1个下拉框,绑定事件联通生成右侧 input */
function initSeachCondition(seachconfig) {
/* 如果没有初始化*/
if (!$('#searchCondition').attr('init')) {
var $ul = $('#searchCondition :first').find('ul');
$ul.empty();
initDefaultSearchCondition(seachconfig[0]);/*初始化搜素区域的 input的显示 */
$.each(seachconfig, function (i, iteams) {
var li = document.createElement('li');
var a = document.createElement('a');
a.innerHTML = iteams.title;
a.setAttribute('name', iteams.name);
a.setAttribute('type', iteams.type);
if (iteams.type == 'select') {
a.setAttribute('choice_name', iteams.choice_name);
} li.append(a);
$ul.append(li);
});
$('#searchCondition').attr('init','true');
} }
如果是第一次应该初始化
function initDefaultSearchCondition(item) {
// item={'name': 'hostname','title':'主机名','type':'input'},
if (item.type == 'input') {
var tag = document.createElement('input');
tag.setAttribute('type', 'text');
// $(tag).addClass('form-control no-radius')
tag.className = "form-control no-radius";
tag.setAttribute('placeholder', '请输入条件');
tag.setAttribute('name', item.name);
} else {
var tag = document.createElement('select');
tag.className = "form-control no-radius";
tag.setAttribute('name', item.name);
$.each(GlOBAL_CHOICES_DICT[item.choice_name], function (i, row) {
var op = document.createElement('option');
op.innerHTML = row[1];
op.setAttribute('value', row[0]);
$(tag).append(op);
})
}
$('#searchCondition').find('.input-group').append(tag);
$('#searchCondition').find('.input-group label').text(item.title);
}
知识点:
1、
var $ul =$('#searchCondition :first').find('ul');
jQuery查找标签下的第一个孩子 筛选器 frist
2、
<div class="search-area clearfix">
bootstrap的属性clearfix,子标签float之后,撑起父级标签;
bootstarp的col-md-offset-2 offset属性本质是float ;
2、搜素区域的input标签

给condition中url里面的li绑定事件,搜素下拉框切换,联动input标签切换
前端js
function bindSearchConditionEvent() {
$('#searchCondition ul').on('click', 'li', function () {
//$this 指得是li标签 <li><a href=""></a></li>
//找到lable标签,修改内容
$(this).parent().prev().prev().text($(this).text());
//根据li的设置的属性 创建input 或者select标签
$(this).parent().parent().next().remove();
var name = $(this).find('a').attr('name');
var type = $(this).find('a').attr('type');
if (type == 'select') {
var choice_name = $(this).find('a').attr('choice_name');
var tag = document.createElement('select');
tag.className = "form-control no-radius";
$.each(GlOBAL_CHOICES_DICT[choice_name], function (i, item) {
var op = document.createElement('option');
op.innerText = item[1];
op.setAttribute('value', item[0]);
$(tag).append(op);
});
}
else {
var tag = document.createElement('input');
tag.className = "form-control no-radius";
tag.setAttribute('placeholder', '请输入条件');
tag.setAttribute('name', name);
}
$(this).parent().parent().after(tag)
})
}
克隆多个搜素条件
1、首先给 图标 + 设置一个 add-condition 属性
<!-- 单条搜索条件 + 图标区域开始 -->
<div class="icons">
<a class="btn btn-default add-condition" >
<i class="fa fa-plus-square"></i>
</a>
</div>
<!-- 单条搜索条件 + 图标区域结束 -->
js
// 添加搜素条件
$('#searchCondition .add-condition').click(function () {
var $condition=$(this).parent().parent().clone();
$condition.find('.add-condition').removeClass('add-condition').addClass('del-condition').find('i').attr('class','fa fa-minus-square');
$condition.appendTo($('#searchCondition'));
});
// 删除搜素条件
$('#searchCondition').on('click','.del-condition',function () {
var $condition=$(this).parent().parent().remove();
})
2、每次点击页面都要把搜素条件传到后端
function inint(pageNum) {
$('#loading').removeClass('hide');
var condition = getSearchCondition();
$.ajax({
url: requesturl,
type: 'GET',
dataType: 'JSON',
data: {'pageNum': pageNum,'condition':condition},

生成这种数据


Q()组合复杂的搜素条件
con=Q() #创建Q对象
print(con)
执行结果
4、编辑模式
进入:把文本变更为input和select标签
退出:把input或者select标签变更为文本
基于js的CURD插件的更多相关文章
- 基于JS功能强大的日期插件Kalendae
开发中需要一个日期插件,可以在zepto下使用,可以选择日期段,可以设置不可选日期 找到一个完全满足的,并且基于JS不依赖于任何库. 在线演示:http://chipersoft.com/Kalend ...
- CURD插件(仿Django-admin版)
前言 如何提升自己的开发效率? 每个新项目都是自己经做过的项目(经验所致),在项目开发过程中不断总结.封装属于自己的组件, 例如:每个web项目大部分都涉及增删改查,分页显示,搜素,CRM就是这样的组 ...
- Breach - HTML5 时代,基于 JS 编写的浏览器
Breach 是一款属于 HTML5 时代的开源浏览器项目,,完全用 Javascript 编写的.免费.模块化.易于扩展.这个浏览器中的一切都是模块,Web 应用程序在其自己的进程运行.通过选择合适 ...
- ExtJS4.2学习(13)基于表格的扩展插件---rowEditing
鸣谢:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-24/182.html --------------- ...
- 基于jq图片居中插件 [center]
最近在做一个项目,大量的图片基于js进行缩放(图片放大镜),考虑用css要写许多hack,而已经基于jq了,干脆写个方法得了. 代码很简单,不用多讲但是很实用. $.fn.extend({ cente ...
- JS鼠标滚动插件scrollpath使用介绍
JS鼠标滚动插件scrollpath:在这个插件中首先要引人的JS是jQuery,因为后面的JS都是基于它的.再者需要引入的是jquery.scrollpath.js.scrollpath.css还有 ...
- 基于js鼠标拖动图片排序
分享一款基于js的图片排序效果.鼠标拖动图片,重新排列图片的排列顺序.该插件适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线 ...
- 基于vue的分页插件
相信大家用过很多jquery的分页插件,那这次就用一用基于vue的分页插件. 这里的环境用的是springboot 首先要引入pagehelper的jar文件,版本是1.2.3,配置文件也需要配置一下 ...
- 基于JS的高级脚本语言 Sara
Sara-基于JS的高级脚本语言 欢迎使用Sara,Sara是一款基于JavaScript的全新的高级脚本语言! Sara不像我们工作室上一款编程语言作品-Ginit一样,他属于更高级的语言 Sara ...
随机推荐
- jQuery 知识点总结
jQuery 是一个“写的更少,但做的更多”的轻量级JavaScript 库.对于网页开发者来说,学会jQuery是必要的.因为它让你了解业界最通用的技术,为将来学习更高级的库打下基础,并且确实可以很 ...
- Model中时间格式化
MVC 中 @Html中的时间格式化 @Html.TextBoxFor(model => model.StartTime, "{0:yyyy-MM-dd HH:mm:ss}" ...
- open()、fwrite()、fread()函数使用说明与示例
fopen()函数: 1.作用: 在C语言中fopen()函数用于打开指定路径的文件,获取指向该文件的指针. 2.函数原型: FILE * fopen(const char * path,const ...
- KMP字符串匹配(模板)
描述: 给出两个字符串 s1 和 s2 ,其中 s2 为 s1 的子串,求出 s2 在 s1 中所有出现的位置.同时要求输出 s2 的 fail 数组. 思路: KMP模板. 标程: #include ...
- 使用phpmyadmin创建数据库
1,使用phpmyadmin也需要实现安装php环境,安装环境请参考:http://www.sitestar.cn/bbs/thread-164-1-1.html: 2,到phpmyadmin官方网站 ...
- HTTP是什么连接
① 在HTTP/1.0中,默认使用的是短连接. 但从 HTTP/1.1起,默认使用长连接,用以保持连接特性. ②http长连接并不是一直保持连接 http的长连接也不会是永久保持连接,它有一个保持时间 ...
- socket之基础
链接https://www.cnblogs.com/clschao/articles/9593164.html
- IOC和DI的区别详解
IOC 是英文inversion of control的缩写,意思是控制反转DI 是英文Dependency Injection的缩写,意思是依赖注入 下面用一个简单的例子来描述一下IOC和DI的 ...
- python类中保存非绑定方法作为成员函数
习惯了函数式,动不动传一个函数.但是直接把函数作为类方法保存,再调用时会报错. 举一个unittest时的例子 class MyTestCase(unittest.TestCase): @classm ...
- docker-compose在dockerfile更新后自动更新image
比如在dockerfile里需要新安装包 形如 加一行 RUN pip3 install XXX 之后,希望docker-compose能更新镜像, 然后启动容器 只需要启动时使用 --build即可 ...