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.编写后台业务逻辑 ...
随机推荐
- 从一段简单算法题来谈二叉查找树(BST)的基础算法
先给出一道很简单,喜闻乐见的二叉树算法题: 给出一个二叉查找树和一个目标值,如果其中有两个元素的和等于目标值则返回真,否则返回假. 例如: Input: 5 / \ 3 6 / \ \ 2 4 7 T ...
- WinForm DataGridView制作表格
1. 将背景颜色改为白色 this.dataGridView1.BackgroundColor = Color.White; 或 2. 禁止启用添加,启用编辑,启用删除 this.dataGridV ...
- WPF 在一个dll创建一个Window(包含xaml),在另一个dll中再次继承 会出错
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e92390eb-bbfa-42fb-baa9-2286444c0dca/the-comp ...
- C#应用配置信息保存和读取
//保存信息 SystemConfig.WriteConfigData(“字段名称”, “这里是需要保存的内容”); //读取信息 SystemConfig.GetConfigData(“字段名称”, ...
- 年度调查 看看 2016 年 Go 语言调查结果
Go 语言官方博客公布了 2016 年 Go 语言使用调查. 在 3,595 名被调查者中,89% 称他们在工作中或工作之外用 Go 编程:63% 称他们的工作是 Web 开发,但只有 9% 的人只从 ...
- WebRequest请求错误(服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF)
WebRequest请求错误(服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF)解决办法,天津config文件,增加一个配置如下 <?x ...
- Java基础(四) StringBuffer、StringBuilder原理浅析
StringBuilder与StringBuffer作用就是用来处理字符串,但String类本身也具备很多方法可以用来处理字符串,那么为什么还要引入这两个类呢? 关于String的讲解请看Java基础 ...
- export命令的使用
一:export将环境变量昭告天下 1.直接输入export会将显示bash下的所有环境变量 2.env/set/export/declare都可以显示shell的变量 ...
- git日常使用整理
注册使用gitlab新用户 在gitlab注册完账号后,创建项目,会有如下提示 点击add an SSHkey 现实如下: 点击generate it,按照提示计算ssh key 把结果粘贴到gitl ...
- 【设计模式】行为型06命令模式(Command Pattern)
命令模式 个人理解:命令模式,本质上是一种多层次的封装. 好处:降低耦合,扩展极其方便. 以下一段文案摘抄自:http://www.runoob.com/design-pattern/command- ...