版本:javascript
django:2.1.7java
python:3.7python
功能描述:jquery
點擊「新建文件夾」按鈕,在table的末尾增長一行;單擊頁面的新增行,使單元格td變成可編輯狀態;輸入內容後,當單元格失去焦點時,保存輸入的內容;回車後經過AJAX提交後臺完成新建文件夾。ajax
HTML部分代碼,id="table2"和EditType="TextBox"後面須要用到。django
<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部分,新增行改一下:app
{% 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.最後,效果以下: