组件化的可编辑表格

文章介绍了如何利用json-server模拟后台数据,通过JavaScript处理JSON文件内容来初始化和更新可编辑表格,同时实现表格的增删改功能,通过DOM操作绑定事件,确保数据与界面同步。然而,目前的实现尚缺少将数据更改回写到JSON文件的功能。
摘要由CSDN通过智能技术生成

设计思路:

        在实现可编辑表格基础功能的情况下,做到对其具体功能的模块化,并且将其数据来源于服务端,由JSON格式展示,当在表格上进行编辑时,异步更新JSON文件中的数据。


实现方法:

        通过json-server来模拟后台的数据操作,编写具体的json文件,将要渲染的表格数据初始化在json文件中。

        在已完成的基础可编辑表格上,通过ajax请求,将json文件中的数据获取,然后再通过js渲染DOM内容,实现初始化表格的生成。

        再根据需求,对表格进行功能的添加,将增加,删除,修改的功能,通过函数封装,将其功能绑定到具体的元素中,实现表格的功能需求。


具体功能代码:

1.读取json数据:

// 读取本地json数据
let ajax = new XMLHttpRequest();
ajax.open("get", "data.json");
ajax.send();
ajax.onreadystatechange = function () {
  if (ajax.readyState == 4 && ajax.status == 200) {
    let alldata = JSON.parse(ajax.responseText);
    title_data.push(alldata.t_title); 
    grade_data.push(alldata.t_grades); 
    getHtml(); // 生成HTML
  }
};

2.渲染DOM完善表格:

let stutable = document.getElementsByClassName("table")[0];
let stutable_title = stutable.getElementsByTagName("thead")[0]
    .getElementsByTagName("tr")[0]; // 获取th标题行
let stutable_grade = stutable.getElementsByTagName("tbody")[0]; // 获取tbody
let stu_trs = stutable_grade.getElementsByTagName("tr"); // 获取tbody的tr标签

var title_data = []; // 存放标题数据
var grade_data = []; // 存放成绩数据
let delbtns = document.getElementsByTagName("button");
let addbtns = document.getElementsByTagName("button");

var editcell = document.getElementsByName("editable"); // 可编辑的单元格
var thetips = document.getElementsByClassName("err")[0];
var alltr = document.getElementsByTagName("tr"); // 获取HTML中所有的tr标签

var flag; // 设置是否显示删除栏


// 渲染DOM内容
function getHtml() {
  let titlekey, gradekey; // 用于存放对象的key
  // 表头
  for (item of title_data) {
    for (let i = 0; i < item.length; i++) {
      titlekey = Object.values(item[i]); // 取出表头数据
      let temp_title = `
                    <th>${titlekey}</th>
                   `;
      stutable_title.insertAdjacentHTML("beforeend", temp_title);
    }
  }
  // 表格内容
  for (item of grade_data) {
    for (let i = 0; i < item.length; i++) {
      gradekey = Object.keys(item[i]);
      let temp_grade = `<tr>`;
      // console.log(gradekey); // 获取到的key数组
      for (let j in gradekey) {
        let k = gradekey[j]; // 获取到的key值
        // console.log(item[i][k]); // 取出对象中的值

        // 判断是否是最后一个键名
        if (j == gradekey.length - 1) {
          temp_grade += `<td>${item[i][k]}</td></tr>`;
        } else {
          temp_grade += `<td>${item[i][k]}</td>`;
        }
      }
      stutable_grade.insertAdjacentHTML("beforeend", temp_grade);
    }
  }
  setEditable([2, 3]); // 设置可编辑单元格
  flag = true; // 删除栏
  if (flag) actionBar(); // 生成操作栏
}

// 添加操作栏
function actionBar() {
  let caozuo = document.createElement("th");
  caozuo.innerText = "操作";
  stutable_title.appendChild(caozuo);
  for (let k = 0; k < stu_trs.length; k++) {
    let caozuo2 = document.createElement("td");
    let btn = document.createElement("button");
    btn.innerText = "删除";
    caozuo2.appendChild(btn);
    stu_trs[k].appendChild(caozuo2);
  }
  delRow(); // 删除操作
}

// 给单元格添加点击事件
function setCellCilck() {
  let scorearr = [30, 9999];
  for (let i = 0; i < editcell.length; i++) {
    editcell[i].onclick = function () {
      updateCell(this, scorearr);
      delRow();
    };
  }
}

3.函数功能封装:

// 更新单元格内容
function updateCell(ele, scorearr) {
  let scoreMax = scorearr[ele.cellIndex - 2];
  scoreMax = scoreMax || 100;
  console.log("当前输入最大值:" + scoreMax);
  if (document.getElementsByClassName("active-input").length == 0) {
    var oldhtml = ele.innerHTML;
    ele.innerHTML = "";
    var newInput = document.createElement("input");
    newInput.setAttribute("class", "active-input");
    newInput.value = oldhtml;
    newInput.onblur = function () {
      this.value = parseFloat(this.value);
      if (this.value < 0 || this.value > scoreMax) {
        console.log("err");
        addAnimate();
        thetips.style.display = "block";
        return;
      } else {
        thetips.style.display = "none";
        ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;

        /*    映射数据表    */
        // 取出当前单元格数据
        let ediId = ele.parentNode.children[0].innerHTML; // 获取当前修改的单元格的id
        // console.log(ediId);
        for (item of grade_data) {
          for (let i = 0; i < item.length; i++) {
            // 取出数据集的所有键名
            let gradekey = Object.keys(item[i]);
            // console.log(item[i].id); // 取出数据集的id
            // console.log(ele.cellIndex); // 输出当前单元格所在行的列数
            if (item[i].id == ediId) {
              item[i][gradekey[ele.cellIndex]] = parseFloat(this.value);
            }
          }
        }
        console.log("修改后的数据是:", grade_data);
      }
    };
    newInput.select();
    ele.appendChild(newInput);
    newInput.focus();
  } else {
    return;
  }
}
// 添加动画
function addAnimate() {
  thetips.className = "err movedown";
}

// 删除表格行
function delRow() {
  for (let i = 0; i < delbtns.length; i++) {
    delbtns[i].onclick = function () {
      let rowindex = this.parentNode.parentNode.rowIndex; // 获取当前行
      let delindex = rowindex - 1;
      stutable.deleteRow(rowindex);
      /*    映射数据表    */
      let ediId = this.parentNode.parentNode.children[0].innerHTML; // 获取当前单元格的id
      for (item of grade_data) {
        for (let i = 0; i < item.length; i++) {
          if (item[i].id == ediId) {
            item.splice(delindex, 1);
            console.log("删除后的数据是:", grade_data);
          }
        }
      }
    };
  }
}

总结:

        为实现可编辑表格的功能的数据管理,这里采用了json文件读的操作,使得数据能够在不手动编写html文件的情况下,实现表格的初始化正常更新,并且对于html中的各个元素节点,通过原生js的操作,使得每一个节点都能被具体的函数事件绑定,实现了功能渲染,以及动态的添加,与基础版本的编辑表格不同的是,可以灵活的决定表格的初始内容。

        但此表格只实现了读取数据的功能,并没有编写出对数据更改,并映射到json文件中的功能。仍然有更改优化的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值