Get value from an input with Jquery - javascript

I have found a lot of answers to this type of question but none are solving the problem.
I even have a very similar piece of code that works. However, this keeps giving a NaN. I have narrowed it down to not being able to get the value of
var or = parseFloat($(this).siblings("input[name='or']").val());
Here is what I have.
Any help is greatly appreciated!
<tbody>
{% for i in t %}
<tr class="hotlines">
<td><strong>{{i.owner}}</strong><br>{{i.owner_id}}</td>
<td>
<li>{{i.tot_itm}}</li>
<li>Per Piece Profit: {{"${:,.2f}".format(i.item_prof)}}</li>
</td>
<td>
<li>Payable Hotlines <br><input type="text" name="hln" maxlength="4" value=""></li>
<li>Per Hotline Profit: {{"${:,.2f}".format(i.hotline_prof)}}</li>
<input type="text" name="or" value="{{i.hotline_prof}}">
</td>
<td>
<li>Total Backpack Profit: {{"${:,.2f}".format(i.tot_prof)}}</li>
<li>Total Hotline Profit: <input type="text" name="hlnt" readonly /></li>
</td>
</tr>
<!-- Total items sent from db -->
<input class="hidden" type="text" name="it" value="{{i.tot_itm}}">
<!-- per hotline override from db -->
<!-- profit from all items * per item override sent from server -->
<input class="hidden" type="text" name="bp" value="{{i.tot_prof}}">
<!-- total proffit from items and hotlines -->
<input class="hidden" type="text" name="th">
<!-- per item override from db -->
<input class="hidden" type="text" name="or_it" value="{{i.item_prof}}">
<!-- total proffit from hotlines -->
<input class="hidden" type="text" name="hl" value="0">
<!-- organization ID -->
<input class="hidden" type="text" name="o" value="{{org.organization_ID}}">
<input class="hidden" type="text" name="owner_n" value="{{i.owner}}">
<input class="hidden" type="text" name="owner_id" value="{{i.id}}">
{% endfor %}
<td><button type="submit" class="btn btn-link btn-xs btn-block">Submit Report</button></td>
</tbody>
AND
$(document).on("keyup", "[name='hln']", function () {
$this = $(this);
//var or = 0
var pro = 0
//using native dom Element.closest() method
//https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
let parent = $(this.closest('.hotlines'));
//or using jQuery's closest();
//let parent = $this.closest('.hotlines');
var value = parseFloat($this.val());
var or = parseFloat($(this).siblings("input[name='or']").val());
var bp = parseFloat($(this).siblings("input[name='bp']").val());
//var other = parseFloat($(this).siblings("input[name='amt']").val());
pro = (value * or);
var total = (pro + bp);
//use find() to find the child element
parent.find('input[name="hlnt"]').val("$" + pro.toFixed(2));
parent.find('input[name="total"]').val("$" + total.toFixed(2));
parent.find('input[name="th"]').val(total);
parent.find('input[name="hl"]').val(pro);
});

With the guidance from Tyler Roper it was a simple fix having nothing to do with Javascript.
I was tired and testing things and tried to quickly convert a page into a table.
The terrible HTML was the cause. To fix it I simply changed to:
<form action="/weekly_reports/" method="POST">
<table id="office_weekly" class="table table-hover table-striped">
<thead>
<th>Office</th>
<th>Backpacks</th>
<th>Hotlines</th>
<th>Total</th>
</thead>
<tbody>
{% for i in t %}
<tr class="hotlines">
<td><strong>{{i.owner}}</strong><br>{{i.owner_id}}</td>
<td>
{{i.tot_itm}}<br>
Per Piece Profit: {{"${:,.2f}".format(i.item_prof)}}
</td>
<td>
Payable Hotlines <br><input type="text" name="hln" maxlength="4" value=""><br>
Per Hotline Profit: {{"${:,.2f}".format(i.hotline_prof)}}<br>
<input type="hidden" name="or" value="{{i.hotline_prof}}">
</td>
<td>
Total Backpack Profit: {{"${:,.2f}".format(i.tot_prof)}}
</td>
<td>Total Hotline Profit: <input type="text" name="hlnt" readonly /></td>
</tr>
{% endfor %}
<td><button type="submit" class="btn btn-link btn-xs btn-block">Submit Report</button></td>
</tbody>
</table>
</form>

Related

Can Javascript be written in .edge file?

