Unable to read table td valued from HTML through jQuery selector - javascript

For creating table I am using ng-repeat to render table row. onchange of dropdown I am calling a function which will run have some conditions on basis of that condition I am pushing an object to an array which bind to a scope variable.
My HTML
<div class="col-md-12" >
<div class="portlet light" >
<div class="portlet-title">
<div class="caption">Installment Structure </div>
</div>
<div class="portlet-body">
<div class="row">
<div class="col-md-12">
<table id="instalmentStructure" class="table table-bordered">
<tbody>
<tr>
<th style="width:20%;">From Installment
</th>
<th style="width:20%;">To Installment</th>
<th style="width:20%;">Installment Amount
</th>
<th style="width:20%;"></th>
</tr>
<tr class="quoteVal" ng-repeat="item in installmentLists">
<td >{{item.fromInst}}</td>
<td >{{item.toInst}}</td>
<td contenteditable="true" class="quoteVal">{{item.amtInst}}</td>
<td>
<span class="col-md-6">
<center>
<a ng-click="editRecord(item,$index)">
<i class="fa fa-pencil"></i>
</a>
</center>
</span>
<span class="col-md-6">
<center>
<a ng-click="deleteRecord(item,$index)">
<i class="fa fa-trash"></i>
</a>
</center>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
My Controller Code:
$scope.createInstallments = function () {
console.log("will create installments");
if (trialCalculCntrl.emiCalQde.bulletFreq == 12) {
console.log("Bullet Frequency is Yearly");
var bulletFreq = trialCalculCntrl.emiCalQde.bulletFreq;
$scope.installmentLists = [];
$scope.installmentObj = {
'fromInst': "",
'toInst': "",
'amtInst': ""
};
var remainder = tenure % 12;
if (remainder == 0) {
var numofrows = ((tenure * 2) / 12).toFixed(0);
for (var i = 1; i <= numofrows; i++) {
if (i == 1) {
$scope.installmentObj = {
'fromInst': i,
'toInst': bulletFreq - 1,
'amtInst': ""
};
$scope.installmentLists.push($scope.installmentObj);
} else if (i % 2 == 0) {
console.log("EVEN i: ", i);
var preval = $('tr.quoteVal').eq(i - 2).find('td:eq(1)').text();
console.log("Previous Val ", preval);
} else {
console.log("ODD i: ", i);
// var preval = $('tr.quoteVal').eq(i-1).find('td:eq(2)').text();
// console.log("Previous Val ",preval);
}
}
console.log("Instalment list : ", $scope.installmentLists);
} else {
var numofrows = (((tenure * 2) / 12) + 1).toFixed(0);
for (var i = 0; i < numofrows; i++) {
$scope.installmentObj = {
'fromInst': "",
'toInst': "",
'amtInst': ""
};
$scope.installmentLists.push($scope.installmentObj);
}
console.log("Instalment list : ", $scope.installmentLists);
}
}
};
Inside for loop after first run I am pushing the object to $scope.installmentLists array but it is not showing in to HTML so I am not able to read the array object in second run of for loop. I am using jQuery selectors to read, so console.log("Previous Val ", preval); gives me an empty string.

Place your jquery about console.log in setTimeout when changed $scope. Otherwise the jquery selector does not return expected because the HTML has not been rendered.
setTimeout(function() {
onsole.log("EVEN i: ", i);
var preval = $('tr.quoteVal').eq(i - 2).find('td:eq(1)').text();
console.log("Previous Val ", preval);
}, 500);

Related

How to properly distribute js code for php foreach?

Have php foreach in file
<?php
foreach($_SESSION['cart'] as $item):
$sqlcartprod = mysqli_query(db(),"SELECT * FROM products WHERE id='".$item['product']."' ");
$rowcartprod = mysqli_fetch_array($sqlcartprod);
?>
<tr>
<td class="shoping__cart__item">
<img src="<?=$rowcartprod['ikonka']?>" width="101" alt="">
<h5><?=$rowcartprod['name_'.$lang]?></h5>
</td>
<td class="shoping__cart__price" >
<span id="priceprod"><?=$rowcartprod['price']?></span> azn
</td>
<td class="shoping__cart__quantity">
<div class="quantity">
<div class="pro-qty">
<input type="text" style="cursor: default" readonly value="<?=$item['qty']?>">
</div>
</div>
</td>
<td class="shoping__cart__total" id="totalprice">
<?=$item['price']*$item['qty']?> azn
</td>
</tr>
<?php endforeach; ?>
for this piece of code:
<div class="quantity">
<div class="pro-qty">
<input type="text" style="cursor: default" readonly value="<?=$item['qty']?>">
</div>
</div>
have JS code:
var proQty = $('.pro-qty');
proQty.prepend('<span class="dec qtybtn">-</span>');
proQty.append('<span class="inc qtybtn">+</span>');
proQty.on('click', '.qtybtn', function () {
var $button = $(this);
var oldValue = $button.parent().find('input').val();
if ($button.hasClass('inc')) {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 0) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 0;
}
}
$button.parent().find('input').val(newVal);
var Price = document.getElementById('priceprod').innerText;
var Tprice = document.getElementById('totalprice');
if (Price[i] > 0) {
Tprice.textContent = (Price[i] * newVal) + ' azn';
}
});
The issue is that when I click on qtybtn + or qtybtn -, the js code works only for the first product in the shopping list, even if there are 2,3 or more products in the list. I tried to separate inside the js code with loops, but then the js code somehow stops working at all. How to distribute correctly so that the js code works for each product separately?

How to calculate uptime from table data using JavaScript

