如何在JavaScript中计算表格列?

时间:2018-09-18 11:37:25

标签: javascript angularjs json html-table

使用JavaScript,我将返回商店服务员的列表,并在最后一行(服务员)之后动态插入一行,以显示合计列下所有服务员的总数。但是,现在我需要做的是在“运行总计”列中为每个服务员显示一个运行总计。

这是我要显示的内容,很明显,此处的运行总计公式不正确...

enter image description here

我知道还有更多的Angular-y方法可以做到这一点。我肯定会实现这种方式。但就目前而言,我只想让您专注于我要走的那条路,关于计算这个连续总排名。这就是我希望您重点关注的内容:

var total = 0;
  document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
    this.attendantNames.forEach(a=>{
      this.total += a.total;
    });
    cell.innerText = this.total;
  });

但是如果您需要查看整个控制器代码,就在这里:

export default class StoreTotalsController {
  constructor() {
    this.attendantNames = [];
    this.stores = [];
    this.emptyResult = true;
    this.totals = 0;
    this.total = 0;
    this.cellValue = "";
    this.runningTotalCells;
    //this.previousTotal = 0;
  }

  getAttendants() {
    showLoader('Searching');
    const baseUrl = '/src/areas/store-totals/services/tender-total-data.json';
    const getStores = new Request(baseUrl, {
      method: 'GET'
      });
    fetch(getStores).then(function(response){
      return response.json();
    }).then(resp => {
    if (!(resp[0] && resp[0].error)) {
      this.attendantNames = resp.stores[0].attendants;
      this.attendantNames.forEach(a=>{
        this.totals += a.total;
        console.log("Attendant :" , a.attendantName, "Had a total of :" , a.total, "With running total " , this.totals);
      });

      //Row at bottom displaying total of totals
      var table = document.querySelector('.table');
      var td1 = document.createElement('td');
      var td2 = document.createElement('td');
      var td3 = document.createElement('td');
      var tr = document.createElement("tr");
      tr.setAttribute("class", "last-row");
      var td1Data = document.createTextNode('  ');
      var td2Data = document.createTextNode('Total');
      var td3Data = document.createTextNode('$' + this.totals.toFixed(2));
      td1.appendChild(td1Data);
      td2.appendChild(td2Data);
      td3.appendChild(td3Data);
      tr.appendChild(td1);
      tr.appendChild(td2);
      tr.appendChild(td3);
      table.appendChild(tr);

      this.emptyResult = false;
      this.errorMessage = null;

    } else {
      this.errorMessage = resp[0].error.name;
    }
    digest();

  var total = 0;
  document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
    this.attendantNames.forEach(a=>{
      this.total += a.total;
    });
    cell.innerText = this.total;
  });
    showLoader(false);
    });
  }

  searchIfReady() {
    if (this.search && this.date && this.date.isValid()) {
      this.getSearch();
    }
  }

  updateDate(date) {
    this.date = moment(date).startOf('day');
    this.searchIfReady();
  }
}
StoreTotalsController.$inject = ['$stateParams'];

2 个答案:

答案 0 :(得分:0)

您可以使用$("td:nth-child(2)").each循环第二个单元格,然后将该单元格的值添加到total变量中,并使用$(this).next('td').text(total);打印该单元格到下一个td

var total = 0;
$("td:nth-child(2)").each(function( index ) {
  total = parseInt($(this).text()) + parseInt(total);
  $(this).next('td').text(total);
});
table{
text-align: center;
}
td{
width: 100px;
background-color: orange;
}
th{
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<th>name</th>
<th>Total</th>
<th>Running Total</th>
<tr>
<td>Eric</td>
<td>100</td>
<td></td>
</tr>

<tr>
<td>Lars</td>
<td>20</td>
<td></td>
</tr>

<tr>
<td>Patrick</td>
<td>200</td>
<td></td>
</tr>
</table>

答案 1 :(得分:0)

let total = 0;

document.addEventListener("DOMContentLoaded", function(event) { 
  document.querySelectorAll("td:nth-child(2)").forEach((cell, index) => {
    const cellInnerHTML = cell.innerHTML
    const numericTotal = cellInnerHTML.substring(1, cellInnerHTML.length);

    total += parseInt(numericTotal) * 1000;

    cell.parentElement.querySelectorAll("td")[2].innerHTML = total;
  });
});

Codepen:

https://codepen.io/anon/pen/vzQyGy

  1. 您需要注意删除$符号。
  2. 在parseInt之后,由于数字格式的原因,根据您的示例,您将剩下2、8和5,而不是2000、8000、5000。 我乘以1000天真地处理它。应该找到更好的解决方案,这只是一个草图。
  3. 您需要将数字格式化为所需的格式。

解决方案在那里,我给您留详细信息:)

