I'm creating a form to input an invoice with dynamically added rows (as seen in this image)
I'm using jquery 1.6.2 to calculate Line Total, sum all Line Totals, calculate Tax and display Total. The problem that I'm having is that calculating Line Total only works for the first added row. As you can see on the image above, the first row (Item 1), is fine (2*30=60), but the second row (Item 2) shows the same total as the first one (it should be 4*100=400). Here's the code for this part:
<script type="text/javascript">
var $k = jQuery.noConflict();
$k(function (){
$k('#item_form').live("keyup", "input[name^=linetotal]", function() {
var quantity = $k('input[name^=quantity]').val();
var unitprice = $k('input[name^=unitprice]').val();
$k('input[name^=linetotal]').val(quantity*unitprice);
var sum = $k('input[name^=linetotal]').sum();
$k('#subtotal').val(sum);
$k('#tax').val(Math.round(sum*10*100)/100);
$k('#total').val(Math.round((sum+Math.round(sum*10*100)/100)*100)/100);
});
});
</script>
Any ideas about what should I try? Thank you all!
You are using $k(input[name^=quantity]').val(); to grab the quantity/unitprice, but this grabs all quantity/unitprice inputs, and .val() gets the value of the first one.
You need to get the one on the same line, although it is odd that you are waiting for keyup on the linetotal. Wouldn't you want keyup on quantity and unitprice?
$k('input[name^=quantity], input[name^=unitprice]').live("keyup", function() {
var quantity = parseFloat($k(this).parent().find('input[name^=quantity]').val());
var unitprice = parseFloat($k(this).parent().find('input[name^=unitprice]').val());
$k(this).siblings('input[name^=linetotal]').val(quantity*unitprice);
var sum = $k(this).siblings('input[name^=linetotal]').sum();
$k('#subtotal').val(sum);
$k('#tax').val(Math.round(sum*10*100)/100);
$k('#total').val(Math.round((sum+Math.round(sum*10*100)/100)*100)/100);
});
});
Basic jsfiddle demo: http://jsfiddle.net/jtbowden/YxJCF/
I believe this is due it taking the first input[name^quantity] and first input[name^unitprice] it runs across. Since both rows have the same names, you have to scope your code to make sure it only pulls from its own row and not from others. Does that make sense?
Related
I am working on making an editable Datatable using Jeditable. I need to be able to dynamically add rows, which I have successfully done. By default, it appears that Datatables will add everything with a row_id of 0, which makes it impossible to differentiate added rows from each other.
So I am working on a function that assigns the row_id. There are no errors, but it also does not seem to work as it still returns a row_id of 0 for all added rows.
$('#addRow').on( 'click', function () {
var rowIndex = $('#example').dataTable().fnAddData([ "column1Data", "column2Data"]);
var row = $('#example').dataTable().fnGetNodes(rowIndex);
$(row).attr('id', row_id_counter);
row_id_counter ++;
Entire code:
http://jsfiddle.net/j2frzerj/
I tested your code in the fiddle provided, and it is adding new table rows with sequential id's, starting with index 0. I am not seeing any duplicate id's of 0?
http://prntscr.com/ew3tg9
http://prntscr.com/ew3tlr
I'm stumped by this current project I'm trying to solve. I'm able to print out the exact results that I want in the console, however I can't figure out how to insert those back into their respective tds within the table.
var calc = $('.calc'),
odds = $('.weight');
$(document).on('keyup keydown', '.calc', function(e){
var curVal = calc.val();
$(document).find('.weight').each(function(){
var oddsVal = ($(this).text() / curVal);
console.log(oddsVal);
});
});
I'm trying to divide the text in each cell of the weight column by the input.calc while a user is entering data into the input so that it updates live.
You can see a Fiddle of it here, with the results printing to the console. How can I make it so each cell in the weight column updates?
Thanks in advance for your help!
The problem is that the cells are getting updated before a value is in the input, which results in 'Infinity' being created 4 times. You can even see it in your console log.
Instead, make sure there is a value in calc before executing the function.
Furthermore, if you repeatedly change the calc field, it will do a new calculation based on the newly replaced values, which does not seem like the correct behavior. So, instead, capture the original values on page load and use those in the calculation:
var originalWeights = getOriginalWeights();
function getOriginalWeights() {
var weights = [];
$('.weight').each(function(index) {
weights[index] = $(this).text();
});
return weights;
}
$(document).on('keyup keydown', '.calc', function(e){
if (!calc.val()) return;
var curVal = calc.val();
$(document).find('.weight').each(function(index){
var oddsVal = (originalWeights[index] / curVal);
$(this).text(oddsVal);
});
});
Fiddle
To solve this you have to edit both HTML and JS code. You should store the original value in a data attribute, and then print it inside the loop using the value parameter of the jquery each function. Here is your fiddle edited, hope it helps!
http://jsfiddle.net/ch1qui/LoLrotkn/3/
You should remove the keydown event from the event delegation as the value on the input box would not be available during keydown. Also having keyup and keydown would trigger the events simultaneously, triggering each block twice. Also you don't need to declare the var calc = $('.calc'), globally since the element would be available during the event target on the document.
$(document).on('keyup', '.calc', function(e){
var curVal = $(this).val();
$('table td.weight').each(function(){
var oddsVal = $(this).text() / curVal;
alert(oddsVal);
});
});
Example : http://jsfiddle.net/LoLrotkn/4/
I'm creating an order form in which users can select an amount of products and it should immediately change total prices. I made some HTML markup and jquery code to achieve this, but I can't get it working. Can anyone see what I'm doing wrong?
Fixed script:
$("input[type=number]").change(function () {
var value = parseFloat($(this).attr("title"));
var total = (value * this.value).toFixed(2);
if (total < 0) total = 0;
$(this).parent().next().find("input").val('€' + total);
});
Inside of event handler this refers to HTMLInputElement, not jQuery instance so you have to wrap it in $(this).
Also you need to traverse one level up to the parent node and then use next() to get target input field.
Finally I added basic validation to prevent negative prices. You can also add min="0" attribute to input fields.
Demo: http://jsfiddle.net/dfsq/X33pS/
I am using jquery to gather data from a dynamically created table via Jquery. I am able to get the data, but now I want to sum up the fields and put the result inside a text field or label etc dynamically when I press enter. I am using the following code:
$("#iq").keypress(function(e)
{
if(e.which==13)
{
var tot=0;
$('#tab .itemtotal').each(function()
{
tot = tot + parseInt($(this).html());
});
$("#totalamount").val(tot);
}
});
My problem is that the value showing in the textfield is zero or NaN for the first time and after that its calculating correctly. I used the same code and associating it with a button and checking its click event and its working properly and showing first item also.
Any suggestions? If need some more clarification let me know. Thanks in advance.
I am creating the mobile version on a current Rails app with a "quiz" feature. There is currently a count of how many questions you have answered being generated by this function.
function updateGroupProgressCounter($group){
var count = $group.find('tr').has('input:checked').length;
$group.parents('.carousel').find('.checkedCount').text( count);
}
I am changing the inputs from radio buttons to select boxes for mobile and want to keep the count feature but can't quite make it work so far. I've tried
var count = $group.find('tr').has('select option:selected').length;
but gives me the total number of questions in that group. Any help is appreciated.
I would toggle a class on the row based on select change event, then count those rows.
$('tr select').change(function(){
$(this).closest('tr').toggleClass('answered', $(this).val()!='' );
});
Second argument of toggleClass determines whether to add/remove.
Then to get total rows:
$('tr.answered').length
toggleClass() API Docs
Another approach using filter() to count select that have value
var number_answered=$('tr select').filter(function(){
return $(this).val !='';
}).length
Probably you are looking for something like this:
$("#boxes").on("change","input", function(){
$("#total").val($("#boxes input:checked").length);
});
Play around with the fiddle
Considering the value of first element of your select list is empty(i.e "")
So the code will be
var count = 0;
$group.find('tr select').each(function(){
if(this.value.length)
count++;
});
I know this is not the best way to do it.
Adding and removing class on the basis of selection and finally finding the length of element that contains required class would be better approach as suggested by #charlietfl.