multi ng -repeat and remove rows in angular js - javascript

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>

Related

what js code that will get the value from the div class name from the append. () to get the value

I am creating a like a data calculator that will compute the inputted number.
My problem is that when adding new input, it cannot get or add the value to the total.
this are the sample out.
When you click the plus(+) button and add new number value, it will not add up to the total.
jQuery($ => {
const $expenses_debit = $(".expenses_debit");
const $res_debit = $("#sub_debit");
$expenses_debit.on("input", () => {
const total = $expenses_debit.get().reduce((acc, el) => (acc += parseFloat(el.value, 10) || 0), 0).toFixed(2);
$res_debit.val(total);
});
});
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap27"); //Fields wrapper
var add_button = $(".add_field_button27"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e) { //on add input button click
e.preventDefault();
if (x < max_fields) { //max input box allowed
x++; //text box increment
$(wrapper).append('<tr><td><div class="row"><div class="col-lg-3"><button class="btn btn-sm btn-light">-</button></div><div class="col-lg-9"><div class="input-group input-group-lg"><input type="text" name="" style="font-size:12px" class="form-control form-control-sm" placeholder="Check No" id="expendable_furniture_check[]"></div></div></div></td><th>Furniture and Fixtures</th><td>12345</td><td><div class="input-group input-group-lg"><span class="input-group-text" style="font-size: 9pt">P</span><input type="text" style="font-size:12px" autocomplete="off" class="form-control form-control-sm expenses_debit operating_debit total1" placeholder="0.00" id="expendable_furniture_debit[]"></div></td><td><div class="input-group input-group-lg"><span class="input-group-text" style="font-size: 9pt">P</span><input type="text" style="font-size:12px" autocomplete="off" class="form-control form-control-sm " placeholder="0.00" disabled></div></td></tr>');
}
});
$(wrapper).on("click", ".remove_field27", function(e) {
e.preventDefault();
$(this).closest("tr").remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<body>
<table class="table table-sm table-hover table-fixed" align="center" style="font-size: 9pt">
<thead style="font-size: 11pt">
<tr align="center">
<th width="15%">Check Series</th>
<th width="20%">Accounts and Explanations</th>
<th>UACS Object Code</th>
<th width="20%">Debit Amount</th>
<th width="20%">Credit Amount</th>
</tr>
</thead>
<tbody class="input_fields_wrap27">
<tr>
<td>
<div class="row">
<div class="col-lg-3">
<button class="btn btn-sm btn-light add_field_button27">+</button>
</div>
<div class="col-lg-9">
<div class="input-group input-group-lg">
<input type="text" name="" style="font-size:12px" class="form-control form-control-sm" placeholder="Check No" id="expendable_furniture_check[]">
</div>
</div>
</div>
</td>
<th>Furniture and Fixtures</th>
<td>12345</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 9pt">P</span>
<input type="text" style="font-size:12px" class="form-control form-control-sm expenses_debit operating_debit total1" placeholder="0.00" id="expendable_furniture_debit[]">
</div>
</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 9pt">P</span>
<input type="text" style="font-size:12px" placeholder="0.00" class="form-control form-control-sm" disabled>
</div>
</tr>
</tbody>
<tbody>
<tr>
<td></td>
<td colspan="2">
<h5 align="right"><b>SUB TOTAL</b></h5>
</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 16pt">P</span>
<input type="text" style="font-size:12px" autocomplete="off" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" name="sub_debit" class="form-control form-control-sm operating_expenses" style="font-size: 16pt; font-weight: bold;"
placeholder="0.00" disabled="" id="sub_debit">
</div>
</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 16pt">P</span>
<input type="text" style="font-size:12px" autocomplete="off" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" name="sub_credit" class="form-control form-control-sm" id="sub_credit" style="font-size: 16pt; font-weight: bold;"
placeholder="0.00" disabled="">
</div>
</td>
</tr>
</tbody>
</table>
</body>
The issue is that at the time you add the event handler to the input field ($expenses_debit.on("input", () => {) there is only one input field. If you add another one the event handler will not be added automatically, you have to do it yourself. You could do so by wrapping the first lines in a function and call it at the beginning and when you add a new input field.
function init_input()
{
const $expenses_debit = $(".expenses_debit");
const $res_debit = $("#sub_debit");
$expenses_debit.on("input", () => {
const total = $expenses_debit.get().reduce((acc, el) => (acc += parseFloat(el.value, 10) || 0), 0).toFixed(2) ;
$res_debit.val(total);
});
}
jQuery($ => {
init_input();
});
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap27"); //Fields wrapper
var add_button = $(".add_field_button27"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<tr><td><div class="row"><div class="col-lg-3"><button class="btn btn-sm btn-light">-</button></div><div class="col-lg-9"><div class="input-group input-group-lg"><input type="text" name="" style="font-size:12px" class="form-control form-control-sm" placeholder="Check No" id="expendable_furniture_check[]"></div></div></div></td><th>Furniture and Fixtures</th><td>12345</td><td><div class="input-group input-group-lg"><span class="input-group-text" style="font-size: 9pt">P</span><input type="text" style="font-size:12px" autocomplete="off" class="form-control form-control-sm expenses_debit operating_debit total1" placeholder="0.00" id="expendable_furniture_debit[]"></div></td><td><div class="input-group input-group-lg"><span class="input-group-text" style="font-size: 9pt">P</span><input type="text" style="font-size:12px" autocomplete="off" class="form-control form-control-sm " placeholder="0.00" disabled></div></td></tr>');
// add event handler to the new input field
init_input();
}
});
$(wrapper).on("click",".remove_field27", function(e){
e.preventDefault(); $(this).closest("tr").remove(); x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<body>
<table class="table table-sm table-hover table-fixed" align="center" style="font-size: 9pt">
<thead style="font-size: 11pt">
<tr align="center">
<th width="15%">Check Series</th>
<th width="20%">Accounts and Explanations</th>
<th>UACS Object Code</th>
<th width="20%">Debit Amount</th>
<th width="20%">Credit Amount</th>
</tr>
</thead>
<tbody class="input_fields_wrap27">
<tr>
<td>
<div class="row">
<div class="col-lg-3">
<button class="btn btn-sm btn-light add_field_button27">+</button>
</div>
<div class="col-lg-9">
<div class="input-group input-group-lg">
<input type="text" name="" style="font-size:12px" class="form-control form-control-sm" placeholder="Check No" id="expendable_furniture_check[]">
</div>
</div>
</div>
</td>
<th>Furniture and Fixtures</th>
<td>12345</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 9pt">P</span>
<input type="text" style="font-size:12px" class="form-control form-control-sm expenses_debit operating_debit total1" placeholder="0.00" id="expendable_furniture_debit[]">
</div>
</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 9pt">P</span>
<input type="text" style="font-size:12px" placeholder="0.00" class="form-control form-control-sm" disabled>
</div>
</tr>
</tbody>
<tbody>
<tr>
<td></td>
<td colspan="2"><h5 align="right"><b>SUB TOTAL</b></h5></td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 16pt">P</span>
<input type="text" style="font-size:12px" autocomplete="off" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" name="sub_debit" class="form-control form-control-sm operating_expenses" style="font-size: 16pt; font-weight: bold;" placeholder="0.00" disabled="" id="sub_debit" >
</div>
</td>
<td>
<div class="input-group input-group-lg">
<span class="input-group-text" style="font-size: 16pt">P</span>
<input type="text" style="font-size:12px" autocomplete="off" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" name="sub_credit" class="form-control form-control-sm" id="sub_credit" style="font-size: 16pt; font-weight: bold;" placeholder="0.00" disabled="">
</div>
</td>
</tr>
</tbody>
</table>
</body>

jquery shopping cart value onchange

I wrote a code for a shopping cart. In that for each change in quantity value (either increasing or decreasing) there should be a change in the price. I tried to implement this for a decreasing price with respect to the quantity. I can change the quantity but I am not able to change the price field because the price still gives me the type of object as I console.log. Can anyone point out what I am doing wrong?
Below is the code:
product.html
<tr>
<td class="product-thumbnail">
<img src="images/cloth_1.jpg" alt="Image" class="img-fluid">
</td>
<td class="product-name">
<h2 class="h5 text-black">Top Up T-Shirt</h2>
</td>
<!-- The price -->
<td>$49.00</td>
<td>
<div class="input-group mb-3" style="max-width: 120px;">
<div class="input-group-prepend">
<button class="btn btn-outline-primary js-btn-minus" type="button">−</button>
</div>
<input type="text" class="form-control text-center" value="1" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
<div class="input-group-append">
<button class="btn btn-outline-primary js-btn-plus" type="button">&plus;</button>
</div>
</div>
</td>
<td>
<div class="price"></div>
</td>
<td>X</td>
</tr>
<tr>
<td class="product-thumbnail">
<img src="images/cloth_2.jpg" alt="Image" class="img-fluid">
</td>
<td class="product-name">
<h2 class="h5 text-black ">Polo Shirt</h2>
</td>
<td>$49.00</td>
<td>
<div class="input-group mb-3" style="max-width: 120px;">
<div class="input-group-prepend">
<button class="btn btn-outline-primary js-btn-minus" type="button">−</button>
</div>
<input type="text" class="form-control text-center" value="1" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
<div class="input-group-append">
<button class="btn btn-outline-primary js-btn-plus" type="button">&plus;</button>
</div>
</div>
</td>
<td>
<div class="price">8</div>
</td>
<td>X</td>
</tr>
main.js
<script>
$('.js-btn-minus').on('click', function(e)
{
e.preventDefault();
if ( $(this).closest('.input-group').find('.form-control').val() !=0 && $(this).closest('.input-group').find('.form-control').val() >0)
{
$(this).closest('.input-group').find('.form-control').val(parseInt($(this).closest('.input-group').find('.form-control').val()) - 1);
var va = parseInt($(this).closest('.input-group').find('.form-control').val());
va = (parseInt(va));
this.a = va;
console.log(this.a);
var price = $(this).closest('tr').find('.price');
console.log(price.val(parseInt(this.a)));
}
}
</script>
use price.html or price.text instead of price.val and then remember, input get value by .val() but other element get by .html() or .text()
First thing is that your table is not well structured. Second thing is that your requirement is not exactly clear to me.
Thought I assume you want to increase or decrease the price where the class is price.
You are receiving the whole element as you are using val() and it is always going to be the object.
If you could tell the exact issue/requirement, I can help you out.
$('.js-btn-minus').on('click', function(e)
{
e.preventDefault();
var next_val = parseInt($(this).closest('.input-group').find('.form-control').val()) - 1;
if (next_val < 0){
next_val = 0
$(this).closest('.input-group').find('.form-control').val(0)
}
else{
$(this).closest('.input-group').find('.form-control').val(next_val);
var existing_value = $(this).closest('tr').find('.price').html()
if ((existing_value || '') == ''){
$(this).closest('tr').find('.price').html(next_val)
}
else{
$(this).closest('tr').find('.price').html(existing_value - 1)
}
}
// Price updates
//var current_price = parseInt($(this).closest('.input-group').parent().prev('td').html().replace('$', ''))
//var final_price = current_price - next_val;
});
$('.js-btn-plus').on('click', function(e)
{
e.preventDefault();
var next_val = parseInt($(this).closest('.input-group').find('.form-control').val()) + 1;
if (next_val < 0){
next_val=0;
$(this).closest('.input-group').find('.form-control').val(0)
}
else{
$(this).closest('.input-group').find('.form-control').val(next_val);
var existing_value = parseInt($(this).closest('tr').find('.price').html())
if ((existing_value || '') == ''){
$(this).closest('tr').find('.price').html(next_val)
}
else{
$(this).closest('tr').find('.price').html(existing_value + 1)
}
}
// Price updates
//var current_price = parseInt($(this).closest('.input-group').parent().prev('td').html().replace('$', ''))
//var final_price = current_price + 1
//console.log(final_price)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td class="product-thumbnail">
<img src="images/cloth_1.jpg" alt="Image" class="img-fluid">
</td>
<td class="product-name">
<h2 class="h5 text-black">Top Up T-Shirt</h2>
</td>
<!-- The price -->
<td class="current_price">$49.00</td>
<td>
<div class="input-group mb-3" style="max-width: 120px;">
<div class="input-group-prepend">
<button class="btn btn-outline-primary js-btn-minus" type="button">−</button>
</div>
<input type="text" class="form-control text-center" value="1" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
<div class="input-group-append">
<button class="btn btn-outline-primary js-btn-plus" type="button">&plus;</button>
</div>
</div>
</td>
<td>
<div class="price"></div>
</td>
<td>X</td>
</tr>
<tr>
<td class="product-thumbnail">
<img src="images/cloth_2.jpg" alt="Image" class="img-fluid">
</td>
<td class="product-name">
<h2 class="h5 text-black ">Polo Shirt</h2>
</td>
<td class="current_price">$49.00</td>
<td>
<div class="input-group mb-3" style="max-width: 120px;">
<div class="input-group-prepend">
<button class="btn btn-outline-primary js-btn-minus" type="button">−</button>
</div>
<input type="text" class="form-control text-center" value="1" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
<div class="input-group-append">
<button class="btn btn-outline-primary js-btn-plus" type="button">&plus;</button>
</div>
</div>
</td>
<td>
<div class="price">8</div>
</td>
<td>X</td>
</tr>
</table>

How to set the selected value of a dynamically created select box

I have a table with multiple cells containing select boxes. The code I have can create/delete rows relative to the entry which you click "+/-" from. I would like it so that if I press "+" then my program will look at the employee chosen in the above entry and have it as the selected value in the current (or new) entry.
I am having a hard time grabbing the value of the field, as well as making it the selected value.
Here is my code:
[JS]
function createRow(id, emp = null) {
var newrow = [
id,
'<select class="browser-default custom-select">' + employee_list + '</select>', // Want to add 'emp' here as selected element
'<select class="browser-default custom-select"></select>',
'<div class="input-group"><input type="number" min="0" step="0.5" class="form-control"><div class="input-group-append"><span class="input-group-text">hours</span></div>',
'<div class="input-group"><div class="input-group-prepend"><span class="input-group-text">$</span></div><input type="number" step="0.01" min="0" class="form-control"></div>',
'<textarea class="form-control" maxlength="200"></textarea>',
'<a class="addButton"><i class="fa fa-plus"></i></a> <a class="deleteButton"> <i class="fa fa-minus"></i></a>'
];
return '<tr><td>' + newrow.join('</td><td>') + '</td></tr>';
}
function renumberRows() {
$('table#budget tbody tr').each(function(index) {
$(this).children('td:first').text(index + 1);
});
}
$('#add').click(function() {
var lastvalue = 1 + parseInt($('table#budget tbody').children('tr:last').children('td:first').text());
$('table#budget tbody').append(createRow(lastvalue));
});
$('table#budget').on('click', '.addButton', function() {
$(this).closest('tr').after(createRow(0));
console.log($(this).closest('tr').children('td:nth-child(2)').val()); // tring to get previous entries selected employee
renumberRows();
}).on('click', '.deleteButton', function() {
$(this).closest('tr').remove();
renumberRows();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="pure-table pure-table-horizontal" id="budget" style="width: 100%" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Row</th>
<th>Employee</th>
<th>Task</th>
<th>Budget</th>
<th>Expense</th>
<th>Comments</th>
<th><a id="add" style="float: right; color: #0000EE">Add Row <i class="fa fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<select class="browser-default custom-select" id="emp" size="1">
<option disabled selected>Choose Employee</option>
<?php for($i=0;$i<count($options_2);$i++){echo $options_2[$i];} ?>
</select>
</td>
<td>
<select class="browser-default custom-select" id="task" size="1">
<option disabled selected>Pick Employee</option>
</select>
</td>
<td>
<div class="input-group">
<input type="number" min="0" step="0.5" class="form-control">
<div class="input-group-append">
<span class="input-group-text">hours</span>
</div>
</td>
<td>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input type="number" step="0.01" min="0" class="form-control">
</div>
</td>
<td><textarea class="form-control" maxlength="200"></textarea></td>
<td><a class="addButton"><i class="fa fa-plus"></i></a>
<a class="deleteButton"> <i class="fa fa-minus"></i></a>
</td>
</tr>
<!-- This is our clonable table line -->
</tbody>
</table><br>
example
The expected result would be to have the employee of the previous (or above) entry as the selected value in the new row upon clicking +. Or in the photo, the blacked out name would be showing where Choose Employee is.
EDIT: the global variable employee_list is an array containing all of the employees in html options format.
It would be easier if createRow() converted the HTML to DOM elements. Then you can use jQuery methods to find the select and set its value.
Use $(this).closest('tr').find('select:first').val() to get the employee from the row where you clicked Add.
It would also be a good idea to add distinct classes to specific inputs and selects, rather than using selectors like select:first to find a particular select in the row.
function createRow(id, emp = null) {
var newrow = [
id,
'<select class="browser-default custom-select">' + employee_list + '</select>', // Want to add 'emp' here as selected element
'<select class="browser-default custom-select"></select>',
'<div class="input-group"><input type="number" min="0" step="0.5" class="form-control"><div class="input-group-append"><span class="input-group-text">hours</span></div>',
'<div class="input-group"><div class="input-group-prepend"><span class="input-group-text">$</span></div><input type="number" step="0.01" min="0" class="form-control"></div>',
'<textarea class="form-control" maxlength="200"></textarea>',
'<a class="addButton"><i class="fa fa-plus"></i></a> <a class="deleteButton"> <i class="fa fa-minus"></i></a>'
];
var elts = $('<tr><td>' + newrow.join('</td><td>') + '</td></tr>');
if (emp !== null) {
elts.find("select:first").val(emp);
}
return elts;
}
function renumberRows() {
$('table#budget tbody tr').each(function(index) {
$(this).children('td:first').text(index + 1);
});
}
$('#add').click(function() {
var lastvalue = 1 + parseInt($('table#budget tbody').children('tr:last').children('td:first').text());
$('table#budget tbody').append(createRow(lastvalue));
});
$('table#budget').on('click', '.addButton', function() {
var prevemp = $(this).closest('tr').find('select:first').val();
$(this).closest('tr').after(createRow(0, prevemp));
console.log($(this).closest('tr').children('td:nth-child(2)').val()); // tring to get previous entries selected employee
renumberRows();
}).on('click', '.deleteButton', function() {
$(this).closest('tr').remove();
renumberRows();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="pure-table pure-table-horizontal" id="budget" style="width: 100%" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Row</th>
<th>Employee</th>
<th>Task</th>
<th>Budget</th>
<th>Expense</th>
<th>Comments</th>
<th><a id="add" style="float: right; color: #0000EE">Add Row <i class="fa fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<select class="browser-default custom-select" id="emp" size="1">
<option disabled selected>Choose Employee</option>
<?php for($i=0;$i<count($options_2);$i++){echo $options_2[$i];} ?>
</select>
</td>
<td>
<select class="browser-default custom-select" id="task" size="1">
<option disabled selected>Pick Employee</option>
</select>
</td>
<td>
<div class="input-group">
<input type="number" min="0" step="0.5" class="form-control">
<div class="input-group-append">
<span class="input-group-text">hours</span>
</div>
</td>
<td>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input type="number" step="0.01" min="0" class="form-control">
</div>
</td>
<td><textarea class="form-control" maxlength="200"></textarea></td>
<td><a class="addButton"><i class="fa fa-plus"></i></a>
<a class="deleteButton"> <i class="fa fa-minus"></i></a>
</td>
</tr>
<!-- This is our clonable table line -->
</tbody>
</table><br>

need to create multiple groups using form in angular6

I need to create multiple groups in the form. when i create a childgroup and enter an input value the same value reflect in another group i known this is due to ngModel but how to overcome this issue. there is another issue i am facing under childGroup there is 2 table when i create another childGroup and add a new table row to that childGroup this will reflect in another childGroup also.
HTML
<fieldset *ngFor="let task of tasks; let a = index">
<legend>childGroup</legend>
<button (click)="deleteRow(a)" class="btn btn-sm btn-circle btn-danger actionMargin rmv-btn">X</button>
<div class="row">
<section class="col col-6">
<label class="label">Name</label>
<label class="input">
<input type="text" class="input-sm" [(ngModel)]="task.Name" name="task[a].Name" required>
</label>
</section>
<section class="col col-6">
<label class="label">Comm</label>
<label class="input">
<input type="text" class="input-sm" [(ngModel)]="task.Config.command" name="task[a].Config.command" required>
</label>
</section>
</div>
<!--Table-->
<section>
<h2>ABC</h2>
<table class="table table-bordered">
<thead>
<tr>
<th class="name">S no.</th>
<th class="name">Label</th>
<th class="name">Value</th>
<th class="name">Dynamic</th>
<th class="name">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of task.ports; let i = index">
<td align="center"><label>{{i + 1}}</label></td>
<td><input type="text" [(ngModel)]="item.Label" name="item[i].Label" [ngModelOptions]="{standalone: true}"
class="inputborder" required></td>
<td><input type="number" [disabled]="item[i].boolean" [(ngModel)]="item[i].Value" name="item.Value"
[ngModelOptions]="{standalone: true}" class="inputborder" required></td>
<td><input type="checkbox" [(ngModel)]="item[i].boolean" name="item[i].boolean" class="check"
[ngModelOptions]="{standalone: true}" required><span class="yes">Yes</span></td>
<td align="center"><button (click)="deleteRow(i,'port')" placement="top" tooltip="Remove Port" class="btn btn-sm btn-circle btn-danger actionMargin rmv-btn">X</button></td>
</tr>
</tbody>
</table>
<button type="button" (click)="Addrow('port')" placement="top" tooltip="Add Port" class="btn btn-sm btn-primary posi">Add
abc</button>
</section>
</fieldset>
TS.
tasks= [];
taskObj = { //click on a blue + button i am pushing this object to tasks
Name: "",
Config: {
command: ""
},
artifacts : [],
ports : []
};
// to add a table row
Addrow(i) {
if (i == 'port') {
let num = 0;
this.taskObj.ports.push({
Label: '',
Value: num,
boolean: true
});
} else {
this.taskObj.artifacts.push({
Source: '',
Relative: ''
})
}
console.log(this.tasks);
}
//remove the table row
deleteRow(index, i) {
if (i == "port") {
this.taskObj.ports.splice(index, 1);
} else {
this.taskObj.artifacts.splice(index, 1);
}
}
I the HTML code i have not add 'XYZ' table code because its same as 'ABC' table. how to implement validation to this loop within loop. Please help me with this issue.

unable to update counter when deleting and creating new section jquery

/*creates phoens dynamically*/
var phoneList = [];
function add_phone() {
var index = phoneList.length+1;
phoneList.push('phone: '+index);
var divtest = '<div class="form-group removeclass'+index+'">'+
'<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone ( '+index+' )</span>'+
'<div class="col-sm-3 nopadding">'+
'<div class="form-group">'+
' <input type="text" class="form-control" name="a[]" value="" placeholder="Type"></div></div>'+
'<div class="col-sm-3 nopadding"><div class="form-group">'+
'<input type="text" class="form-control" name="b[]" value="" placeholder="Model"></div>'+
'</div><div class="col-sm-3 nopadding">'+
'<div class="form-group"> <input type="text" class="form-control" name="c[]" value="" placeholder="Color">'+
'</div></div><div class="col-sm-3 nopadding"><div class="form-group"><div class="input-group"> '+
'<select class="form-control" name="d[]">'+
'<option value="">Year</option><option value="2015">2015</option><option value="2016">2016</option>'+
'<option value="2017">2017</option><option value="2018">2018</option> </select><div class="input-group-btn"> '+
'<button class="btn btn-danger" type="button" onclick="remove_phone('+ index +');"> <span '+
'class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button></div></div></div></div><div '+
'class="clear"></div>';
$('#education_fields').append(divtest);
updatePhonePicker();
}
function remove_phone(rid) {
$("#phone_picker option[value='"+rid+"']").remove();
$('.removeclass'+rid).remove();
phoneList.splice(phoneList.indexOf(rid),1);
updatePhonePicker();
}
function updatePhonePicker(){
var options = '<option selected disabled>---</option>';
phoneList.forEach(function(element, index){
options+='<option value="'+element+'">'+element+'</option>'
})
$('#tab_logic').find('tr').each(function(ind,ele){
var r = $(ele).find("#phone_picker").empty().append(options);
});
}
/*Add details about phone added here*/
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><select class='form-control' title='Phone' id='phone_picker'><option selected disabled>---</option></select> </td><td><input name='mail"+i+"' type='text' placeholder='field 1' class='form-control input-md'></td><td><input name='mobile"+i+"' type='text' placeholder='field 2' class='form-control input-md'></td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"></tr>');
i++;
updatePhonePicker();
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Add Phone-->
<div class="panel panel-default">
<div class="panel-heading">Phone Information</div>
<div class="panel-body">
<div id="education_fields">
</div>
<div class="input-group">
<div class="input-group-btn">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Add Phone.</span>
<button class="btn btn-success" type="button" onclick="add_phone();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
<!--Individual phone information-->
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone selected additional details.</span>
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
#
</th>
<th class="text-center">
Phone
</th>
<th class="text-center">
Type
</th>
<th class="text-center">
Carrier
</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
1
</td>
<td>
<select class="form-control" title="Phone" id="phone_picker">
<option selected disabled>---</option>
</select>
</td>
<td>
<input type="text" placeholder='field 1' class="form-control"/>
</td>
<td>
<input type="text" placeholder='field 2' class="form-control"/>
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<a id="add_row" class="btn btn-default pull-left">Add Phone</a><a id='delete_row' class="pull-right btn btn-default">Delete Phone</a>
</div>
When clicking on 'Add Phone', I get the option to add as many phones as needed. Phone count (How many phones created) get added on the 'Phone selected additional details' select option when adding or removing a new phone.
My issue is that when I create 3 phone sections then remove phone #1 and add another phone again it give me the same phone counter (example added 1,2,3 removed 1 added another one get 1 and 1 again and it should be like that, it should be a unit counter(phone) everytime).
To be more specific steps go as follow:
click on 'add phone' one time and a 2nd time and a 3rd time.
click on the red button where it's title 'Phone(1)'.
check if the number of phone present match what is on the 'Phone' select/dropdown.
You will see that the number of phone display doesn't match what on select.
Your issue is in this line:
var index = phoneList.length+1;
Because you create new div with a class like removeclass1, removeclass2..... you can consider to get directly the last div and so extract the number instead to increment by one:
var index = 1;
if ($('#education_fields > div').length > 0) {
index = 1 + +$('#education_fields > div:last').attr('class').match(/.*removeclass(\d+).*/)[1];
}
From your comment:
Ok this is good but if you look down the table column 'Phone' and the select/dropdown, it seems not be getting updated when deleting 'phone'/section
You can change updatePhonePicker in order to build dynamically the options getting the data directly from the divs:
From:
phoneList.forEach(function(element, index){
options+='<option value="'+element+'">'+element+'</option>'
})
to:
$('#education_fields > div > span').each(function(idx, ele) {
var txt = ele.textContent.replace(/[()]/g, '').trim();
options+='<option value="'+txt+'">'+txt+'</option>'
})
var phoneList = [];
function add_phone() {
var index = 1;
if ($('#education_fields > div').length > 0) {
index = 1 + +$('#education_fields > div:last').attr('class').match(/.*removeclass(\d+).*/)[1];
}
phoneList.push('phone: '+index);
var divtest = '<div class="form-group removeclass'+index+'">'+
'<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone ( '+index+' )</span>'+
'<div class="col-sm-3 nopadding">'+
'<div class="form-group">'+
' <input type="text" class="form-control" name="a[]" value="" placeholder="Type"></div></div>'+
'<div class="col-sm-3 nopadding"><div class="form-group">'+
'<input type="text" class="form-control" name="b[]" value="" placeholder="Model"></div>'+
'</div><div class="col-sm-3 nopadding">'+
'<div class="form-group"> <input type="text" class="form-control" name="c[]" value="" placeholder="Color">'+
'</div></div><div class="col-sm-3 nopadding"><div class="form-group"><div class="input-group"> '+
'<select class="form-control" name="d[]">'+
'<option value="">Year</option><option value="2015">2015</option><option value="2016">2016</option>'+
'<option value="2017">2017</option><option value="2018">2018</option> </select><div class="input-group-btn"> '+
'<button class="btn btn-danger" type="button" onclick="remove_phone('+ index +');"> <span '+
'class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button></div></div></div></div><div '+
'class="clear"></div>';
$('#education_fields').append(divtest);
updatePhonePicker();
}
function remove_phone(rid) {
$("#phone_picker option[value='"+rid+"']").remove();
$('.removeclass'+rid).remove();
phoneList.splice(phoneList.indexOf(rid),1);
updatePhonePicker();
}
function updatePhonePicker(){
var options = '<option selected disabled>---</option>';
$('#education_fields > div > span').each(function(idx, ele) {
var txt = ele.textContent.replace(/[()]/g, '').trim();
options+='<option value="'+txt+'">'+txt+'</option>'
})
$('#tab_logic').find('tr').each(function(ind,ele){
var r = $(ele).find("#phone_picker").empty().append(options);
});
}
/*Add details about phone added here*/
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><select class='form-control' title='Phone' id='phone_picker'><option selected disabled>---</option></select> </td><td><input name='mail"+i+"' type='text' placeholder='field 1' class='form-control input-md'></td><td><input name='mobile"+i+"' type='text' placeholder='field 2' class='form-control input-md'></td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"></tr>');
i++;
updatePhonePicker();
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!--Add Phone-->
<div class="panel panel-default">
<div class="panel-heading">Phone Information</div>
<div class="panel-body">
<div id="education_fields">
</div>
<div class="input-group">
<div class="input-group-btn">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Add Phone.</span>
<button class="btn btn-success" type="button" onclick="add_phone();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
<!--Individual phone information-->
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone selected additional details.</span>
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
#
</th>
<th class="text-center">
Phone
</th>
<th class="text-center">
Type
</th>
<th class="text-center">
Carrier
</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
1
</td>
<td>
<select class="form-control" title="Phone" id="phone_picker">
<option selected disabled>---</option>
</select>
</td>
<td>
<input type="text" placeholder='field 1' class="form-control"/>
</td>
<td>
<input type="text" placeholder='field 2' class="form-control"/>
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<a id="add_row" class="btn btn-default pull-left">Add Phone</a><a id='delete_row' class="pull-right btn btn-default">Delete Phone</a>
</div>
I think your problem is in the first line of add_phone
var index = phoneList.length+1;
I would remove the "+1", because if you add your first item it get's the html class removeclass1, but has the index 0 in the phoneList array. To remove this phone you call removePhone(1), but actually its index is 0, so you remove no phone or rather a wrong phone.
You simply have to write another function like the updatePhonePicker() where you gonna update the numbers displayed inside the <span>
Here is the function:
1-First surround the counter display in a span and give it a class (counterClass): ....Phone <span class="counterClass">( '+index+' )</span>
2- Each row give it a class (.someClass)
function updatePhoneNumbers(){
var counter = i;
$('someClass').forEach(function(element, index){
var number = i-counter+1;
$(element).find('.counterClass').html(counter);
counter--;
})
}

Categories

Resources