对于您的代码,它应该像这样:

this.attendantNames.forEach((attendant, index) => {
    const table = document.querySelector('.table');
    const attendantRow = table.querySelectorAll('tr')[index];
    const runningTotalCell = attendantRow.querySelectorAll('td')[2];

    //am assuming that this.totals is 0 at the beginning of this loop, right?
    this.totals += parseInt(attendant.total); //am not sure of format attendant.total have in your data, not sure if you need parsing here and if  it will work

    runningTotalCell.innerHTML = `$${this.totals.toFixed(2)}`; 
})

应该可以工作,但是无法运行代码,查看它是否确实在执行或抛出错误,对其进行调试等。我不能百分百地给您。 如果有任何错误,请尝试自己解决:) 如果您会被卡住,请回来并告诉我哪里出了问题以及在哪里,我会尝试再次提供帮助:)

一般评论

  • 您的方法被命名为getAttendants,它的作用远比WAAAAY(获取助理)更多。它获取话务员数据,创建表的各个部分,并用数据填充该表。它不应该。方法只能做一件事(单一职责原则),并且要正确命名。
  • 您应该在几个功能之间划分职责,并在它们之间传递数据,使每个功能只能处理一项任务。

例如  -功能A-获取话务员数据  -函数B-创建表  -函数C-用服务员数据填充该表

在这些函数中,您可以将代码拆分为较小的函数。 在放置注释的位置,您可以使用内部带有注释代码的函数,并且仅按名称命名,它们将向开发人员解释其功能。 例如

在每个循环中使用以下三行,仅用于访问该runnintTotalCell。

const table = document.querySelector('.table');
const attendantRow = table.querySelectorAll('tr')[index];
const runningTotalCell = attendantRow.querySelectorAll('td')[2];

您可以提取它们并用单独的函数包装:

getRunningTotalCellForRow(rowIndex) { 
    const table = document.querySelector('.table');
    const attendantRow = table.querySelectorAll('tr')[index];
    return attendantRow.querySelectorAll('td')[2];
}

并在forEach循环中使用。

等等。

通常,为了学习正确的编码方式,您可以学习一些教程,阅读一些书籍并了解相关规则:)

关于书籍-罗伯特·C·马丁(Robert C. Martin)的《清洁法》是其中之一。 至于教程和其他在线资源。

在浏览器中搜索您选择的文本,例如:  -如何编写简洁的代码  -单一责任原则  -坚实的干吻  -关键软件开发原则

我认为,从网站上您会发现,您可以找到更多内容并投入使用。

祝你好运,玩得开心!

编辑代码后:

我检查了您的屏幕截图。红色部分告诉我,在第一行中,您在第二个单元格中插入TOTAL FOR ALL(大约32k)是该值,但在第三值乘以3时则增加了一倍。得出结论,您必须在循环中弄乱一些附加内容。

所以

var total = 0;
document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
  this.attendantNames.forEach(a=>{
    this.total += a.total;
  });
  cell.innerText = this.total;
});

您在上面做什么:

  1. 您定义的var total = 0(并且从不使用)

  2. 每个第4个单元格

  3. 带所有服务员,并为每个服务员

  4. 将其total值添加到this.total

  5. 并将其插入innerText

现在看到了吗?对于每个单元格,您正在为所有话务员插入汇总总数(加上您已经拥有的this.totals值,因为您永远不会将其清零)。

以下为正确版本:

const runningTotalCells = document.querySelectorAll("td:nth-child(4)");
//no need for nested loops
this.attendantNames.forEach((attendant, index) => {
  this.total += a.total;
  runningTotalCells[index].innerText = this.total;
})

现在可以使用吗?