my jquery code doesn't work on dynamically appended elements. It is working fine for the elements that already present there but When I embed a new row using the jQuery append function, then the jquery code no longer works.
Here is the jquery code that embeds a new row
<script>
$(document).ready(function() {
$('#add_row').click(function(){
$('#sale_table').append('<tr><td><select class="form-control" name="item_name[]"><option>Select an Item</option><?php while($item_result = mysqli_fetch_assoc($select_item_query)) { ?><option><?php echo $item_result['item_name']; ?></option><?php } ?></select></td><td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td><td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td></tr>');
});
});
</script>
and this is the jquery code that I'm trying to run on appended row. This code doesn't work on appended rows
<script>
$(document).ready(function() {
$('#sale_item_price, #sale_item_quantity').on('keyup', function(){
var sum = 0;
$('.sale-entry > tbody > tr').each(function() {
var qty = $(this).find('#sale_item_quantity').val();
var price = $(this).find('#sale_item_price').val();
var discount = $(this).find('#sale_item_discount').val();
var amount = (qty * price);
if(discount){
amount = amount - discount;
}
$(this).find('#sale_item_total_amount').val(amount);
sum += amount;
});
$('#sale_subtotal_amount').text(sum);
$('#sale_total_amount').text(sum);
$("#sale_item_discount").on('keyup', function() {
var discount = $("#sale_item_discount").val();
$("#sale_item_total_amount").val(sum - discount);
$("#sale_subtotal_amount").text(sum - discount);
$("#sale_total_amount").text(sum - discount);
});
});
});
</script>
and here is the HTML code
<table class="table sale-entry" id="sale_table">
<thead class="thead-light">
<tr>
<th scope="col">Item Name</th>
<th scope="col">Quantity</th>
<th scope="col">Rate</th>
<th scope="col">Discount</th>
<th scope="col">Total Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td><select class="form-control" name="item_name[]">
<option>Select an Item</option>
<?php while($item_result = mysqli_fetch_assoc($select_item_query)) { ?>
<option><?php echo $item_result['item_name']; ?></option>
<?php } ?>
</select>
</td>
<td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td>
<td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td>
</tr>
</tbody>
</table>
What could be the issue?
if $('#sale_item_price, #sale_item_quantity').on('keyup'... not working then $(document).on('keyup', '#sale_item_price, #sale_item_quantity',... works.
Here, $('#sale_item_price, #sale_item_quantity') is unaware of DOM changed.
Have a look in example:-
$(document).ready(function() {
$(document).on('keyup', '#sale_item_price, #sale_item_quantity, #sale_item_discount', function() {
var sum = 0;
$('.sale-entry > tbody > tr').each(function() {
var qty = $(this).find('#sale_item_quantity').val();
var price = $(this).find('#sale_item_price').val();
var discount = $(this).find('#sale_item_discount').val();
var amount = (qty * price);
if (discount) {
amount = amount - discount;
}
$(this).find('#sale_item_total_amount').val(amount);
sum += amount;
});
$('#sale_subtotal_amount').text(sum);
$('#sale_total_amount').text(sum);
});
});
$(document).ready(function() {
$('#add_row').click(function() {
$('#sale_table').append('<tr><td><select class="form-control" name="item_name[]"><option>Select an Item</option></select></td><td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td><td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td></tr>');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table sale-entry" id="sale_table">
<thead class="thead-light">
<tr>
<th scope="col">Item Name</th>
<th scope="col">Quantity</th>
<th scope="col">Rate</th>
<th scope="col">Discount</th>
<th scope="col">Total Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select class="form-control" name="item_name[]">
<option>Select an Item</option>
</select>
</td>
<td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td>
<td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td>
</tr>
</tbody>
</table>
<button id="add_row" type="button">Add row</button>
<div>sale_subtotal_amount: <span id="sale_subtotal_amount"></span></div>
<div>sale_total_amount: <span id="sale_total_amount"></span></div>
Related
I have a search with filter that narrows down data as expected. I would like to implement the functionality of hiding all the data by default, and only show results when they match a search. At the moment if nothing is typed everything is shown. The list will be very long once all data will be added, hence the request. Many thanks.
$(document).ready(function(){
$("#search-box").on("keyup", function() {
var value = $(this).val().toLowerCase();
var filter = $('#search-filter').val().toLowerCase();
if(filter == "listitem") {
$(".listitem").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$(".td-"+filter).filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
}
});
$('#search-filter').on("change",function(){
var value = $("#search-box").val().toLowerCase();
var filter = $(this).val().toLowerCase();
if(filter == "listitem") {
$(".listitem").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$(".td-"+filter).filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="input-group">
<div class="input-group-append">
<select id="search-filter" name="search-filter">
<!--<option value="listitem">All</option>-->
<option value="" disabled selected>Search by</option>
<option value="name">Name</option>
<option value="surname">Surname</option>
</select>
</div>
<input id="search-box" type="text" name="search" placeholder="Type here..." required="required"/>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr class="listitem">
<td class="td-name">Jane</td>
<td class="td-surname">Doe</td>
</tr>
<tr class="listitem">
<td class="td-name">Dela</td>
<td class="td-surname">Cruz</td>
</tr>
</tbody>
</table>
</div>
Start by hiding everything. Then use an if statement to test if the search value is not empty, and show the matching elements.
I've also pulled the filtering code out into a named function, so we don't have to repeat it in both event listeners.
.filter() shouldn't be used to execute operations on each element, that should be done with .each(). But in this case you can use it to return a new collection that's just the matching elements, and you can then show them all together.
function filter_items(value, filter) {
$(".listitem, thead").hide();
if (value != '') {
if (filter == "listitem") {
$(".listitem").filter(function() {
return $(this).text().toLowerCase().includes(value)
}).show();
} else {
$(".td-" + filter).filter(function() {
return $(this).text().toLowerCase().includes(value)
}).closest(".listitem").show();
}
if ($(".listitem:visible").length > 0) {
$("thead").show();
}
}
}
$(document).ready(function() {
$("#search-box").on("keyup", function() {
var value = $(this).val().toLowerCase();
var filter = $('#search-filter').val().toLowerCase();
filter_items(value, filter);
});
$('#search-filter').on("change", function() {
var value = $("#search-box").val().toLowerCase();
var filter = $(this).val().toLowerCase();
filter_items(value, filter);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="input-group">
<div class="input-group-append">
<select id="search-filter" name="search-filter">
<!--<option value="listitem">All</option>-->
<option value="" disabled selected>Search by</option>
<option value="name">Name</option>
<option value="surname">Surname</option>
</select>
</div>
<input id="search-box" type="text" name="search" placeholder="Type here..." required="required" />
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr class="listitem">
<td class="td-name">Jane</td>
<td class="td-surname">Doe</td>
</tr>
<tr class="listitem">
<td class="td-name">Dela</td>
<td class="td-surname">Cruz</td>
</tr>
</tbody>
</table>
</div>
form, which is fetching service name in <td>Name</td> and jQuery below is appending sub total as quantity increases with respect to price.
$(document).on('change', '.qty', function() {
var quantity = $(this).val();
var sub = $(this).parent().next().children();
var price = $(this).parent().prev().children().val();
var subTotal = parseInt(quantity) * parseInt(price);
sub.val(subTotal);
});
var i = 1;
$(function() {
$("#btnAdd").bind("click", function() {
var div = $("<tr />");
div.html(GetDynamicTextBox(""));
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function() {
$(this).closest("tr").remove();
// GrandTotal();
});
});
function GetDynamicTextBox(value) {
i++;
return '<td><select class="form-control select2 select-service" style="width: 100%;" id="service-select' + i + '" required name="product[]"><option value="">--Select Product--</option> <?php foreach($dbf->fetchOrder("service") as $services){?><option value="<?= $services['
id '];?>"><?= $services['
service '];?></option><?php }?></select></td>' +
'<td><input class="form-control rate" name = "rate[]" type="text" placeholder="Rate" id="rate1' + i + '" required readonly/></td>' +
'<td><input class="form-control qty" placeholder="Quantity" name = "qty[]" type="number" id="qty1' + i + '" /></td>' +
'<td><input class="form-control sub-total" placeholder="Sub Total" name = "sub_total[]" type="text" id="sub_total1' + i + '" readonly required/></td>' +
'<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign"></i></button></td>'
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-responsive table-striped table-bordered">
<thead>
<tr>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Sub Total</td>
<td><button id="btnAdd" type="button" class="btn btn-primary" data-toggle="tooltip" data-original-title="Add more controls"><i class="glyphicon glyphicon-plus-sign"></i> Add </button></td>
</tr>
</thead>
<tbody id="TextBoxContainer">
<tr>
<td>
<select class="form-control select-service" style="width: 100%;" id="service-select" required name="service[]">
<option value="">--Select Services--</option>
<?php foreach($dbf->fetchOrder("service") as $services){?>
<option value="<?= $services['id'];?>">
<?= $services['service'];?>
</option>
<?php }?>
</select>
</td>
<td><input type="text" class="form-control rate" placeholder="Rate" readonly name="rate[]" id="rate1" required></td>
<td><input type="number" min="1" class="form-control qty" placeholder="Quantity" name="qty[]" id="qty1"></td>
<td><input type="text" min="1" class="form-control sub_total" placeholder="Sub Total" name="sub_total[]" readonly id="sub_total1"></td>
<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign"></i></button></td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
this is the multiple dynamic input field of the same form above, which is adding Name,Price,Quantity,Sub Total dynamic field as add button is clicked.
My goal is to add all the sub-total from the multiple dynamic field and display it inside a different field.
You can use each loop to iterate through all inputs i.e : sub_total then get value of input and add it to some variable on each iteration and finally append it to some element.
Demo Code :
$(document).on('change', '.qty', function() {
var quantity = $(this).val();
var sub = $(this).parent().next().children();
var price = $(this).parent().prev().children().val()
var subTotal = parseInt(quantity) * parseInt(price);
sub.val(subTotal);
calculate_total(); //call to calculate
});
var i = 1;
$(function() {
$("#btnAdd").bind("click", function() {
var div = $("<tr />");
div.html(GetDynamicTextBox(""));
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function() {
$(this).closest("tr").remove();
calculate_total(); //call to calculate
});
});
function GetDynamicTextBox(value) {
i++;
return '<td><select class="form-control select2 select-service" style="width: 100%;" id="service-select' + i + '" required name="product[]"><option value="">--Select Product--</option></select></td>' + '<td><input class="form-control rate" value="10" name = "rate[]" type="text" placeholder="Rate" id="rate1' + i + '" required readonly/></td>' + '<td><input class="form-control qty" placeholder="Quantity" name = "qty[]" type="number" id="qty1' + i + '" /></td>' + '<td><input class="form-control sub_total" placeholder="Sub Total" name = "sub_total[]" type="text" id="sub_total1' + i + '" readonly required/></td>' + '<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign">x</i></button></td>'
}
function calculate_total() {
var total = 0;
//loop through all inputs(sub-total)
$("input.sub_total").each(function() {
//check if value is not null
total += ($(this).val() != "") ? parseInt($(this).val()) : 0;
})
//add total
$("#total").text(total)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-responsive table-striped table-bordered">
<thead>
<tr>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Sub Total</td>
<td><button id="btnAdd" type="button" class="btn btn-primary" data-toggle="tooltip" data-original-title="Add more controls"><i class="glyphicon glyphicon-plus-sign"></i> Add </button></td>
</tr>
</thead>
<tbody id="TextBoxContainer">
<tr>
<td>
<select class="form-control select-service" style="width: 100%;" id="service-select" required name="service[]">
<option value="">--Select Services--</option>
<option value="1">1 </option>
<option value="2">2 </option>
<option value="3">3 </option>
</select>
</td>
<td><input type="text" class="form-control rate" placeholder="Rate" readonly name="rate[]" value="10" id="rate1" required></td>
<td><input type="number" min="1" class="form-control qty" placeholder="Quantity" name="qty[]" id="qty1"></td>
<td><input type="text" min="1" class="form-control sub_total" placeholder="Sub Total" name="sub_total[]" readonly id="sub_total1"></td>
<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign">x</i></button></td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="3">Total : </th>
<th id="total">0</th>
</tr>
</tfoot>
</table>
I have a table that looks like this
<table id="tableScanItems" class="table">
<th>Scan Item</th>
<th>Inactive</th>
<tr>
<td><input type='text' id='input1' class='form-control'/></td>
<td><input type='checkbox' id='checkbox1' class='form-control'/></td>
</tr>
<tr>
<td><input type='text' id='input2' class='form-control'/></td>
<td><input type='checkbox' id='checkbox2' class='form-control'/></td>
</tr>
<tr>
<td><input type='text' id='input3' class='form-control'/></td>
<td><input type='checkbox' id='checkbox3' class='form-control'/></td>
</tr>
</table>
On a button click I have this jQuery that runs.
$("#tableScanItems tr").each(function (){
$(this).closest('tr').find("input").each(function() {
...get the values for each row and do stuff
});
});
I need to loop the html table to get the values of the input type=text and the input type=checkbox
The JS does loop properly and gets the input type=text values but not the input type=checkbox values. Do I need to specify a different parameter in the .each to see the value of checkbox?
Ryan
EDIT
If I do this I cannot see the values of the user inputs.
$(this).closest('tr').find("input").each(function() {
alert(this.value)
});
You can loop like below. You need to treat checkboxes differently to get their values:
$("#tableScanItems tr").each(function (){
$(this).closest('tr').find("input").each(function() {
var elem = $(this);
if (elem.is(':checkbox')) {
console.log( !!elem.attr("checked"));
} else {
console.log(elem.val());
}
});
});
Working fiddle here: https://jsfiddle.net/5yt9hon1/1/
Check some checkboxes and hit submit. You will see the values of the checkboxes in a div.
$(document).ready(function () {
$('#btnSubmit').click(function () {
var result = $('input[type="checkbox"]:checked')
if (result.length > 0) {
var resultString = result.length + " checked <br/><br/>"
result.each(function () {
resultString+= $(this).val() + "<br/>";
});
$('#divCheckboxValues').html(resultString);
}
else {
$('#divCheckboxValues').html(" No checkbox checked");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table id="tableScanItems" class="table">
<th>Scan Item</th>
<th>Inactive</th>
<tr>
<td><input type='text' id='input1' class='form-control'/></td>
<td><input type='checkbox' id='checkbox1' class='form-control'/></td>
</tr>
<tr>
<td><input type='text' id='input2' class='form-control'/></td>
<td><input type='checkbox' id='checkbox2' class='form-control'/></td>
</tr>
<tr>
<td><input type='text' id='input3' class='form-control'/></td>
<td><input type='checkbox' id='checkbox3' class='form-control'/></td>
</tr>
</table>
<input id="btnSubmit" type="submit" value="submit" />
<br />
<div id="divCheckboxValues">
</div>
I have implemented dynamic row add/delete in thymeleaf using jquery. But I am unable to capture the row values as array of json objects.
$(function(){
$('#addMore').on('click', function() {
var data = $("#tab_logic tr:eq(1)").clone(true).appendTo("#tab_logic");
data.find("input").val('');
});
$(document).on('click', '.remove', function() {
var trIndex = $(this).closest("tr").index();
if(trIndex>1) {
$(this).closest("tr").remove();
}
});
The table to which dynamic row gets added/deleted is as below:-
<table class="table table-bordered table-hover" id="tab_logic">
<tr class="tr-header">
<label for="requestno">Sales target</label>
<th>Team lead</th>
<th>Sales volume</th>
<th><a href="javascript:void(0);"
style="font-size: 18px;" id="addMore"> <span
class="glyphicon glyphicon-plus"></span></a></th>
</tr>
<tr>
<td>
<input type="text" name="teamLead" class="form-control" ></input>
</td>
<td>
<input type="text" name="salesVolume" class="form-control" ></input>
</td>
<td>
<a href='javascript:void(0);' class='remove'><span
class='glyphicon glyphicon-remove'></span></a>
</td>
</tr>
</table>
You can serialized forms inputs using the serialize() function. This will return a query string that then can be converted to JSON object using JSON.stringify(). So, my recommendation, would be to add everything inside a form and then serialize it.
HTML
<table class="table table-bordered table-hover" id="tab_logic">
<tr class="tr-header">
<label for="requestno">Sales target</label>
<th>Team lead</th>
<th>Sales volume</th>
<th><a href="javascript:void(0);"
style="font-size: 18px;" id="addMore"> <span
class="glyphicon glyphicon-plus"></span></a></th>
</tr>
<form id="myForm>
<tr>
<td>
<input type="text" name="teamLead" class="form-control" ></input>
</td>
<td>
<input type="text" name="salesVolume" class="form-control" ></input>
</td>
<td>
<a href='javascript:void(0);' class='remove'><span
class='glyphicon glyphicon-remove'></span></a>
</td>
</tr>
</form>
</table>
Javascript/jQuery
$(function(){
$('#addMore').on('click', function() {
// Add the row to your form, not the table.
var data = $("#tab_logic tr:eq(1)").clone(true).appendTo("#myForm");
data.find("input").val('');
});
$(document).on('click', '.remove', function() {
var trIndex = $(this).closest("tr").index();
if(trIndex>1) {
$(this).closest("tr").remove();
}
});
// Method that will generate the JSON object.
function toJSON() {
var data = $('#myForm').serialize();
console.log(JSON.stringify(data));
}
I have a simple nested json embedded in my html file to which I want to insert some data dynamically using form.
I am able to insert data to parent level but unable to insert to child level. What I am doing wrong?
Here is the code:
<div class="container" ng-app="myApp" ng-controller="myCtrl">
<label>Enter Data</label>
<input ng-model="name" type="text">
<input ng-model="rollno" type="number">
<input ng-model="id" type="text">
<button ng-click="addData(data)">Enter Data</button>
<table class="table table-bordered">
<tr>
<th>Sr No</th>
<th>Name</th>
<th>Roll No</th>
<th>Subjects</th>
<th>Delete</th>
</tr>
<tr ng-repeat="data in myData">
<td>{{$index+1}}</td>
<td>{{data.name}}</td>
<td>{{data.rollno}}</td>
<td ng-repeat="subject in data.subjects">{{subject.id1}}, {{subject.id2}}</td>
<td>remove</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($scope){
$scope.myData =[{"name":"Jon","rollno":123,"subjects":[{"id1":"Maths","id2":"Hindi"}]},{"name":"Ron","rollno":234,"subjects":[{"id1":"English","id2":"Hindi"}]}];
$scope.addData = function(data){
$scope.myData.push({name:$scope.name,rollno:$scope.rollno,id1:$scope.id1});
}
$scope.removeData = function(index){
$scope.myData.splice(index, 1);
}
});
</script>
If you are trying to insert subjects as well using addData function you can do the below. In html add those ng-models
<input ng-model="name" type="text">
<input ng-model="rollno" type="number">
<input ng-model="id" type="text">
<input ng-model="subid1" type="text"/>
<input ng-model="subid2" type="text"/>
In js
$scope.addData = function(data){
var arrData = {name:$scope.name,rollno:$scope.rollno,subjects:[{id1:$scope.subid1,id2:$scope.subid2 }]};
$scope.myData.push(arrData);
}