Django前端HTML經過JS實現表格可編輯,動態添加行,回車完成新建文件夾

版本: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">&nbsp;&nbsp;&nbsp;
                       {% 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'>&nbsp;&nbsp;&nbsp;
    // 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.最後,效果以下:

相關文章
相關標籤/搜索