user9541762
user9541762

Reputation:

Ng-Bind Affecting Table Head

I have a table with three columns in the header. I want to bind a function that calculates that third column--the running total column. When I added this binding to the thead in the template, I got the results I wanted. But I lost my table header. I worked in a solution proposed by a user, and it worked, my table head came back. But now the problem is, there is another view using the expanding table template. What I need to do is, in this ng-repeat property in $table.properties track by property.type, I need to check to see whether the table has the 'runningTotal' type property. And if it does, to fire my calculateRunningTotal function. Otherwise this function is firing for every table using this template and trying to manipulate the third column, whatever that may be. That's not what I need.

<th ng-bind="calculateRunningTotal(property.type)" ng-repeat="property in $table.properties track by property.type"
            class="col-xs-{{property.size}} clickable" ng-click="$table.sorter.changeType(property.type)">
            {{property.label}} &nbsp;
          <i class="fa fa-caret-{{$table.sorter.directionFor(property.type)}} fa-lg"></i>
        </th>

Store Tender Totals Now Missing First Two Column Headers Access Logs Table Now Missing All Column Headers

This is the template code:

import app from 'act/app';
import * as table from 'act/components/table';
import './expanding-table.styles.less';
import * as $ from 'jquery';

const expander = `
  <td class="col-xs-1 text-center link" ng-click="$event.stopPropagation()">
    <i class="fa fa-chevron-{{$item.expanded ? 'up' : 'down'}}" ng-click="$item.expanded = !$item.expanded"></i>
  </td>
`;

const fakeRows = `
  <tbody ng-if="!$table.list.length">
    <tr class="dummy-data" ng-repeat="dummy in $table.fakeRows">
      ${expander}

      <td ng-repeat="property in $table.properties track by property.type">
        dummy
      </td>
    </tr>
  </tbody>
`;

const header = `
  <thead>
    <th>

    </th>

    <th ng-bind="calculateRunningTotal()" ng-repeat="property in $table.properties track by property.type"
        class="col-xs-{{property.size}} clickable" ng-click="$table.sorter.changeType(property.type)">
        {{property.label}} &nbsp;
      <i class="fa fa-caret-{{$table.sorter.directionFor(property.type)}} fa-lg"></i>
    </th>
  </thead>
`;

const rows = ({ row, ngRepeat, cell }) => `
  <tbody ng-if="$table.list.length">
    <tr class="clickable"
        ng-repeat-start="${ngRepeat}"
        ng-click="$item.expanded = !$item.expanded"
        ng-init="$item.expanded = false">
      ${row({ cell })}
    </tr>

    <tr class="expanded-row" ng-show="$item.expanded"
        ng-repeat-end>
      <td colspan="12">
        <div expanded-placeholder></div>
      </td>
    </tr>
  </tbody>
`;

const row = ({ cell }) => `
  ${expander}

  ${cell}
`;

app.directive('actExpandingTable', ['$compile', $compile =>
  table.defaultDirective({
    link: function($scope, $element, $attrs, $tables, $transclude) {
      // wondering what's going on here? see table/table.resources.js

      const $el = $(table.generateTemplate({ header, rows, row, fakeRows }));
      $scope.vm = $scope.$parent.vm;
      $scope.calculateRunningTotal= function(){
 if(type ==="runningTotal"){
        console.log("Calculate Running Total Called");
        var attendantTotalCell = 0;
        var total = 0;
        var totalCell="";
        var totalsCells = document.querySelectorAll("td:nth-child(3)");

        totalsCells.forEach(function(cell, index){
          totalCell = cell.innerText;
          attendantTotalCell = totalCell.replace(/[^0-9-.]/g, '');
          total = parseInt(attendantTotalCell) + parseInt(total);
          if(cell.nextElementSibling){
          cell.nextElementSibling.innerHTML = '$' + total.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
          }
        })

        var tableHeadRow = document.querySelectorAll('th.col-xs-2.clickable');
        tableHeadRow.forEach(th =>{
          th.addEventListener("click", function(){
            console.log("Table head clicked");
            var attendantTotalCell = 0;
            var total = 0;
            var totalCell="";
            totalsCells.forEach(function(cell, index){
              totalCell = cell.innerText;
              attendantTotalCell = totalCell.replace(/[^0-9-.]/g, '');
              total = parseInt(attendantTotalCell) + parseInt(total);
              if(cell.nextElementSibling){
              cell.nextElementSibling.innerHTML = '$' + total.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
              }
            })
          })
        }) 
         return label;
         }
        }
      $transclude($scope, content => {
        if (content.length > 1) {
          $el.find('[expanded-placeholder]').replaceWith(content);
        } else {
          throw new Error('Expanding table requires transcluded content to show when expanded!');
        }

        $compile($el)($scope, v => $element.append(v));
      });
    },
  })
]);

Upvotes: 0

Views: 56

Answers (1)

Naga Sai A
Naga Sai A

Reputation: 10975

Use double curly markup {{calculateRunningTotal()}} instead of ng-bind ,as ng-bind with a function, will not be fired for every digest cycle unless you are passing any variable to that method. Check this link for more details - AngularJS ng-bind with a function

<th ng-repeat="property in $table.properties track by property.type"
        class="col-xs-{{property.size}} clickable" ng-click="$table.sorter.changeType(property.type)">
        {{calculateRunningTotal()}}{{property.label}} &nbsp;
      <i class="fa fa-caret-{{$table.sorter.directionFor(property.type)}} fa-lg"></i>
    </th>

Reason for empty header with example :

th tag displays return value value of ng-bind function, as calculateRunningTotal calculates total and no return value, header is getting as empty

To resolve your issue with ng-bind, pass property.label to ng-bind="calculateRunningTotal(property.label)" and return value from calculateRunningTotal

$scope.calculateRunningTotal= function(label){
  //total calculation here

return label

}

codepen sample for reference - https://codepen.io/nagasai/pen/vzqadB

Upvotes: 1

Related Questions