I just started learning Adonis.js and I would like to know if it's possible to write Javascript in an .edge file? I've found this tutorial (here) on how to add table row dynamically and I want to implement this in my Adonis.js project. I've add the coding inside a <script> tag, yet there's nothing happen when I clicked the 'Add' button. Does anyone know how to work this out? Or even have another solution on this?
Thank you in advance for the help.
#layout('main')
#section('content')
Go back
<hr>
<h1>Create Club</h1>
<form action="/clubs/create" method="POST">
{{ csrfField() }}
<div class="form-group">
<label>Club Name</label>
<input type="text" name="clubName" class="form-control" value="{{ old('clubName', '') }}">
{{ elIf('<span class="text-danger">$self</span>', getErrorFor('clubName'), hasErrorFor('clubName')) }}
</div>
<div class="form-group">
<label>Club Description</label>
<textarea name="clubDesc" class="form-control">{{ old('clubDesc', '') }}</textarea>
{{ elIf('<span class="text-danger">$self</span>', getErrorFor('clubDesc'), hasErrorFor('clubDesc')) }}
</div>
<br>
<table class="table order-list">
<thead>
<tr>
<td>Name</td>
<td>Position</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="text" name="memberName" class="form-control"/>
</td>
<td>
<input type="text" name="position" class="form-control"/>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<input type="button" class="btn btn-sm btn-block" id="addrow" value="Add Member"/>
</td>
</tr>
</tfoot>
</table>
<button class="btn btn-primary" type="submit">Create!</button>
</form>
<script>
$(document).ready(function () {
var counter = 0;
$("#addrow").on("click", function () {
var newRow = $("<tr>");
var cols = "";
cols += '<td><input type="text" class="form-control" name="memberName' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="position' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function (event) {
$(this).closest("tr").remove();
counter -= 1
});
});
function calculateRow(row) {
var price = +row.find('input[name^="price"]').val();
}
function calculateGrandTotal() {
var grandTotal = 0;
$("table.order-list").find('input[name^="price"]').each(function () {
grandTotal += +$(this).val();
});
$("#grandtotal").text(grandTotal.toFixed(2));
}
</script>
#endsection
From the docs:
in order to write raw HTML, you must wrap it inside {{{ }}}
That suggests that you should be able to do*:
{{{
<script>
// .. JavaScript here
</script>
}}}
*There may be other - potentially better, ways. I've never used the templating engine before, but the above seems to accomplish what you are looking for.

multi ng -repeat and remove rows in angular js

