Django前端HTML通过JS实现表格可编辑,动态添加行,回车完成新建文件夹
版本:
django:2.1.7
python:3.7
功能描述:
点击“新建文件夹”按钮,在table的末尾增加一行;单击页面的新增行,使单元格td变成可编辑状态;输入内容后,当单元格失去焦点时,保存输入的内容;回车后通过AJAX提交后台完成新建文件夹。
HTML部分代码,id="table2"和EditType="TextBox"后面需要用到。
<button class="btn btn-default" type="button" id="create_dir" name="create_dir" value="create_dir" style='margin-left:10px;margin-right:10px;color:rgb(60, 141, 188);' onclick="AddRow($('#table2')[0],1)">新建文件夹</button> <table id="table2" class="table table-hover" style="overflow: auto;" >
<tr>
<td class='th3' EditType="TextBox">
<img src="/static/img/file4_24.ico">
{% if fileinfo.search_flag == 0 %}
{{ fileinfo.file_name }}
{% else %}
{{ fileinfo.file_path }}
{% endif %}
</td>
</tr>
样式表格td部分,新增行改一下:
{% block style %}
<style>
td{
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #CCCCCC;
}
.EditCell_TextBox {
width: 90%;
border:1px solid #0099CC;
}
.EditCell_DropDownList {
width: 90%;
}
</style>
{% endblock %}
JS部分,也是最关键的一部分:
{% block javascripts %}
<script>
/**
* JS实现可编辑的表格
* 用法:EditTables(tb1,tb2,tb2,......);
**/
//添加行
function AddRow(table, index){
var lastRow = table.rows[table.rows.length-1];
var newRow = lastRow.cloneNode(true);
//计算新增加行的序号,需要引入jquery 的jar包
var startIndex = $.inArray(lastRow,table.rows);
var endIndex = table.rows;
table.tBodies[0].appendChild(newRow);
// newRow.cells[0].innerHTML=endIndex-startIndex;
newRow.cells[1].innerHTML="新建文件夹";
// <img src='/static/img/folder_24.ico'>
// console.log(newRow.cells[0].innerHTML);
SetRowCanEdit(newRow);
return newRow;
}
function SetRowCanEdit(row){
// console.log(row.cells.length);
for(var j=0;j<row.cells.length; j++){ //如果当前单元格指定了编辑类型,则表示允许编辑
var editType = row.cells[j].getAttribute("EditType");
if(!editType){
//如果当前单元格没有指定,则查看当前列是否指定
editType = row.parentNode.rows[0].cells[j].getAttribute("EditType");
}
if(editType){
//新建后直接处于可编辑状态
EditCell(row.cells[j]);
row.cells[j].onclick = function (){
EditCell(this);
}
}
}
}
//设置指定单元格可编辑
function EditCell(element, editType){
var editType = element.getAttribute("EditType");
if(!editType){
//如果当前单元格没有指定,则查看当前列是否指定
editType = element.parentNode.parentNode.rows[0].cells[element.cellIndex].getAttribute("EditType");
} switch(editType){
case "TextBox":
CreateTextBox(element, element.innerHTML);
break;
default:
break;
}
}
//为单元格创建可编辑输入框
function CreateTextBox(element, value){
//检查编辑状态,如果已经是编辑状态,跳过
var editState = element.getAttribute("EditState");
if(editState != "true"){
//创建文本框
var textBox = document.createElement("INPUT");
textBox.type = "text";
textBox.className="EditCell_TextBox"; // value = "新建文件夹"
//设置文本框当前值
if(!value){
value = element.getAttribute("Value");
}
textBox.value = value; //设置文本框的失去焦点事件
textBox.onblur = function (){
CancelEditCell(this.parentNode, this.value);
}
//向当前单元格添加文本框
ClearChild(element);
element.appendChild(textBox);
textBox.focus();
textBox.select(); //改变状态变量
element.setAttribute("EditState", "true");
element.parentNode.parentNode.setAttribute("CurrentRow", element.parentNode.rowIndex);
//回车事件
textBox.onkeypress = function(event){
// console.log(element.innerHTML);
// console.log(this.value);
if (event.keyCode == "13"){
$.ajax({
url:"/create_dir?dir_name="+this.value,
// url:"{% url 'upload_files' %}",
type:"GET",
data:'', //
processData:false,
contentType:false,
success:function (data) {
// console.log(data)
// alert("创建文件夹完成!");
history.go(0);
}
});
}
} }
}
//取消单元格编辑状态
function CancelEditCell(element, value, text){
element.setAttribute("Value", value);
if(text){
element.innerHTML = text;
}else{
element.innerHTML = value;
}
element.setAttribute("EditState", "false");
//检查是否有公式计算
CheckExpression(element.parentNode);
}
//清空指定对象的所有字节点
function ClearChild(element){
element.innerHTML = "";
}
//提取指定行的数据,JSON格式
function GetRowData(row){
var rowData = {};
for(var j=0;j<row.cells.length; j++){
name = row.parentNode.rows[0].cells[j].getAttribute("Name");
if(name){
var value = row.cells[j].getAttribute("Value");
if(!value){
value = row.cells[j].innerHTML;
}
rowData[name] = value;
}
}
//alert("ProductName:" + rowData.ProductName);
//或者这样:alert("ProductName:" + rowData["ProductName"]);
return rowData;
} //检查当前数据行中需要运行的字段
function CheckExpression(row){
for(var j=0;j<row.cells.length; j++){
expn = row.parentNode.rows[0].cells[j].getAttribute("Expression");
//如指定了公式则要求计算
if(expn){
var result = Expression(row,expn);
var format = row.parentNode.rows[0].cells[j].getAttribute("Format");
if(format){
//如指定了格式,进行字值格式化
row.cells[j].innerHTML = formatNumber(Expression(row,expn), format);
}else{
row.cells[j].innerHTML = Expression(row,expn);
}
}
}
} //计算需要运算的字段
function Expression(row, expn){
var rowData = GetRowData(row);
//循环代值计算
for(var j=0;j<row.cells.length; j++){
name = row.parentNode.rows[0].cells[j].getAttribute("Name");
if(name){
var reg = new RegExp(name, "i");
expn = expn.replace(reg, rowData[name].replace(/\,/g, ""));
}
}
return eval(expn);
} $(function() {
var tabProduct = document.getElementById("table2");
// 设置表格可编辑
// 可一次设置多个,例如:EditTables(tb1,tb2,tb2,......)
// EditTables(tabProduct);
// console.log('test!!!!!!!!!!!!!!');
}); </script>
{% endblock %}
JS部分根据自己的需求优化了一下:
1.EditTables()设置多个表格不要了,我只需要编辑新增行就行了。而且innerHTML会被看到td中代码。
2.tabProduct获取自己table的id。
3.新增按钮onclick="AddRow($('#table2')[0],1)",参数为自己表对象,注意[0]。AddRow中可以改新增行默认内容,我的为“新建文件夹”。
4.SetRowCanEdit()函数中增加如下代码,使新增行后直接处于可编辑状态,也可以单击进入编辑状态。
EditCell(row.cells[j]);
5.CreateTextBox()中获取用户输入的值,增加捕获键盘回车事件后,通过AJAX提交后台:
textBox.onkeypress = function(event){
if (event.keyCode == "13"){
$.ajax({
url:"/create_dir?dir_name="+this.value,
type:"GET",
data:'', //
processData:false,
contentType:false,
success:function (data) {
// alert("创建文件夹完成!");
history.go(0);
}
});
}
}
6.python后台实现新建文件夹,AJAX异步处理后返回直接更新目录,不需要刷新:
def create_dir(request):
if request.method == 'GET':
dir_name = request.GET.get('dir_name')
print('create_dir:'+dir_name)
path = os.path.join(current_path,dir_name)
while os.path.exists(path):
path += '-副本'
os.makedirs(r'%s'%path)
return HttpResponse(path)
else:
return HttpResponse("error")
7.这样空表格的时候新建行还是会出问题,因为是克隆最后一行新建的,所有空表格时需要自己动态的新建一个行,DataTable.js空表格时会有提示“空表格”的一行,所有先deleteRow删除行,再insertRow插入行。最后创建可编辑单元,和单机触发。
代码如下:
function AddRow(table, index){
var lastRow = table.rows[table.rows.length-1];
var newRow = lastRow.cloneNode(true);
//计算新增加行的序号,需要引入jquery 的jar包
if(newRow.cells.length > 1){
newRow.cells[1].innerHTML="新建文件夹";
table.tBodies[0].appendChild(newRow);
SetRowCanEdit(newRow);
}else{
table.deleteRow(1);
newRow = table.insertRow(1);
newRow.insertCell(0).innerHTML = "<td><input type='checkbox'/></td>";
newRow.insertCell(1).innerHTML = "<td>新建文件夹</td>";
newRow.insertCell(2).innerHTML = "<td>-</td>";
newRow.insertCell(3).innerHTML = "<td>-</td>";
newRow.insertCell(4).innerHTML = "<td>-</td>";
newRow.insertCell(5).innerHTML = "<td>-</td>";
newRow.insertCell(6).innerHTML = "<td>-</td>";
newRow.insertCell(7).innerHTML = "<td>-</td>";
CreateTextBox(newRow.cells[1],newRow.cells[1].innerHTML);
newRow.cells[1].onclick = function (){
CreateTextBox(this,this.innerHTML);
}
}
return newRow;
}
8.最后,效果如下:
Django前端HTML通过JS实现表格可编辑,动态添加行,回车完成新建文件夹的更多相关文章
- 使用js在页面上新建文件夹
使用js在页面上新建文件夹 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- js控制表格实时编辑
点击添加,在表格的最后一行添加一行表单元素,右侧按钮变为保存和取消.(点击保存,数据用ajax无刷新添加到界面,点击取消,取消此行的添加.)点击编辑,在本行改为表单,带有原来的值,右侧按钮变为确认和取 ...
- js实现表格行的动态加入------Day56
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/marSmile_tbo/article/details/36752655 现代页面通常都是用div+ ...
- 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...
- 每天一个JS 小demo之新建文件夹。主要知识点:DOM方法的综合运用
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"& ...
- django模板导入外部js和css等文件
1.新建文件夹templates(存放模板文件),新建文件夹media(存放js.css.images文件夹),并把两个文件夹放到了项目的根目录下 2.设定模板路径 设置模板路径比较简单,只要在set ...
- java实现word转pdf在线预览(前端使用PDF.js;后端使用openoffice、aspose)
背景 之前一直是用户点击下载word文件到本地,然后使用office或者wps打开.需求优化,要实现可以直接在线预览,无需下载到本地然后再打开. 随后开始上网找资料,网上资料一大堆,方案也各有不同,大 ...
- 前端之Vue.js库的使用
vue.js简介 Vue.js读音 /vjuː/, 类似于 view Vue.js是前端三大新框架:Angular.js.React.js.Vue.js之一,Vue.js目前的使用和关注程度在三大框架 ...
- node.js零基础详细教程(2):模块化、fs文件操作模块、http创建服务模块
第二章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...
随机推荐
- wpf 复制/剪切到本地系统剪切板中以供右键粘贴用
原文:wpf 复制/剪切到本地系统剪切板中以供右键粘贴用 http://www.cnblogs.com/yhdkzy/archive/2012/11/27/2790655.html /// & ...
- 在WPF中引用WinForm的控件
以ArcEngine为例: mapControl = new AxMapControl(); MapHost.Child = mapControl; //MapHost为WindowsFormHos ...
- sql xml 查询指定节点值,以及节点属性值
SELECT top 10 [HFMBDATA].query('(/Items/Item[@ID=''tbBryj''])').value('(//TextValue)[1]','nvarcha ...
- AFN小结(简单的封装)
AFN小结 1,AFN概念.原理 2,AFN的封装使用 3,AFN与其它框架对比 ————————————————————————————————— 1 , AFN的概念原理: AFN的基础是NSUR ...
- PHP命名空间和自动加载初探
参考资料: PHP手册-语言参考:http://php.net/manual/zh/language.namespaces.php 概要: 1. 声明了命名空间之后,下面的const, funct ...
- 我们错过了那么多机会,怎么办(就是预见未来的能力,并且要去做、要去投入,所以要主动学习、储备、选择,要不断的思考)good
那天在IT职业咨询QQ群里聊天,提到腾讯.阿里,我说跟着这两家公司从小到大的朋友,都获得了不菲的回报,成了富翁或者财务自由了. 有群友感叹说:“是啊,我们错过了那么多机会.” 看到这句话,我心里一动, ...
- RedHat 7.3 修改ASM磁盘绑定路径
RedHat 7中,很多命令发生了改变,绑定磁盘不再是start_udev,而是udevadm,具体绑定方式,请看另一篇博文: http://www.cnblogs.com/zx3212/p/6757 ...
- matplotlib简介
python的matplotlib包可以帮助我们绘制丰富的图表,有助于我们的数据分析. matplotlib官方文档:matplotlib 本博客所有代码默认导入matplotlib.pyplot和n ...
- Delphi线程类 DIY(把类指针作为参数传进去,就可以执行类里面的方法啦)
Delphi 封装了一个很强大的线程类 TThread, 我们也自己动手制作一个简单的线程类 首先Type一个类 type TwwThread = class constructor Create; ...
- C++开源库,欢迎补充
C++在“商业应用”方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C#语 ...