Adding values from array with AngularJS - javascript

Using javascript and AngularJS how would I go about adding the Hours values into a variable. I've tried simple JS that I do know (limited knowledge, still beginner) and no luck.
<table class="table table-condensed table-striped table-hover">
<thead>
<tr>
<!--<td></td>-->
<td>Employee <i class="fa fa-sort"></i></td>
<td>Hours <i class="fa fa-sort"></i></td>
<td>Date <i class="fa fa-sort"></i></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="jobhour in jobHours | orderBy:predicate:reverse">
<!--<td>{{$index + 1}}</td>-->
<td>{{jobhour.UserName}}</td>
<td>{{jobhour.AdminHours*1 + jobhour.FieldHours*1 + jobhour.OtherHours*1 + jobhour.TravelHours*1 | number:2}}</td>
<td>{{jobhour.Date | date:medium}}</td>
</tr>
</tbody>
</table>
Above is the code for the ng-repeat on the table and you see I'm adding several values into that column already (this may be why I'm not sure on a simple way to approach this). The TOTAL value I'm trying to get is nothing more than a simple UI notification. I want to place this 'TOTAL SUM' into the label above next to Total Hours:
ANSWER FOR THIS SPECIFIC CODE:
Here's what I ended up doing and worked perfectly. Thanks for the help.
function addArr(arr){
var val = 0;
for (var i = 0; i < arr.length; i++) {
val += parseFloat(arr[i].AdminHours || 0) + parseFloat(arr[i].FieldHours || 0) + parseFloat(arr[i].TravelHours || 0) + parseFloat(arr[i].OtherHours || 0);
//val += arr[i].AdminHours + arr[i].FieldHours + arr[i].TravelHours + arr[i].OtherHours;
}
$scope.totalHours = val;
}

Have a function on your controller that loops through the array and adds the values together, then return and value. Something like this
var addArr = function(arr){
var val = 0;
for(var i = 0; i < arr.length; i++){
val += arr[i];
}
return val;
}
$scope.val = addArr(theArray);
Here's what I ended up doing and worked perfectly. Thanks for the help.
function addArr(arr){
var val = 0;
for (var i = 0; i < arr.length; i++) {
val += parseFloat(arr[i].AdminHours || 0) + parseFloat(arr[i].FieldHours || 0) + parseFloat(arr[i].TravelHours || 0) + parseFloat(arr[i].OtherHours || 0);
//val += arr[i].AdminHours + arr[i].FieldHours + arr[i].TravelHours + arr[i].OtherHours;
}
$scope.totalHours = val;
}

Related

Add a column to a table with AngularJS

I tried to add a column if a button is pressed, but with no success.
I made a JSFiddle example with my problem.
I would be very thankful if someone could help me with this problem.
This is my try:
$scope.addValue = function() {
$scope.headers.push('new header');
var users = 5;
for(var i = 0; i < users; i++) {
var rowData = [];
for (var j = 0; j < 1; j++) {
rowData.push('data i=' + i + ' j=' + j)
}
$scope.data.push(rowData);
}
};
Here is a working example based on this JSFiddle.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.headers = [];
$scope.data = [];
$scope.colCount = 3;
var data = [];
// populate demo data
for (var i = 0; i < 10; i++) {
$scope.headers.push('Col ' + (i + 1));
var rowData = [];
for (var j = 0; j < 10; j++) {
rowData.push('Row-' + (i + 1) + ' - Col ' + (j + 1))
}
data.push(rowData);
}
$scope.increment = function(dir) {
(dir === 'up') ? $scope.colCount++: $scope.colCount--;
}
$scope.data = data;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<button ng-click="increment('up')">Add Column</button>
<button ng-click="increment('down')">Remove Column</button>
<table>
<tr>
<th ng-repeat="h in headers | limitTo: colCount">{{h}}</th>
</tr>
<tr ng-repeat="row in data">
<td ng-repeat="item in row | limitTo: colCount">{{item}}</td>
</tr>
</table>
</div>

How to create rows cell loop in js