I'm new to AngularJs and I'm stuck in multi ng-repeat.
HTML CODE
<table class="table table-bordered tdPaddingNull verTop">
<thead>
<tr>
<th width="200px">Product Details </th>
<th width="250px">Current Availability</th>
<th width="200px">Batch </th>
<th>Quantity</th>
<th>Rate INR </th>
<th>Amt. INR</th>
<th>Converted Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(i,product) in listproducts track by $index">
<td style="padding: 7px;">
<input auto-complete ui-items="prductdetail" ng-model="formData.product_name[i]" class="form-control form-white" my-id="{{i}}"/>
<input id="product_id{{i}}" placeholder="productid" type="hidden" value="" ng-model="formData.product_id[i]" my-id="{{i}}"/>
<a ng-click="addProductBatch()" title="Add Another Batch Quantity" style="float:right;"><i class="fa fa-plus" aria-hidden="true"></i> ADD BATCH </a>
</td>
<td class="line-item-column item-currentavail transferorder-lineitem">
<div class="row text-muted font-sm">
<div class="col-md-6">
Source Stock
</div>
<div class="separationline col-md-6">
Destination Stock
</div>
</div>
<div class="row font-xs">
<div class="col-md-6">
0.00 Units
</div>
<div class="separationline col-md-6">
0.00 Units
</div>
</div>
</td>
<td style="padding: 7px;">
<div style="display:inline-block;width:100%;" ng-repeat="addBatch in listAddbatches">
<select class="form-control form-white selectNor" ng-model="formData.batch_id[i]" ng-change="changedBatchValue(formData.batch_id)" style="margin-bottom: 5px;width: 88%;float: left;">
<option value="">Select Batch</option>
<option value="{{blist.batch_id}}" ng-repeat="blist in batchList">{{blist.batch_number}}</option>
</select>
<a class="inputTabel1" ng-click="removeBatch($index)" title="Remove Batch" style="float:left;margin-left: 4px;"> <i class="fa fa-times-circle-o" aria-hidden="true" ></i>
</a>
</div>
</td>
<td style="padding: 7px;">
<input class="form-control form-white" type="text" value="" ng-model="formData.product_count[i]" ng-repeat="addBatch in listAddbatches" style="margin-bottom: 5px;"/>
</td>
<td style="padding: 7px;">
<input class="form-control form-white " placeholder="Selling Price" type="text" value="0.00" ng-model="formData.sel_inr_rate[i]">
</td>
<td>
<input class="form-control form-white form-Tabel" placeholder="Amount in INR" type="text" value="0.00" ng-model="formData.sel_inr_amount[i]" readonly />
</td>
<td class="Amount ">
<input class="form-control form-white form-Tabel" placeholder="" type="text" value="0.00" ng-model="formData.exc_total_amount[i]" readonly />
<button class="inputTabel" ng-click="removeProduct($index)"> <i class="fa fa-times-circle-o" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
ANGULAR CODE
/****************ADD ANOTHER BATCH QUANTITY**************/
$scope.addAnotherProduct = function(listproducts,$event) {
newItemNo = $scope.listproducts.length+1;
$scope.listproducts.push({'batch_id[newItemNo]':'','product_count[newItemNo]':''});
};
$scope.removeProduct = function(index) {
/*var lastItem = $scope.listproducts.length-1;
$scope.listproducts.splice(lastItem);
$scope.listAddbatches = '';*/
$scope.listproducts.splice(index,1);
};
$scope.removeBatch = function(index) {
/*var lastItem = $scope.listAddbatches.length-1;
$scope.listAddbatches.splice(lastItem);
$scope.listAddbatches = '';*/
$scope.listAddbatches.splice(index,1);
};
$scope.addProductBatch = function() {
var newItemNo = $scope.listAddbatches.length+1;
$scope.listAddbatches.push({'id':'batch'+newItemNo});
};
Here when I click ADD ANOTHER PRODUCT it should create an entire row in the table without the columns of Batch and Quantity, but now it's appearing as it in before row created.
Then when I click ADD BATCH it should create under the table column Batch and Quantity of the corresponding row, but now it's adding in all the rows and when I remove added batch, it should remove the corresponding batch, but now it's removing the last added batch.
The same happens when I remove added product (Entire Row), it should remove the corresponding row of the product but now it's removing lastly added Product row.
How can I fix all the aforementioned issues?
Please help me
There are multiple issues with your approach:
1) You are using a global array listAddbatches but you want to add the batches by product, so why shouldn't you use product.listAddbatches array?
2) When using track by $index you will not able to delete correct element from array or object since compiler directive is not re-compiling the element when its data attribute changes.
3) Using array length to generate id like var newItemNo = $scope.listAddbatches.length + 1; is not a good idea since the array length could change (when removing items) in a way that you will have the same ids for different elements.
4) This line is very strange {'batch_id[newItemNo]':'','product_count[newItemNo]':''}, since you are calculating newItemNo, but this is a simple string 'batch_id[newItemNo]'. Why do you need this?
5) Do not recommend to use $index to remove items, since it could point to some other element in case of filtering.
Your code could like this (simplified version), hope this helps:
angular.module('plunker', [])
.controller('MainCtrl', function($scope) {
$scope.listproducts = [];
$scope.addAnotherProduct = function(listproducts) {
listproducts.push( {
listAddbatches: []
});
};
$scope.removeProduct = function(product) {
var index = $scope.listproducts.indexOf(product);
if (index >= 0)
$scope.listproducts.splice(index, 1);
};
$scope.removeBatch = function(product, batch) {
var index = product.listAddbatches.indexOf(batch);
if (index >= 0)
product.listAddbatches.splice(index, 1);
};
$scope.addProductBatch = function(product) {
product.listAddbatches.push({ });
};
});
<script src="https://code.angularjs.org/1.6.4/angular.js" ></script>
<html ng-app="plunker">
<body ng-controller="MainCtrl">
<table class="table table-bordered tdPaddingNull verTop">
<thead>
<tr>
<th width="200px">Product Details </th>
<th width="250px">Current Availability</th>
<th width="200px">Batch </th>
<th>Quantity</th>
<th>Rate INR </th>
<th>Amt. INR</th>
<th>Converted Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(i, product) in listproducts">
<td style="padding: 7px;">
<input auto-complete ui-items="prductdetail" ng-model="formData.product_name[i]" class="form-control form-white" my-id="{{i}}"/>
<input id="product_id{{i}}" placeholder="productid" type="hidden" value="" ng-model="formData.product_id[i]" my-id="{{i}}"/>
<a ng-click="addProductBatch(product)" title="Add Another Batch Quantity" style="float:right;"><i class="fa fa-plus" aria-hidden="true"></i> ADD BATCH </a>
</td>
<td class="line-item-column item-currentavail transferorder-lineitem">
<div class="row text-muted font-sm">
<div class="col-md-6">
Source Stock
</div>
<div class="separationline col-md-6">
Destination Stock
</div>
</div>
<div class="row font-xs">
<div class="col-md-6">
0.00 Units
</div>
<div class="separationline col-md-6">
0.00 Units
</div>
</div>
</td>
<td style="padding: 7px;">
<div style="display:inline-block;width:100%;" ng-repeat="addBatch in product.listAddbatches">
<select class="form-control form-white selectNor" ng-model="formData.batch_id[i]" ng-change="changedBatchValue(formData.batch_id)" style="margin-bottom: 5px;width: 88%;float: left;">
<option value="">Select Batch</option>
<option value="{{blist.batch_id}}" ng-repeat="blist in batchList">{{blist.batch_number}}</option>
</select>
<a class="inputTabel1" ng-click="removeBatch(product, addBatch)" title="Remove Batch" style="float:left;margin-left: 4px;"> <i class="fa fa-times-circle-o" aria-hidden="true" ></i>
</a>
</div>
</td>
<td style="padding: 7px;">
<input class="form-control form-white" type="text" value="" ng-model="formData.product_count[i]" ng-repeat="addBatch in product.listAddbatches" style="margin-bottom: 5px;"/>
</td>
<td style="padding: 7px;">
<input class="form-control form-white " placeholder="Selling Price" type="text" value="0.00" ng-model="formData.sel_inr_rate[i]">
</td>
<td>
<input class="form-control form-white form-Tabel" placeholder="Amount in INR" type="text" value="0.00" ng-model="formData.sel_inr_amount[i]" readonly />
</td>
<td class="Amount ">
<input class="form-control form-white form-Tabel" placeholder="" type="text" value="0.00" ng-model="formData.exc_total_amount[i]" readonly />
<button class="inputTabel" ng-click="removeProduct(product)"> <i class="fa fa-times-circle-o" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
<button ng-click="addAnotherProduct(listproducts)">Add Another Product</button>
</body>
</html>