I have table data for UP and DOWN counts and I want to calculate and display "uptime" as a percentage, for several targets within a the same table. Source counts have commas that must be removed, and I need to show the results to 3 decimal places (no rounding). Some targets begin with a number. The table itself is from an external source, displayed in an iFrame.
So far I have got the decimal places truncating, but I am looking for help parsing the table columns and rows to remove the commas and do the math.
(100 - (downCount / upCount * 100))
EDIT: The accepted answer changed this to:
(upCount / (upCount + downCount) * 100)
https://jsfiddle.net/ncarlton/d12ec7q3/1/
Vanilla JavaSript only please (no jQuery).
JavaScript Starter:
// these are the "correct" answers I'm trying to calculate from sourceTable data
let firstTargetCalc = (100 - (42 / 2218563 * 100));
let _2ndTargetCalc = (100 - (3 / 239384 * 100));
let thirdTargetCalc = (100 - (0 / 8340 * 100));
// this is how I want to truncate the decimals -- not rounding
function truncateDecimals(num, digits) {
var numS = num.toString(),
decPos = numS.indexOf('.'),
substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
trimmedResult = numS.substr(0, substrLength),
finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;
return parseFloat(finalResult);
}
// here's the "final" answers with the truncation
let trunc1st = truncateDecimals(firstTargetCalc, 4)
let trunc2nd = truncateDecimals(_2ndTargetCalc, 4)
let trunc3rd = truncateDecimals(thirdTargetCalc, 4)
// here's what I want to display to the end user as the calculated uptime for each target
// alert('firsttarget uptime: ' + trunc1st + '%\n2ndtarget uptime: ' + trunc2nd + '%\nthirdtarget uptime: ' + trunc3rd + '%');
The full HTML with a large extraneous <thead> is in the JSFiddle. But the important part might look like this in the <tbody> for three targets. The number of targets will vary but will usually be fewer than ten.
HTML:
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">firsttarget</td>
<td>UP</td>
<td class="numeric-value">2,218,563</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">firsttarget</td>
<td>DOWN</td>
<td class="numeric-value">42</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">2ndtarget</td>
<td>UP</td>
<td class="numeric-value">239,384</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">2ndtarget</td>
<td>DOWN</td>
<td class="numeric-value">3</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">thirdtarget</td>
<td>UP</td>
<td class="numeric-value">8,340</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">thirdtarget</td>
<td>DOWN</td>
<td class="numeric-value">0</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>```
[1]: https://i.stack.imgur.com/SNDdW.png
You can use regex to parse your table rather than iterating rows; your calculation to get the percentage is also incorrect. See snippet for working example.
function showTableData() {
const targetTable = document.getElementById('jstable'); // where to draw the new table
const sourceTable = document.querySelector(".table"); // set kibana as
const innerText = sourceTable.innerText;
const ups = innerText.match(/(\w*(target))\s*(UP)\s*[\d,]*\d(?! )/g);
const downs = innerText.match(/(\w*(target))\s*(DOWN)\s*[\d,]*\d(?! )/g);
let innerHTML = "";
for (let i = 0; i < ups.length; i++) {
const up = ups[i];
const down = downs[i];
const target = up.match(/(\w*(target))/)[0];
const upCount = parseInt(up.match(/[\d,]*\d$/)[0].replace(/,/g, ""));
const downCount = parseInt(down.match(/[\d,]*\d$/)[0].replace(/,/g, ""));
const percentage = (upCount / (upCount + downCount) * 100).toFixed(3)
innerHTML += `${target} uptime: ${percentage}%<br/><br/>`
}
targetTable.innerHTML = innerHTML;
}
// these are the "correct" answers I'm trying to calculate from sourceTable data
let firstTargetCalc = (100 - (42 / 2218563 * 100));
let _2ndTargetCalc = (100 - (3 / 239384 * 100));
let thirdTargetCalc = (100 - (0 / 8340 * 100));
// this is how I want to truncate the decimals -- not rounding
function truncateDecimals(num, digits) {
var numS = num.toString(),
decPos = numS.indexOf('.'),
substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
trimmedResult = numS.substr(0, substrLength),
finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;
return parseFloat(finalResult);
}
// here's the "final" answers with the truncation
let trunc1st = truncateDecimals(firstTargetCalc, 4)
let trunc2nd = truncateDecimals(_2ndTargetCalc, 4)
let trunc3rd = truncateDecimals(thirdTargetCalc, 4)
// here's what I want to display to the end user as the calculated uptime for each target
// alert('firsttarget uptime: ' + trunc1st + '%\n2ndtarget uptime: ' + trunc2nd + '%\nthirdtarget uptime: ' + trunc3rd + '%');
// this will eventually be run within the function to set the iFrame URL
// need to wait for the iFrame to load to get data for calculations
// for now we will present a button...
function showTableData() {
const targetTable = document.getElementById('jstable'); // where to draw the new table
const sourceTable = document.querySelector(".table"); // set kibana as
const innerText = sourceTable.innerText;
const ups = innerText.match(/(\w*(target))\s*(UP)\s*[\d,]*\d(?! )/g);
const downs = innerText.match(/(\w*(target))\s*(DOWN)\s*[\d,]*\d(?! )/g);
let innerHTML = "";
for (let i = 0; i < ups.length; i++) {
const up = ups[i];
const down = downs[i];
const target = up.match(/(\w*(target))/)[0];
const upCount = parseInt(up.match(/[\d,]*\d$/)[0].replace(/,/g, ""));
const downCount = parseInt(down.match(/[\d,]*\d$/)[0].replace(/,/g, ""));
const percentage = (upCount / (upCount + downCount) * 100).toFixed(3)
innerHTML += `${target} uptime: ${percentage}%<br/><br/>`
}
targetTable.innerHTML = innerHTML;
}
/*
function showTableData() {
document.getElementById('jstable').innerHTML = ""; // where to draw the new table
let sourceTable = document.querySelector(".table"); // set "source" table
for (var i = 0, row; row = sourceTable.rows[i]; i++) {
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
for (var j = 0, col; col = row.cells[j]; j++) {
//iterate through columns
//columns would be accessed using the "col" variable assigned in the for loop
}
}
}
/*calc.prototype.toFixedDown = function(digits) {
var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
m = this.toString().match(re);
return m ? parseFloat(m[1]) : this.valueOf();
};*/
/*
// rounding function
function roundTo(n, digits) {
var negative = false;
if (digits === undefined) {
digits = 0;
}
if( n < 0) {
negative = true;
n = n * -1;
}
var multiplicator = Math.pow(10, digits);
n = parseFloat((n * multiplicator).toFixed(11));
n = (Math.round(n) / multiplicator).toFixed(2);
if( negative ) {
n = (n * -1).toFixed(2);
}
return n;
}
// set the vars
/*let uptimeCells = document.querySelectorAll("td");
for (let i = 0; i < uptimeCells.length; i+=3) {
let uptimeTarget = uptimeCells[i].firstChild.data;
let uptimeFilter = uptimeCells[i + 1].firstChild.data;
let uptimeCount = uptimeCells[i + 2].firstChild.data;
console.log(uptimeTarget, uptimeFilter, uptimeCount);
}
// if () {
// }
return `<p>${this.targetName} ${this.calculatedUptime}</p>`;*/
<body>
<div class="rebuild-table">
<p><input type="button" id="bt" value="Show Rebuilt Table" onclick="showTableData()" /></p>
<p id="jstable"></p>
<h1>
Expected Results
</h1>
<div id=results>
<p>
firsttarget uptime: 99.998%
<!--(100-((42/2218563)*100))-->
</p>
<p>
2ndtarget uptime: 99.999%
<!--(100-((3/239384)*100)) rounded up from 99.9987..-->
</p>
<p>
thirdtarget uptime: 100.000%
<!--(100-((0/8340)*100))-->
</p>
</div>
</div>
<div>
<h1>
Data
</h1>
<!--THE TABLE BELOW IS PRESENTED WITHIN AN IFRAME BUT FOR THE JSFIDDLEWE WILL COMMENT OUT THE IFRAME ELEMENT
<iframe id="iframeURL">-->
<table class="table table-condensed">
<thead>
<tr>
<!-- ngRepeat: col in ::columns -->
<th ng-repeat="col in ::columns" ng-click="paginatedTable.sortColumn($index)" class="">
<span ng-bind="::col.title" class="ng-binding">targets</span>
<!-- ngIf: col.info -->
<!-- ngIf: col.sortable !== false --><i ng-if="col.sortable !== false" class="fa ng-scope fa-sort" ng-class="{
'fa-sort-asc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'asc',
'fa-sort-desc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'desc',
'fa-sort': paginatedTable.sort.columnIndex !== $index || paginatedTable.sort.direction === null
}">
</i>
<!-- end ngIf: col.sortable !== false -->
<!-- ngIf: col.filterable --><i aria-label="Click on a cell to filter" ng-if="col.filterable" class="fa fa-search ng-scope" ng-click="$event.stopPropagation()" tooltip="Click on a cell to filter"></i>
<!-- end ngIf: col.filterable -->
</th>
<!-- end ngRepeat: col in ::columns -->
<th ng-repeat="col in ::columns" ng-click="paginatedTable.sortColumn($index)" class="">
<span ng-bind="::col.title" class="ng-binding">filters</span>
<!-- ngIf: col.info -->
<!-- ngIf: col.sortable !== false --><i ng-if="col.sortable !== false" class="fa ng-scope fa-sort" ng-class="{
'fa-sort-asc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'asc',
'fa-sort-desc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'desc',
'fa-sort': paginatedTable.sort.columnIndex !== $index || paginatedTable.sort.direction === null
}">
</i>
<!-- end ngIf: col.sortable !== false -->
<!-- ngIf: col.filterable -->
</th>
<!-- end ngRepeat: col in ::columns -->
<th ng-repeat="col in ::columns" ng-click="paginatedTable.sortColumn($index)" class="visualize-table-right">
<span ng-bind="::col.title" class="ng-binding">Count</span>
<!-- ngIf: col.info -->
<!-- ngIf: col.sortable !== false --><i ng-if="col.sortable !== false" class="fa ng-scope fa-sort" ng-class="{
'fa-sort-asc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'asc',
'fa-sort-desc': paginatedTable.sort.columnIndex === $index && paginatedTable.sort.direction === 'desc',
'fa-sort': paginatedTable.sort.columnIndex !== $index || paginatedTable.sort.direction === null
}">
</i>
<!-- end ngIf: col.sortable !== false -->
<!-- ngIf: col.filterable -->
</th>
<!-- end ngRepeat: col in ::columns -->
</tr>
</thead>
<tbody kbn-rows="page" kbn-rows-min="perPage">
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">firsttarget</td>
<td>UP</td>
<td class="numeric-value">2,218,563</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">firsttarget</td>
<td>DOWN</td>
<td class="numeric-value">42</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">2ndtarget</td>
<td>UP</td>
<td class="numeric-value">239,384</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">2ndtarget</td>
<td>DOWN</td>
<td class="numeric-value">3</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">thirdtarget</td>
<td>UP</td>
<td class="numeric-value">8,340</td>
</tr>
<tr>
<td class="cell-hover ng-scope" ng-click="clickHandler($event)">thirdtarget</td>
<td>DOWN</td>
<td class="numeric-value">0</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
</div>
<!--</iframe>-->
<p>
Notes: some targets begin with numbers. The final implementation will have various numbers of targets to calculate. Cannot change the table itself, other than the names of the UP and DOWN filters (e.g., cannot add id="" to any table elements because it's
generated externally). The entire 'thead' element is not important to this project.</p>
</body>

How to keep the drop down list selection after web page refresh using Angularjs

I am writing and application using AngularJs, HTML and PHP. In the application I have a dropdown list, which when an option is selected a table is populated with related data drawn from a database. I can add to or delete info from the table. That works perfectly. However, the challenge I have is that each time the table is edited, the web page refreshes/route is reloaded and the drop down list returns to its default value. The effect of this is the user having to manually reselect the dropdown list value to carryout each operation on the table.
How can I alter the code to keep/persist the last selected option value and have the said dropdown list option selected when the webpage/route reloads?
I have seen many help responses to setting initial default value for dropdown lists. However that is not what I am trying to achieve. I am trying to set the post reload value or value after the webpage reloads.
Below is a part of what I have tried. I am at my whits end trying to figure it out. Any help is appreciated.
EDIT
Problem Solved
HTML before changes
<select id="b_year" ng-options="b.year for b in budgets track by b.year" ng-model="b.selectedBudget" ng-change="getBudgetItems(b.selectedBudget.year)" required><option value="">-- Choose budget year --</option></select>
HTML with solution changes
<select id="b_year" ng-options="b.year for b in budgets" ng-model="b.selectedBudget" ng-init="b.selectedBudget" ng-selected="getBudgetItems(b.selectedBudget.year)" required><option value="">-- Choose budget year --</option></select>
Controller snippet before changes
$scope.reloadRoute();
$scope.items.push({'line_item': li.line_item, 'weight': li.weight, 'allocated': li.allocated});
localStorage['b_year'] = year; //Store the selected year in local storage for later use
budget_size = server.getBudgetSize();
for(var i = 0; i < budget_size; i++){
if($scope.budgets[i].year === localStorage['b_year']){
$scope.b.selectedBudget[i] = localStorage['b_year'];
}else{
}
}
Controller with solution changes
app.controller(.... {
....
(function(){
$http.get( //Get info on budgets
"http://localhost/TrGway/getbudgetinfo.php"
)
.success(function(data){
$scope.budgets = data.budgets;
for(var i = 0; i < data.budgets.length; i++){
if($scope.budgets[i].year === selectedYear){
$scope.b = {};
$scope.b.selectedBudget = $scope.budgets[i];
}
}
})
.error(function(data){
$scope.message = "Error!! Getting Budget Info Failed: " + data;
});
})();
....
$scope.$watch("b.selectedBudget.year", function(item) {
localStorage.setItem("selectedYear", item);
});
});
App.controller('budgetCtrl', ['$scope', '$http', '$location', '$window', '$route', 'BudgetService', function($scope, $http, $location, $window, $route, BudgetService){
(function(){
$http.get( //Get info on budgets
"http://localhost/TrGway/getbudgetinfo.php"
)
.success(function(data){
server.setBudgets(data.budgets);//Set the budget info in the BudgetService for
//later usage anywhere in the program;
$scope.budgets = data.budgets;
budget_size = server.getBudgetSize();
server.getBudgetInfo();
})
.error(function(data){
$scope.message = "Error!! Getting Budget Info Failed: " + data;
});
})();
(function(){ //Get Line Items Info to populate the table
$http.get(
"http://localhost/TrGway/lineItemInfo.php"
)
.success(function(data){
server.setLineItems(data.items);
$scope.items = data.items;
server.getLineItemsInfo();
})
.error(function(data){
$scope.message = "Error!! Getting Line Items Info Failed: "+data;
});
})();
$scope.addBudget = function(budget){
if( budget.year < new Date().getFullYear() ){
alert("Budgets cannot be created retroactively.\n\
\nPlease enter a budget year greater than "+ new Date().getFullYear() );
$scope.budget.year = "";
}else{
server.addBudget(budget);
server.getBudgetInfo();
$scope.budgets = server.getBudgets();
$scope.budget = {};//Clear the add budget form
}
};
$scope.getBudgetItems = function(year){
/*This is where info on the budget for the selected year is retrieved and passed to the table
This works great every time*/
if( year === undefined ){ //If no year is selected do nothing
$scope.budget_amount = 0;
$scope.budget_amount_used = 0;
$scope.budget_amount_remaining = 0;
}else{
Budgets = server.getBudgets();
budget_size = server.getBudgetSize();
for(var i = 0; i < budget_size; i++){
if(Budgets[i].year === year){
$scope.budget_amount = Budgets[i].starting_amount;
$scope.budget_amount_used = Budgets[i].amount_used;
$scope.budget_amount_remaining = Budgets[i].running_balance;
amount_remaining = Budgets[i].starting_amount - Budgets[i].amount_used;
percent_used += (Budgets[i].amount_used / Budgets[i].starting_amount * 100);
server.setSelectedBudget(Budgets[i]);
}else{
//$scope.budget_amount = 0;
}
}
server.setPercentUsed(percent_used);
server.setPercentRemaining( 100 - percent_used);
server.setAmountRemaining(amount_remaining);
}
};
/*======================= THIS IS WHERE THE CHALLENGE IS ====================*/
$scope.addLineItem = function(li, b){
/*This is where the List items are added to the table before page reload*/
if(($scope.budget_amount_used-0 + li.allocated-0) > $scope.budget_amount){
alert("Budgeted amount exceeded!!!\nPlease consider revising");
$location.path('editbudget');
$scope.li.weight = 0;
$scope.li.allocation = 0;
}else{
server.setSelectedBudgetYear(b.selectedBudget.year); //Save selected year to a variable
server.addLineItem(li, b); //Add the new Line items row to database
$scope.reloadRoute();
$scope.items.push({'line_item': li.line_item, 'weight': li.weight, 'allocated': li.allocated});
$scope.b = {};
//$scope.b.selectedBudget = localStorage.getItem("selected");
$scope.$watch("b.selectedBudget.year", function(item) {
localStorage.setItem("selected", item);
});
//$scope.b.selectedBudget.year = server.getSelectedBudgetYear(); //I tried this also
}
$scope.li.line_item = "";
$scope.li.weight = 0;
$scope.li.allocation = 0;
$scope.b.selectedBudget = localStorage.getItem("selected");
/* LEAVING THIS SO YOU CAN SEE WHAT ELSE I HAVE TRIED
$scope.b = {};
$scope.b.selectedBudget = localStorage.getItem("selectedBudget");
$scope.watch("b.selected", function(item) {
localStorage.setItem("selected", item);
});
$scope.b.selectedBudget = localStorage['b_year'];
*/
/* LEAVING THIS SO YOU CAN SEE WHAT ELSE I HAVE TRIED
budget_size = server.getBudgetSize();
for(var i = 0; i < budget_size; i++){
if($scope.budgets[i].year === server.getSelectedBudgetYear()){
$scope.b.selectedBudget.year = server.getSelectedBudgetYear();
}else{
}
}*/
};
$scope.deleteLineItem = function(row, b){
$http({
method: "post",
url: "http://localhost/TrGway/deleteLineItem.php",
crossDomain: true,
data:{
'seq': row.seq,
'year': row.year,
'allocated':row.allocated,
'starting_amount': b.selectedBudget.starting_amount,
'amount_used': b.selectedBudget.amount_used,
'running_balance': b.selectedBudget.running_balance
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(response){
if(response.toString() === "success"){
var index = -1;
var itemsArr = eval( $scope.items );
for( var i = 0; i < itemsArr.length; i++ ) {
if( itemsArr[i].seq === row.seq ) {
index = i;
break;
}
}
if( index === -1 ) {
alert( "Something has gone wrong!!\nLine item was not deleted.\nPlease try again" );
}
server.reset();
server.reload();
$scope.budget_percent_used = server.getPercentUsed()-0;
$scope.budget_percent_remaining = server.getPercentRemaining()-0;
$scope.budget_amount_used = server.getAmountUsed()-0;
$scope.budget_amount_remaining = server.getAmountRemaining()-0;
server.setTotalWeighting($scope.totalweighting + row.weight)-0;
server.setPercentUsed(server.getTotalWeighting())-0;
server.setPercentRemaining(100 - server.getPercentUsed())-0;
$scope.items.splice( index, 1 ); //Remove the row with matching index/seq value
$scope.totalweighting = server.getTotalWeighting();
$scope.budget_percent_used = server.getPercentUsed()-0;
$scope.budget_percent_remaining = server.getPercentRemaining()-0;*/
$scope.reloadRoute();
}else{ //If deleting the line item failed
$location.path('editbudget');
$scope.budgetmessage = "Line Item Update Failed: "+response;
}
})
.error(function(response){ //If there was an error connecting to the server
$scope.budgetmessage = "Error!! Updating Line Item Failed: "+response;
});
row.isEditing = false;
};
$scope.updateLineItem = function(row){
$http({
method: "post",
url: "http://localhost/TrGway/updateLineItem.php",
crossDomain: true,
data:{
'seq': row.seq,
'line_item': row.line_item,
'weight': row.weight,
'allocated': row.allocated
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(response){
if(response.toString() === "success"){
$location.path('editbudget');
}else{
$location.path('editbudget');
$scope.budgetmessage = "Line Item Update Failed: "+response;
}
})
.error(function(response){
$scope.budgetmessage = "Error!! Updating Line Item Failed: "+response;
});
row.isEditing = false;
};
$scope.cancelLineItemEditing = function(row){
row.isEditing = false;
};
$scope.updateBudget = function(b){
$http({
method: "post",
url: "http://localhost/TrGway/updatebudget.php",
crossDomain: true,
data:{
'year': b.selectedBudget.year,
'starting_amount': b.edit_starting_amount
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(response){
if(response.toString() === "success"){
server.setStartingAmount(b.edit_starting_amount);
var line_items = server.getLineItems();
var start_amount = server.getStartingAmount();
var total_weight = 0;
var amount_used = 0;
var amount_remaining = 0;
var percent_used = 0;
var percent_remaining = 0;
for(var i = 0; i < line_items.length; i++){
//Update the line items on the page immediately
line_items[i].weight = ( line_items[i].allocated / start_amount) * 100;
total_weight += line_items[i].weight;
amount_used += line_items[i].allocated-0;
//Update the line items in the database immediately
$scope.updateLineItem(line_items[i]);
}
server.load();
percent_used = ( amount_used / start_amount) * 100;
amount_remaining = start_amount - amount_used;
percent_remaining = 100 - percent_used;
server.setLineItems(line_items);
server.setTotalWeighting(total_weight);
server.setAmountUsed(amount_used);
server.setPercentUsed(percent_used);
server.setAmountRemaining(amount_remaining);
server.setPercentRemaining(percent_remaining);
$scope.items = server.getLineItems();
$scope.total = 0;
$scope.total = server.getStartingAmount();
$scope.totalweighting = server.getTotalWeighting()-0;
$scope.budget_amount_used = server.getAmountUsed()-0;
$scope.budget_percent_used = server.getPercentUsed()-0;
$scope.budget_percent_remaining = server.getPercentRemaining()-0;
$scope.budget_amount_remaining = server.getAmountRemaining()-0;
$location.path('editbudget');
}else{
$location.path('editbudget');
$scope.budgetmessage = "Budget Update Failed: "+response;
}
})
.error(function(response){
$scope.budgetmessage = "Error!! Updating Budget Failed: "+response;
});
$scope.b = {};
};
$scope.reloadRoute = function(){
$route.reload();
server.reload();
//alert('Loaded!!');
};
}]);
<div class="breadcrumbs" id="breadcrumbs">
<ul class="breadcrumb">
<li>Home</li>
<li class="active">Add/Edit line Items</li>
<li style="float: right" ng-controller="authCtrl"><a ng-click="logout();">Logout</a></li>
<li style="float: right">Back</li>
</ul>
</div>
<div class="row" ng-cloak="" ng-controller="budgetCtrl">
<div class="col-md-5">
<section>
<form name="LineItemForm" class="form-horizontal" role="form">
<fieldset>
<table class="table table-striped">
<thead>
<tr>
<th style="width: 150px" colspan="1">Select Budget Year To Edit Line Items</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">
<div class="col-md-7">
<!-- THIS IS WHERE THE YEAR IS SELECTED -->
<select id="b_year" ng-options="b.year for b in budgets track by b.year" ng-model="b.selectedBudget" ng-change="getBudgetItems(b.selectedBudget.year);" ng-selected="" required>
<option value="">-- Choose budget year --</option>
</select>
</div>
</td>
</tr>
<tr>
<th style="width: 150px" colspan="1">{{b.budgetmessage}}</th>
</tr>
<tr>
<td>
<h3>Add Line Item Here</h3>
<div class="form-group">
<label class="col-md-3 control-label no-padding-right" for="line_item">Line Item</label>
<div class="col-md-7">
<input type="text" class="form-control" name="line_item" id="line_item" ng-model="li.line_item" ng-disabled="!b.selectedBudget" required/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label no-padding-right" for="weight">weighting %</label>
<div class="col-md-7">
<input type="number:2" class="form-control" name="weight" id="weight" ng-init="li.weight = 0" ng-model="li.weight" ng-disabled="!b.selectedBudget || !li.line_item || li.line_item.length<5" required/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label no-padding-right" for="allocated">Allocated $</label>
<div class="col-md-7">
<input type="number:2" class="form-control" name="allocated" id="allocated" placeholder="{{li.allocated = (budget_amount * li.weight) / 100 | currency}}" ng-init="li.allocated=0" ng-model="li.allocated" ng-disabled="!b.selectedBudget || !li.weight" required />
</div>
</div>
<div class="form-group" style="padding-right: 100px;">
<span class="lbl col-sm-5"> </span>
<div class="col-md-7 message" >
<span id="message" class="block input-icon input-icon-right">{{message}}</span>
</div>
</div>
<div class="form-group">
<div style="padding-right:100px">
<button type="submit" class="width-35 pull-right btn btn-sm btn-primary" ng-click="addLineItem(li, b)" data-ng-disabled="LineItemForm.$invalid || li.weight===0 || li.line_item.length < 5">
Add Line Item
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</fieldset>
</form>
</section>
</div>
<div>
<section>
<div class="col-lg-14" style="float: right">
<form>
<fieldset>
<table class="table table-striped" >
<thead>
<tr>
<!--<th>Index</th>-->
<th>Line Items</th><th style="width: 150px">% Weighting</th><th style="width: 150px">Allocation $</th><th style="width: 120px">Tasks</th><!---->
</tr>
</thead>
<tbody>
<tr data-ng-repeat="row in items" ng-model="items" ng-if="row.year === b.selectedBudget.year"><!--<td>{{$index+1}}</td>-->
<td title="'Line Item'" ng-switch="row.isEditing" ng-class="line_item.$dirty ? 'bg-warning' : ''" ng-form="name" demo-tracked-table-cell>
<span ng-switch-default class="editable-text">{{row.line_item}}</span>
<div class="controls" ng-class="line_item.$invalid && line_item.$dirty ? 'has-error' : ''" ng-switch-when="true">
<input type="text" name="line_item" ng-model="row.line_item" class="editable-input form-control input-sm" required />
</div>
</td>
<td>{{ row.weight = row.allocated / budget_amount * 100 | number: 2 }}</td>
<td title="'Allocation'" ng-switch="row.isEditing" ng-class="allocated.$dirty ? 'bg-warning' : ''" ng-form="allocated" demo-tracked-table-cell>
<span ng-switch-default class="editable-text">{{ row.allocated | currency }}</span>
<div class="controls" ng-class="allocated.$invalid && allocated.$dirty ? 'has-error' : ''" ng-switch-when="true">
<input type="text" name="allocated" ng-model="row.allocated" class="editable-input form-control input-sm" required/>
</div>
</td>
<td>
<button class="btn btn-primary btn-sm" ng-click="updateLineItem(row)" ng-if="row.isEditing" ng-disabled="rowForm.$pristine || rowForm.$invalid"><span class="glyphicon glyphicon-ok"></span></button>
<button class="btn btn-default btn-sm" ng-click="cancelLineItemEditing(row)" ng-if="row.isEditing"><span class="glyphicon glyphicon-remove"></span></button>
<button class="btn btn-default btn-sm" ng-click="row.isEditing = true" ng-if="!row.isEditing"><span class="glyphicon glyphicon-pencil"></span></button>
<button class="btn btn-danger btn-sm" ng-click="deleteLineItem(row, b)" ng-if="!row.isEditing"><span class="glyphicon glyphicon-trash"></span></button>
</td>
</tr>
<tr>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>TOTAL (Budget Estimate)</b>
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>{{ totalweighting = budget_amount > 0 ? 100 : 0 | number:2 }}%</b><!---->
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>{{ budget_amount | currency }}</b>
</span>
</h5>
</td><td></td>
</tr>
<tr>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>BUDGET AMOUNT USED</b>
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>{{ budget_percent_used = budget_amount_used > 0 ? budget_amount_used * 100/budget_amount : 0 | number:2 }}%</b>
<!--Adding the -0 forces the compiler to treat the value as a number-->
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<!--{{ budget_amount_used + li.allocated | currency }}-->
<b>{{ budget_amount_used | currency }}</b>
</span>
</h5>
</td><td></td>
</tr>
<tr>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>BUDGETED AMOUNT REMAINING</b>
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<b>{{ budget_percent_remaining = 100 - budget_percent_used | number:2 }}%</b>
<!--Adding the -0 forces the compiler to treat the value as a number-->
</span>
</h5>
</td>
<td>
<h5>
<span class="block input-icon input-icon-right">
<!--{{ budget_amount_remaining - li.allocated | currency }}-->
<b>{{ budget_amount_remaining | currency }}</b>
</span>
</h5>
</td><td></td>
</tr>
</tbody>
</table>
</fieldset>
</form>
</div>
</section>
</div>
</div>
I'd do something like this:
app.controller(.... {
....
$scope.b = {};
$scope.b.selected = localStorage.getItem("selected");
$scope.watch("b.selected", function(item) {
localStorage.setItem("selected", item);
});
....
});
EDIT
So we suspect that the initial value gets overwritten somewhere. Here is some help how to debug it: You can define a property setter on $scope.b, that could alert or break to debugger. Use something like this:
$scope.b = {
set selectedBudget(v) {
debugger;
// or alert(1);
}
};
Solution
This is the solution I came up with to keep the drop down list selection after webpage refresh. I hope this will help someone. I have added comments to help explain what I did. I hope they are clear. However, I welcome any correction or clarification. I was able to come up with this solution , thanks to help from #Tamas Hegedus, who pointed me in the right direction.
app.controller(.... {
....
(function(){
$http.get( //Get info on budgets
"http://localhost/TrGway/getbudgetinfo.php"
)
.success(function(data){
$scope.budgets = data.budgets; //assign array of elements to the scope variable
for(var i = 0; i < data.budgets.length; i++){ //Loop through each array element
if($scope.budgets[i].year === selectedYear){ //Check if any of the 'year' value in the array match the value stored in localStorage
$scope.b = {}; //reset the selected scope variable
$scope.b.selectedBudget = $scope.budgets[i]; //Assign the array element with the matching year, as the selected scope element
}
}
})
.error(function(data){
$scope.message = "Error!! Getting Budget Info Failed: " + data;
});
})();
....
$scope.$watch("b.selectedBudget.year", function(item) { //Set watch on array element 'year' for changes/selection
localStorage.setItem("selectedYear", item); //When an element is selected from the drop down list, its value is stored in localStorage
});
});
<select id="b_year" ng-options="b.year for b in budgets" ng-model="b.selectedBudget" ng-selected="getBudgetItems(b.selectedBudget.year)" required><option value="">-- Choose budget year --</option></select>

How to select and deselect an div / button in angularJs?

I am trying to make items not in list but in div and if an item is clicked, the div will be in different colors and the item will be added into a column but if the item is clicked again, the item will changed to original color and in the column the item will be gone. I just can't think how to do it in angular way. I came to another option to be able to add in the column and to remove the item, there's a remove button but I am still curious how the select and deselect can be done.
This is what I have in my html (ignore my btn btn-primary classes I was using button to give it a try in the first place)
<!--Select App Features-->
<div class="panel-heading" ng-controller="FeaturesController as featuresCtrl">
<h1 class="text-center">App Features</h1>
<div class="text-center">
<div ng-repeat="app in featuresCtrl.apps" class="btn btn-primary platform-btn-style" ng-click="featuresCtrl.addPrices(app.name, app.price)">{{ app.name }}</div><br>
</div>
<div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Device Added</th>
<th>Device Price</th>
<th></th>
</tr>
</thead>
<tr ng-repeat="appList in featuresCtrl.listAppPrices">
<td>{{ appList.name }}</td>
<td>{{ appList.price }}</td>
<td><button class="btn btn-default" ng-click="featuresCtrl.remove($index)">Remove</button></td>
</tr>
</table>
<div>Total : {{ featuresCtrl.totalAppPrice() }}</div>
</div>
</div><!-- end select app features / FeaturesController-->
My controller in js
//Controller for app features
app.controller("FeaturesController", function(){
this.apps = features;
this.listAppPrices = [];
// add name and price into the new array which is used to show in the table
this.addPrices = function(name, price){
//Checks if the exact name, price property exists in the array and return boolean
var found = this.listAppPrices.some(function (e){
console.log(e.name);
return ((e.name === name) && (e.price === price)) ;
});
//If found not true then push the new values into the array
if(!found){
this.listAppPrices.push({name: name, price: price});
}
};
// adds all the prices of the array which gives the total
this.totalAppPrice = function(){
var total = 0;
for(var i = 0; i < this.listAppPrices.length; i++){
total += this.listAppPrices[i].price;
}
return total;
};
// remove the whole object in the array when remove is clicked
this.remove = function(index) {
this.listAppPrices.splice(index, 1);
};
});
I kind of having the idea of how this can be done but I just can't think of the code to write it.
P.S. the codes are simple, I just learned it in code school and wanted to created something for fun to educate myself. Thanks in advance people
angular.module("stack", [])
.controller("FeaturesController", function($scope) {
// this.apps = features;
this.listAppPrices = [];
this.apps = [{ "name": "a1", "price": "12" }, { "name": "a2", "price": "13" }, { "name": "a3", "price": "14" }];
$scope.dummyArray = [];
var f = 0,
x = 0,
rem = false;
this.setSelected = function(app, index) {
console.log("app ", app);
//remove an item
if (app.selected) {
console.log(" list ", $scope.dummyArray);
$scope.dummyArray.forEach(function(e, ind) {
if (e.name === app.name) {
console.log(ind, " e ", e);
rem = true;
$scope.dummyArray.splice(ind, 1);
}
});
console.log("dumm ", $scope.dummyArray);
this.listAppPrices = $scope.dummyArray;
} else {
rem = false;
}
//used to select a div and change its colour
app.selected ? app.selected = false : app.selected = true;
//add an item
if (!rem) {
if ($scope.dummyArray.length) {
$scope.dummyArray.forEach(function(each) {
console.log("each ");
if (each.name !== app.name) {
console.log("inside if ");
f = 1;
}
});
} else {
console.log("inside else ");
$scope.dummyArray.push(app);
}
if (f === 1) {
f = 0;
console.log("push");
$scope.dummyArray.push(app);
}
console.log(" list--> ", $scope.dummyArray.length);
this.listAppPrices = $scope.dummyArray;
}
}
});
.selected {
background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="stack">
<head>
<title>stack</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="panel-heading" ng-controller="FeaturesController as featuresCtrl">
<h1 class="text-center x">App Features</h1>
<div class="text-center">
<div ng-repeat="app in featuresCtrl.apps track by $index" class="btn btn-primary platform-btn-style" ng-click="featuresCtrl.setSelected(app,$index)" ng-class="{selected: app.selected}">{{ app.name }}</div>
<!-- <div ng-if="(c%2===0)" ng-repeat="app in featuresCtrl.apps" class="btn btn-primary platform-btn-style" ng-click="featuresCtrl.setSelected(app)">{{ app.name }}</div> -->
<br>
</div>
<div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Device Added</th>
<th>Device Price</th>
<th></th>
</tr>
</thead>
<tr ng-repeat="appList in featuresCtrl.listAppPrices">
<td>{{ appList.name }}</td>
<td>{{ appList.price }}</td>
<td>
<button class="btn btn-default" ng-click="featuresCtrl.remove($index)">Remove</button>
</td>
</tr>
</table>
<div>Total : {{ featuresCtrl.totalAppPrice() }}</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<script type="text/javascript" src="controller.js"></script>
</body>
</html>
I haven't added the functionality of remove button.I also haven't count the totalAppPrice. Otherwise your problem is solved :) .

jQuery post with ajax from variable number of input boxes

I am trying to pass user input for a variable number of inputs for two different fields back to the controller using jQuery post with ajax. I am having trouble getting more than just the first inputs. For example, if an employee is assigned multiple pieces of equipment, only the first one is passed to the controller.
In the View I am displaying each employee in a table with a button for each to open a modal where their individual equipment can be assigned. In each modal there are two text boxes (vehicles & tools) with the option for the user to add more of each using jQuery.
I am new to JS, and can't figure out how to determine how many inputs there are, and I don't know how to put these into an array to pass to the controller. Any help is very appreciated!
View:
#int count = 0;
#foreach (var item in Model)
{
<tr>
<td>
<button class="btn btn-default" data-toggle="modal" data-target="#modal-#count">
Assign Resources
</button>
<div class="modal fade" id="modal-#count" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">#item.Rank #item.FirstName #item.LastName</h4>
</div>
<div class="modal-body">
<input type="hidden" value="#item.assignedRosterID" id="assignedRosterID-#count" />
<div class="table">
<table>
<thead>
<tr>
<th class="text-center">
Vehicles
</th>
<th class="text-center">
Equipment
</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="middle">
<div class=”addV” id=”addV-#count”>
<p>
<input type="text" size="20" class="text-center" value="" id="vehicleNumber-#count" name=”vehicle” placeholder="Vehicle Number" />
</p>
</div>
</td>
<td valign="middle">
<div class="addEquip" id="addEquip-#count">
<p>
<input type="text" id="equipmentLabel-#count" size="20" class="text-center" name="equipment" value="" placeholder="Equipment Label" />
</p>
</div>
</td>
</tr>
<tr>
<td></td>
<td>
Add Additional Vehicle
</td>
<td>
Add Additional Equipment
</td>
</tr>
</tbody>
</table>
<span style="color: red"></span>
</div>
<div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="closeModal-#count">Close</button>
<button type="button" class="btn btn-primary" id="saveModal-#count">Save changes</button>
</div>
</div>
</div>
</div>
</td>
<td style="font-weight:bold">
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td style="font-weight:bold">
#Html.DisplayFor(modelItem => item.FirstName)
</td>
</tr>
count++;
}
JS
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
i
$('#saveModal-' + i).click(function () {
var DetailsVM = {
arID: $('#assignedRosterID-' + i).val(),
vehicleNumber: $('#vehicleNumber-' + i).val(),
equipmentLabel: $('#equipmentLabel-' + i).val()
}
$.ajax({
type: 'POST',
url: '/Rosters/SaveResources',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(DetailsVM),
traditional: true,
success: function (response) {
alert("Data Inserted Successfully!");
},
error: function (xhr, err) { alert(xhr.responseText) }
});
});
})(i);
};
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
$(function () {
var addDiv = $('#addV-' + i);
var j = $('#addV-' + i + 'p').size() + 1;
$(document).on('click', '#addVehicle + i, function () {
$('<p><input type="text" id="vehicle + i + '-' + j + '" size="20" name="vehicle + j + '" value="" placeholder=" Vehicle Number" /> Remove </p>').appendTo(addDiv);
j++;
return false;
});
$(document).on('click', '#remNew', function () {
if (j > 1) {
$(this).parents('p').remove();
j--;
//$("span").text("There are " + j + " equipment input boxes. ");
}
return false;
});
});
})(i);
};
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
$(function () {
var addDiv = $('#addEquip-' + i);
var j = $('#addEquip-' + i + 'p').size() + 1;
$(document).on('click', '#addEquipment-' + i, function () {
$('<p><input type="text" id="equipment-' + i + '-' + j + '" size="20" name="equipment_' + j + '" value="" placeholder=" Equipment Label " /> Remove </p>').appendTo(addDiv);
j++;
return false;
});
$(document).on('click', '#remNew', function () {
if (j > 1) {
$(this).parents('p').remove();
j--;
//$("span").text("There are " + j + " equipment input boxes. ");
}
return false;
});
});
})(i);
};
Model:
public class DetailsVM
{
public string arID { get; set; }
public string vehicleNumber { get; set; }
public string equipmentLabel { get; set; }
}
The logic for this is only setup to save one of each type since multiple is not working. When I put a break point on this and inspect VM it only contains the first values.
Controller:
public ActionResult SaveResources(DetailsVM VM)
{
int assignedRosterID = Int32.Parse(VM.arID);
int equipmentID = db.Equipments.Where(x => x.EquipmentLabel == VM.equipmentLabel).Select(x => x.EquipmentID).FirstOrDefault();
int vehicleID = db.Vehicles.Where(x => x.VehicleNumber == VM.vehicleNumber).Select(x => x.VehicleID).FirstOrDefault();
var tempEquipments = new TempEquipment();
tempEquipments.AssignedRosterID = assignedRosterID;
tempEquipments.EquipmentID = equipmentID;
db.TempEquipments.Add(tempEquipments);
var tempVehicles = new TempVehicle();
tempVehicles.AssignedRosterID = assignedRosterID;
tempVehicles.VehicleID = vehicleID;
db.TempVehicles.Add(tempVehicles);
db.SaveChanges();
return Json(1, JsonRequestBehavior.AllowGet);
}
you can set a class on the save-buttons and get the parent tr by
var tr = $(this).closest('tr')
so ... the arID would be like
tr.find('[name="arID"]')
wrap your first for in a function and make it global.
to make it globale, decline it above the for like
function bindClick() {}
then you will not need your for due to your class on the button.
in your bindClick you can go
$('.saveModal').each(function( ){
$(this).unbind('click').on('click, function(e){
e.preventDefault(); // do this if you dont want to do default action for this button .. like to submit a form
var tr = $(this).closest('tr') // get the parent of all inputs to search in this container
[native code] // var DetailsVM = {...
}
});
then change $('#assignedRosterID-' + i).val() to tr.find('.assignedRosterID').val()
Don't forget to add classes to the inputs! or find them by attribute name : tr.find('[name="your-field-name"]').val()
do the same with your other functions and trigger the bindClick in your function, where you add the new fields ;)

Categories

Resources