I am trying to sum a table column total.
Here is an example of only two column for test purposes. I want to calculate table column's item total using a javascript loop.
How to create the loop if we don't know how many rows and columns are inside in table? I hope you understand what I mean and also hope for your kindly suggestion.
<p><b>Student at Stanford University 2013-2014</b></p>
<table><tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr></table>
<table id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
<tr><th>Engineering</th><td>8750</td><td>9863</td></tr>
<tr><th>Humanities & Sciences</th><td>7819</td><td>7219</td></tr>
<tr><th>Medicine</th><td>5219</td><td>4200</td></tr>
</table>
<button onclick="Calculate()">Calculate</button>
<div id="Studentf" class="Studentf"></div>
<div id="Students" class="Students"></div>
<div id="Studentt" class="Studentt"></div>
and
var ftable = document.getElementById("sdtable");
var i= 0;
var sumFirst=0;
var sumSecond=0;
var sumTotal=0;
function Calculate(){
for (i=0;i<ftable.rows.length; i++){
sumFirst=sumFirst+parseInt(ftable.rows[i].cells[1].innerHTML);
sumSecond=sumSecond+parseInt(ftable.rows[i].cells[2].innerHTML);
}
sumTotal=sumFirst+sumSecond;
document.getElementById("Studentf").innerHTML +="<b>Student in 2013 = </b>" +sumFirst;
document.getElementById("Students").innerHTML +="<b>Student in 2014 = </b>" +sumSecond;
document.getElementById("Studentt").innerHTML +="<b>Total Student = </b>" +sumTotal;
}
The key here is that you need to use cells collection to get number of columns that can change when you add new years to the table. You will also have to dynamically create elements for summary information per year.
Here is an example:
var ftable = document.getElementById("sdtable");
var i = 0;
var sumFirst = 0;
var sumSecond = 0;
var sumTotal = 0;
function Calculate() {
var rows = ftable.tBodies[0].rows,
header = ftable.tHead.rows[0],
cells = ftable.tBodies[0].rows[0].cells,
years = [];
for (var i = 0; i < rows.length; i++) {
for (var j = 1; j < cells.length; j++) {
if (!years[j]) years[j] = 0;
years[j] += parseInt(rows[i].cells[j].innerHTML);
}
}
sumTotal = years.reduce(function(prev, curr) {
return prev + curr;
}, 0);
var sum = document.getElementById("sum");
sum.innerHTML = '';
for (var j = 1; j < cells.length; j++) {
console.log(header.cells[j])
sum.insertAdjacentHTML('afterbegin', '<p><b>' + header.cells[j].innerHTML + '</b> = ' + years[j] + '</p>');
}
sum.insertAdjacentHTML('beforeend', "<b>Total Student = </b>" + sumTotal);
}
Demo: http://jsfiddle.net/x2sscpxL/1/
The table should probably look more like:
<table>
<thead>
<tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr>
</thead>
<tbody id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
...
</tbody>
<tfoot>
<tr><th>Totals:</th><th></th><th></th></tr>
</table>
to split the header, body and footer into separate table sections. The function should then be like:
function calculate(){
// Get a reference to the tBody
var tBody = document.getElementById('sdtable');
if (!tBody) return;
var row, rows = tBody.rows;
var cell, cells;
var cellTotals = {};
// For each row in the body
for (i=0, iLen=rows.length; i<iLen; i++) {
row = rows[i];
cells = row.cells;
// Add the cells in each column, starting on the second column
// i.e. starting with cell index 1
for (var j=1, jLen=cells.length; j<jLen; j++) {
cell = cells[j];
if (j in cellTotals) {
cellTotals[j] += Number(cell.textContent || cell.innerText);
} else {
cellTotals[j] = Number(cell.innerHTML);
}
}
}
// Write the totals into the footer
var tFoot = tBody.parentNode.tFoot;
row = tFoot.rows[0];
for (var k=1; k<jLen; k++) {
row.cells[k].innerHTML = cellTotals[k];
}
}
Note that by convention, variables with a name starting with a capital letter are reserved for constructors (though constants usually are all caps).
Here is calculation of table witn n rows and n columns
Note: header cells wrapped in thead section
var ftable = document.getElementById("sdtable");
var tbody = ftable.getElementsByTagName("tbody")[0]
var columnsCount = ftable.rows[0].cells.length;
var sumTotal = [];
for(i=0; i<columnsCount;i++)
sumTotal.push(0); //here initialize with zero
function Calculate(){
for (i=0;i<tbody.rows.length; i++){
for (j=0; j<columnsCount; j++)
if (tbody.rows[i].cells[j] && tbody.rows[i].cells[j].innerHTML)
sumTotal[j] += parseInt(tbody.rows[i].cells[j].innerHTML);
}
return sumTotal;
}
sumTotal = Calculate();
tfootrow = ftable.tFoot.rows[0];
console.log(tfootrow)
for(i=0; i<sumTotal.length; i++){
tfootrow.insertCell(i).innerHTML = sumTotal[i];
}
<table id="sdtable">
<thead>
<tr>
<th>Business</th>
<th>Earth Sciences</th>
<th>Education</th>
<th>Engineering</th>
<th>Humanities & Sciences</th>
<th>Medicine</th>
</tr>
</thead>
<tbody>
<tr><td>12922</td><td>11420</td></tr>
<tr><td>4320</td><td>4611</td></tr>
<tr><td>14560</td><td>13490</td></tr>
<tr><td>8750</td><td>9863</td></tr>
<tr><td>7819</td><td>7219</td></tr>
<tr><td>5219</td><td>4200</td></tr>
<tr><td></td><td>1</td><td>2</td></tr>
</tbody>
<tfoot>
<tr></tr>
</tfoot>
</table>