Make static functions to be dynamic

I am doing an exercise to learn JavaScript. I am having issues making my program dynamic. What I want to do here is:
Create two input to let the user set up the new product data.
Create a button. This button will have assigned a click event that will: 1- Get the data from the inputs. 2- Create a new product row with the data we stored.
Be able to delete all items and decrease total price based on the price of reminding item. In case there is no item, total price should be 0.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shoping</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/index.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<header>
<h1 class="h1 text-center mb">Shoping<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span></h1>
</header>
<table class="table mb">
<thead>
<tr>
<th>Products:</th>
<th>Price:</th>
<th>Quantity:</th>
<th>Total:</th>
<th>
</th>
</tr>
</thead>
<tbody id="soyTBody">
<tr id="itemSubject">
<th scope="row"><span id="productName">T-Shirts</span></th>
<td class="price1"> <span class="dolar">$</span><span id="product">15</span></td>
<td class="qty1">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem1">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<tr id="itemSubject2">
<th scope="row"><span id="productName">Stickers</span></th>
<td class="price2"> <span class="dolar">$</span><span id="product2">2</span></td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty2" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem2">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total2">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem2()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<!-- <tr>
<th scope="row">Stickers</th>
<td class="price2">$1</td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty2text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total-2">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
<!-- <tr>
<th scope="row">Flags</th>
<td class="price3">$2</td>
<td class="qty3"><form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty3text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total3">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
</tbody>
</table>
<div class="row text-right">
<button class="delate btn btn-success" onclick="getPrice();getPrice2();totalPrice2()" type="submit" value="calculatePriceButton" >
<input id ="calc-prices-button" class="calculator" type="button" value="Calculate Prices">
<!-- <span class="delateButton"><strong>Calculate Prices</strong></span> -->
</button>
</div>
<h2 class="text-center">Total Price: $<span id="totalPrice"></span></h2>
</div>
</body>
</html>
JS:
// qty
function getQty() {
var qty = document.querySelector("#qty").value;
document.querySelector("#total").innerHTML = qty;
return qty;
}
getQty();
// qty2
function getQty2() {
var qty2 = document.querySelector("#qty2").value;
document.querySelector("#total2").innerHTML = qty2;
return qty2;
}
getQty();
// Price
function getPrice() {
var price = parseInt(document.querySelector("#product").innerHTML);
document.querySelector("#total").innerHTML = price * getQty();
}
getPrice();
// Price 2
function getPrice2() {
var price2 = parseInt(document.querySelector("#product2").innerHTML);
document.querySelector("#total2").innerHTML = price2 * getQty2();
}
getPrice2();
// total Price
function totalPrice2() {
var total = parseInt(document.querySelector("#total").innerHTML);
var total2 = parseInt(document.querySelector("#total2").innerHTML);
document.querySelector("#totalPrice").innerHTML = total + total2;
}
totalPrice2();
//Romove Item
function removeItem() {
var remove = document.querySelector("#itemSubject").remove("itemSubject");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem();
function removeItem2() {
var remove = document.querySelector("#itemSubject2").remove("itemSubject2");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem2();
For your getPrice() and getPrice2() functions, we can make them dynamic by changing the following:
var price = parseInt(document.querySelector("#product").innerHTML);
and
var price2 = parseInt(document.querySelector("#product2").innerHTML);
These lines looks for elements with static names, instead we should give all inputs a common class name and loop through them. That way, we don't have to rely on static element IDs. For example, if we gave each input the class 'quantityinput', we can do the following:
var elements = document.getElementsByClassName("quantityinput");
for(var i=0; i<elements.length; i++) {
// Select this element and get its quantity
var this_total = elements[i].value;
// Get the price for this element by selecting the price td, then its second child
var this_price = elements[i].parentElement.parentElement.parentElement.previousSibling.childNodes[2].value;
// Select the total label for this row
var this_total_label = elements[i].parentElement.parentElement.parentElement.childNodes[1];
// Now update the total label for this row by multiplying the price and the quantity
this_total_label.value = this_total * this_price;
}
Now we don't have to worry about a certain row missing, since we iterate through all existing rows. A similar approach can be taken when calculating the total price for all rows, just loop through each rows total price, add them together then assign the total to the total price label.

How to submit Multiple Form data with ng-model on single submit

Hi I want to post all form data with same model name. that is my code in this i also clone tr tag to create more form with same name classes & Model .
<tr class="row_1">
<form name="myForm1" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
<tr class="row_1">
<form name="myForm2" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
<tr class="row_1">
<form name="myForm3" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
</form>
</tr>
</tbody>
</table>
<!-- </form> -->
<button class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
<button class="btn btn-warning" onclick="cloneRow()" id="add_job">Add Row</button>
angular Code Like That
$scope.saveJob = function(data) {
console.log(data);
//http request goes here
}
EDIT: This structure is not good. I think you are trying to create a lot of rows and select table DOM and datas. It is not an angular way!
How to do that with angular way
You need to define an array in your controller.
$scope.jobList = [];
You need to define a push method. Your save method work with jobList array.
$scope.addEmptyJob() = function(){
var newJob = {};
$scope.jobList.push(newJob);
}
You need to define a repeating td and one submit button.
<form name="myForm_{{$index}}" class="sub_job">
<tr class="row_1" ng-repeat="job in jobList">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
<td>
<button class="btn btn-warning" ng-click="addEmptyJob()" id="add_job">Add New Row</button>
</td>
</tr>
<button type="submit" class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
</form>
OLD ANSWER for single save.
You need to define every form with a button. And every form have to be unique. So you can use $index for unique. End you need to add type="submit" to buttons for form control.
<tr class="row_1" ng-repeat="job in myArray track by $index">
<form name="myForm_{{$index}}" class="sub_job">
<td><input type="text" name="quantity" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity" ng-model="job.quality"/></td>
<td>
<button type="submit" class="btn btn-primary" ng-click="saveJob(job)" id="save_exit">Save & Exit</button>
<button type="submit" class="btn btn-warning" onclick="cloneRow()" id="add_job">Add Row</button>
</td>
</form>
</tr>
You can achieve this thing with array and ng-repeat rather than cloning html element.
HTML
<table><tbody>
<tr class="row_1" ng-repeat="job in jobs track by $index">
<form name="myForm" class="sub_job">
<td><input type="text" name="quantity[]" ng-model="job.quantity"/></td>
<td><input type="text" name="quantity[]" ng-model="job.quality"/></td>
</form>
</tr>
</tbody></table>
<button class="btn btn-primary" ng-click="save()" id="save_exit">Save & Exit</button>
<button class="btn btn-warning" ng-click="clone()" id="add_job">Add Row</button>
Angular Controller
// You can fetch this array of jobs from server for showing purpose
$scope.jobs = [
{
quantity: "1.0" ,
quality: "A"
},
{
quantity: "2.0" ,
quality: "B"
}
]
$scope.clone = function(){
// You can change default values for new job to appear
var empty = {
quantity: "" ,
quality: ""
};
$scope.jobs.push(empty);
}
$scope.save = function(){
// You can send this array of jobs to server for saving purpose
console.log($scope.jobs);
}
You can't have a single model for multiple input elements, because if you change value in either of the input boxes, it will overwrite it with the latest value. Assuming you start filling the form, from form1 to form3, and do a submit, the model will hold value entered in the last used input box, i.e form3.
To solve your problem you need to use a collection, array or object (preferably array) as your model.
Your controller would be something like:
var JobModel = function() {
return {
jobs: [],
addRow: function() {
var model = {
quantity: "",
quality: "",
};
this.jobs.push(model);
},
save: function() {
console.log(this.jobs);
},
submit: function(){
for(var i=0;i<this.jobs.length;i++){
doSomeHTTPRequest(this.jobs[i]);
}
}
};
};
$scope.jobModel = new JobModel();
Your HTML will be somthing like:
<button ng-click="jobModel.addRow()">
Add Job
</button>
<div ng-repeat="job in jobModel.jobs">
<input type="text" ng-model="job.quantity" placeholder="Quantity">
<input type="text" ng-model="job.quality" placeholder="Quality">
</div>
<button ng-click="jobModel.save()">
Save Jobs
</button>
To submit your form with same name you would need to iterate over the jobs array and make ajax calls for each

Trying to add new row (div) for invoice and getting while page repeat

As the title says I am trying to have a row repeat when I click a button so I can use PHP to hook in and pull the data and do something with it (create an invoice and bill it). The code section I have is:
<!-- Table row -->
<br><br>
<div class="row">
<!--Product Table-->
<div class="col-xs-12 table">
<table class="table table-striped">
<tbody>
<tr>
<td><form><input type="text" name="product-name[]" placeholder="Product Name"></form></td>
<td><form><input type="text" name="description[]" placeholder="Description"></form></td>
<td><form><input type="text" name="qty[]" size="1" placeholder="Quantity"></form></td>
<td><form><input type="text" name="price-unit[]" size="2" placeholder="Price Per Unit"></form></td>
<td><form><input type="text" name="subtotal[]" size="2" placeholder="Sub Total"></form></td>
</tr>
<p id='newrow'></p>
</tbody>
</table>
<input type='button' class="btn btn-success" id='add' value='Add item' />
</div>
<!--/Product Table-->
<!-- /.col -->
<script type="text/javascript">
$('#add').click(function(){
var n= $('.row').length+1;
var temp = $('.row:first').clone();
$('input:first',temp).attr('placeholder','Item #'+n)
$('.row:last').after(temp);
})
</script>
</div>
<!-- /.row -->
Hopefully someone can help me as I have been hours now on it spread over a week and can not seem to figure it out. I am sure it is something small and I have just missed it. Thanks in advance :D
You need to use event delegation for the click event on add button.
Using event delegation you can that attach an event for the dynamically created elements by attaching the event on the parents that will fire for all descendants matching a selector
Read : https://learn.jquery.com/events/event-delegation/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Table row -->
<div class="row">
<!--Product Table-->
<div class="col-xs-12 table">
<table class="table table-striped">
<tbody>
<tr>
<td><form><input type="text" name="product-name[]" placeholder="Product Name"></form></td>
<td><form><input type="text" name="description[]" placeholder="Description"></form></td>
<td><form><input type="text" name="qty[]" size="1" placeholder="Quantity"></form></td>
<td><form><input type="text" name="price-unit[]" size="2" placeholder="Price Per Unit"></form></td>
<td><form><input type="text" name="subtotal[]" size="2" placeholder="Sub Total"></form></td>
</tr>
<p id='newrow'></p>
</tbody>
</table>
</div>
<input type='button' class = "add" class="btn btn-success" id='add' value='Add item' />
</div>
<!--/Product Table-->
<!-- /.col -->
<script type="text/javascript">
$(document).on("click",".add",function(){
var n= $('.row').length+1;
var temp = $('.row:first').clone();
$('input:first',temp).attr('placeholder','Item #'+n)
$('.row:last').after(temp);
})
</script>
<!-- /.row -->

Categories

Resources