Child element is not getting selected in jquery

I have a gridview that is being rendered as follows
<table cellspacing="0" cellpadding="4" rules="cols" id="ContentPlaceHolder1_ucstockcount1_GridView1" style="color:Black;background-color:White;border-color:#DEDFDE;border-width:1px;border-style:None;width:100%;border-collapse:collapse;">
<tr style="color:White;background-color:#6B696B;font-weight:bold;">
<th scope="col">Sr.no</th><th scope="col">Style</th><th scope="col">Stk Last Mon</th><th scope="col">Stk Received</th><th scope="col">Stk This Mon</th><th scope="col">Change</th><th scope="col">Price</th><th scope="col">Value</th>
</tr><tr style="background-color:#F7F7DE;">
<td>1</td><td>T1-34H</td><td>0</td><td>0</td><td>
<input name="ctl00$ContentPlaceHolder1$ucstockcount1$GridView1$ctl02$TextBox2" type="text" id="ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_0" onblur="updatevals("ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_0",0,0,5.00,"ContentPlaceHolder1_ucstockcount1_GridView1_Label1_0","ContentPlaceHolder1_ucstockcount1_GridView1_Label2_0")" />
</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label1_0">0</span>
</td><td>5.00</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label2_0">0</span>
</td>
</tr><tr style="background-color:White;">
<td>2</td><td>T1-43B</td><td>0</td><td>0</td><td>
<input name="ctl00$ContentPlaceHolder1$ucstockcount1$GridView1$ctl03$TextBox2" type="text" id="ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_1" onblur="updatevals("ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_1",0,0,5.00,"ContentPlaceHolder1_ucstockcount1_GridView1_Label1_1","ContentPlaceHolder1_ucstockcount1_GridView1_Label2_1")" />
</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label1_1">0</span>
</td><td>5.00</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label2_1">0</span>
</td>
</tr>
I use the following code to extract values at client side.
function updatea(grid) {
$('#' + grid + ' tr').each(function (i) {
var style = "";
var lastmon = 0;
var received = 0;
var thismon = 0;
var change = 0;
var price = 0;
var value = 0;
$(this).children('td').each(function (j) {
if (j == 2) {
style = $(this).html();
} else if (j == 3) {
lastmon = $(this).html();
} else if (j == 4) {
received = $(this).html();
} else if (j == 5) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
// else if (j == 6) {
// change = $(this).children('span').val().trim();
// alert(change);
// }
// alert($(this).html());
});
});
}
Till 4th column I am able to get values as required but when i need to extract the value of a textbox that is inside the 5th column I get error TypeError: $(...).children(...).val(...) is undefined
I have taken the code from Traverse html table using jQuery
please help. Thankx
Two problems, the index starts from 0 so column with index 4 has input element, second the first row does not have input element
function updatea(grid) {
//start processing from row 1
$('#' + grid + ' tr').slice(1).each(function (i) {
var style = "";
var lastmon = 0;
var received = 0;
var thismon = 0;
var change = 0;
var price = 0;
var value = 0;
$(this).children('td').each(function (j) {
if (j == 1) {
style = $(this).html();
} else if (j == 2) {
lastmon = $(this).html();
} else if (j == 3) {
received = $(this).html();
//column 5 has index 4
} else if (j == 4) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
});
});
}
Demo: Fiddle
The index in each() is zero based, and the fifth TD doesn't have an input, the fourth has:
} else if (j == 4) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
You can make selections easier this way
$('#' + grid + ' tr').slice(1).each(function (i) {
var style = $('td:eq(1)', this).html();
var lastmon = $('td:eq(2)', this).html();
var received = $('td:eq(3)', this).html();
var thismon = $('td:eq(4) input', this).val();
}
+1 to #arun-p-johny for .slice(1)
Sometimes val() function didn't work for me in some conditions. You may test attr('value') instead of val() or you can change children() to $($(this).find('input')).val().trim() or $(this+'input').val().trim() or $(this).children().val().trim()
So I don't really remember right now but sometimes the returning object is not DOM Object.
Finally you can test $($(this).children('input')).val().trim().
As you can see there are too much moves to find anything. I just focused the main problem, so you need to test these and if any of them don't work, just tell me.
But I think the main problem is returning value is not DOM object. So it tries to reach non object and it gives error.

How to populate a table with vertical and horizontal results?

HeaderA HeaderB HeaderA HeaderB
stuff 232 hey 3434
world 033 boy 221
bat 435 girl 930
This table is dynamic and gets populated live. Here's my JS code, but the logic is not working correctly. I need to tell it that every 2 columns is a new record, and make a new row every 4th column. Here's what I have so far:
function html_data(data) {
var html = '';
$.each(data, function (index, value) {
if ((index+1) % 4 == 0 && index != 0) {
html += '<td>'+value+'</td>';
html += '</tr>'
} else if ((index+1) % 5 == 0) {
html += '<tr>';
html += '<td>'+value+'</td>';
} else {
html += '<td>'+value+'</td>';
}
html += '</tr>';
});
return html;
}
Obviously the above code is completely wrong, but that's all I have so far. If I can the get the mod logic, I can fill in the blanks.
Try this http://jsfiddle.net/G3JK5/
HTML
<table id="table">
<tr>
<th>HeaderA</th>
<th>HeaderB</th>
<th>HeaderA</th>
<th>HeaderB</th>
<th>HeaderA</th>
<th>HeaderB</th>
</tr>
</table>
<input type="button" id="btn" value="Add some random data" />
Javascript
//Sample usage
var tbl = new weirdTable('table');
document.getElementById('btn').addEventListener('click', function(){
tbl.addData([
parseInt(Math.random() * 100),
parseInt(Math.random() * 100)
]);
});
weirdTable
function weirdTable(tableId){
var _me = null;
var _currentIndex = 0;
var _colCount = 0;
var _lastRowIndex = 0;
var construct = function(tableId){
_me = document.getElementById(tableId);
_colCount = _me.rows[0].cells.length;
_currentIndex = _colCount;
};
this.addData = function(data){
var row = _me.rows[_lastRowIndex];
//or var data = arguments;
for(var i = 0; i < data.length; i++){
if(_currentIndex >= _colCount){
_lastRowIndex++;
_currentIndex = 0;
row = _me.insertRow(_lastRowIndex);
}
row.insertCell(_currentIndex).innerText = data[i];
_currentIndex++;
}
};
construct(tableId);
}
Unless I'm missing something, you can just do this:
if (index%4===0) { // start of a row
html += '<tr>';
}
html += '<td>'+value+'</td>';
if (index%4===3) { // end of row
html += '</tr>';
}

Find if a cell contents appears more than once

I have a table body that looks like the following:
<tbody>
<tr class="basket_main">
<td class="basket_item">
<input type="text" class="basket_qty_txt" id="ctl00_ctl00_main_body_content_main_content_area_shopping_basket_ctl01_txt_qty_162" value="3" name="ctl00$ctl00$main_body_content$main_content_area$shopping_basket$ctl01$txt_qty_162">
</td>
<td class="basket_item prod_code" id="ctl00_ctl00_main_body_content_main_content_area_shopping_basket_ctl01_prod_code_col">
CSM160
</td>
<td class="basket_item">
SIL.MTG:RENAULT R19 1988 ON
</td>
<td class="basket_item max_qty">
5
</td>
<td class="basket_item">
<input type="button" class="basket_item_button">
<input type="button" class="basket_item_button">
</td>
</tr>
</tbody>
There could be many rows in this table, what I'm trying to find out is if the prod_code appears in more than one row in the table using javascript or jquery.
Iterate through the table cells and collect the data.
Live demo http://jsfiddle.net/kEAzB/6/
var items = {};
$('tr td.basket_item.prod_code').each(function(){
var value = $(this).text();
if (items[value] == undefined) {
items[value] = 0;
}
items[value] += 1;
});
for (key in items) {
alert(key + ":" +items[key]);
}
You could scan all the table rows, store the product codes in an Associative Array (ie productCodes and check if the same product code is already defined.
var productCodesTds = document.getElementsByClassName("prod_code"),
productCodes = Object.create(null),
max,
i;
for (i = 0, max = productCodesTds; i < max; i += 1) {
productCode = productCodesTds[i].innerText;
if (productCode in productCodes) {
// the productCode is already defined in an other td
}
else {
productCodes['productCode'] = null;
}
}
push all the codes to array
var arr = new Array();
$('.prod_code').each(function(){
var prod_code = $(this).val();
arr.push(prod_code);
});
sort the array and check if there are duplicate values
var sorted_arr = arr.sort();
var results = [];
for (var i = 0; i < arr.length - 1; i += 1) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
alert("duplicate value"+sorted_arr[i + 1]);
}
}

Categories