I'm trying to generate a price based on radio button selections, on input fields that are added (sort of like a list). Unfortunately since each set of radio buttons added has a unique name (so that they can be parsed separately later) the function that calculates the price is pulling the radio buttons value by it's name. This is clearly problematic since there are multiple instances of the same scenario.
Anyone?
http://jsfiddle.net/pxrpF/1/
I'm also looking to generate a Grand Total that will add up each set, so if anyone can help me figure these two bits out that would be wonderful!
This should handle the problem with grabbing the right radio buttons:
var containerCount = $(this).parents('.container').prevAll('.container').size();
var $r = $('.container:eq('+containerCount+')').find(cardType);
var $d = $('.container:eq('+containerCount+')').find(cardQ);
EDIT (to incorporate conversation below)
In addition, the selector strings cardType and cardQ should be as follows:
var cardType = ":radio[name*='type']:checked"
var cardQ = ":radio[name*='quantity']:checked"
The *= ensures that the attribute starts with type or quantity respectively.
Related
I have a drop-down menu in a form with elements retrieved from a database. Something like this :
for($i=0;$i<count($resq);$i++){
print("<li><a class=\"dropdown-item\" href=\"#\" id=\"$i\">{$resq[$i][0]}</a></li>");
}
$resq being an array containing the result of the query (i used mysqli_fetch_all).
As you can see I tried to dynamically generate the id of the items(first item has id=0, second has id=1 and so on till the final value of $i) but I think this is not correct.
Previously, I had the following JS code(which worked) which I used to set the drop-down value to the one selected by the user and to set the value of a hidden input to that value.(I know the code isn't elegant but I just wanted to test the logic in the first place)
var x=document.getElementById('dropdownMenuButton1slct');//dropdown
var c1=document.getElementById("0");//i - categories(IDs of the dropdown elements)
var c2=document.getElementById('1');
var c3=document.getElementById('2');
var c4=document.getElementById('3');
var c5=document.getElementById('4');
var p=document.getElementById('iaval');//hidden input from form
function clic(z){
z.onclick=function () {
x.innerHTML=z.innerHTML;
p.value=x.innerHTML;
};
}
clic(c1);
clic(c2);
clic(c3);
clic(c4);
clic(c5);
But now the same method won't work. If you can, please suggest me a different way or something, I am kinda stuck. I can provide more info if this seems vague or something like that. Thanks.
I am not a front-end developer and I have very limited exposure to JQuery JS etc. So any help is appreciated, thanks.
Objective : - I want to put the sum of all fields (except last ) of a fieldset into last field of that fieldset.
The form is rather complicated, in this form, there are multiple fieldsets and each fieldset contain multiple fields.
This form is generated by Drupal Views & I have very limited options to navigate in this form.
I can not use id, name or any other attribute as they are dynamically generated by CMS also there are hundreds of such fieldset so it is not feasible to write code for every one of them.
So, future addition of fields may alter the attributes. And I can not add my own attributes, classes, or ids to this form.
form looks something like this
<fieldset>
------<div>
---------<fieldset> **this one**
------------------<input>
------------------<input>
------------------<input>
------------------<input>
----------------nth <input> <= Sum of 1st to (n-1)th should come here
-----------------------<div>
I think that it can be done possibly through input:last but can't figure out how to use it properly.
Here is the function I wrote
$(function() {
$('input').change(function() {
var sum = 0;
// Loop through all inputs
$(this).closest('fieldset').find('input').each(function() {
sum += parseInt($(this).val());
console.log(sum);
// i want to put sum into last <input> tag of the current fieldset
});
});
}); // end function()
the output of console.log ($(this).closest('fieldset').find("input").last());); is
So, I figured that I have to extract attribute value, so far I have tried these
$(this).closest('fieldset').find("input").last().data('value'); Undefined
and
$(this).closest('fieldset').find("input").last().attr('value'); results in Undefined
I am trying to build a form calculation javascript that works fine with radio buttons, but I haven't been able to make it work with checkboxes.
The form includes a domain whois check, which generates checkboxes with the name 'domain' and the value is the checked domain's tld, its price is echoed in the same table cell. I managed to whip up a js code that matches the checked values with data from an array containing the tld prices. (see below)
Problem #1: The value of the checkbox should be the whole domain name (so that I can carry that variable with $_POST later on
Problem #2: The currently working js does not add up more domains of the same tld (foo.com and bar.com's price is added only once insted of twice) since the for loop that works well with radio buttons cannot work with multiple checks
--
Solutions I have pondered:
Solution #1: Add ID to checkboxes with their names being the searched domains and their value being the price of that domain tld and push them into a js object where the for loop could match the checked ones with their prices -- conflicts with problem #1, although I suppose I could get all checked checkboxes with jQuery and append them to a hidden input that PHP could process later on (?)..
Solution #2: Make js get the price of the domain from the table cell it's located in and add that up. -- problem: how do I make js get the price if the table cell's ID depends on what domain is searched for?
Here's the currently working js that processes only the checkboxes:
var domaintld = new Array();
domaintld["com"]=3000;
domaintld["eu"]=3650;
domaintld["org"]=3650;
domaintld["net"]=2850;
domaintld["info"]=4050;
function calcdomaintldPrice() {
var domaintldPrice=0;
var theForm = document.forms["orderform"];
var chosenDomains = theForm.elements["domain"];
for(var i=0; i < chosenDomains.length; i++) {
if(chosenDomains[i].checked) {
domaintldPrice = domaintld[chosenDomains[i].value];
break;
}
}
return domaintldPrice;
}
Here's an example of a checkbox markup:
<input type="checkbox" name="domain" value="net" id="dfbdfb.net" class="domainradio"
onclick="calculateTotal()"><label for="dfbdfb.net" class="domainradio"> </label>
Ad problem 1: You might want to provide more info, such as how the html is generated. As far as I can see you could just set value to the same as id couldn't you?
Ad problem 2:
Substitute
domaintldPrice = domaintld[chosenDomains[i].value];
with
domaintldPrice += domaintld[chosenDomains[i].value];
and remove the break
I am trying to calculate discounted price which I am able to do without anyproblem for a single item. I also have 'add more' button to add many item as I can. So here, I started facing problem in calculating the discounted price for these dynamically added input field.
My default discount calculation script for single item is
$('#discount_1').change(function(){
var quantity=$('#qty_1').val();
var percent=$('#discount_1').val();
var price=$('#price_1').val();
var tprice = price * quantity
var discountpercent=percent / 100;
var discountprice=(tprice * discountpercent );
$('#total_1').val(tprice - discountprice);
});
I tried changing it to the following
$(":input[id^='discount_']").change(function(){
var quantity=$(":input[id^='qty_']").val();
var percent=$(":input[id^='discount_']").val();
var price=$(":input[id^='price_']").val();
var tprice = price * quantity
var discountpercent=percent / 100;
var discountprice=(tprice * discountpercent );
$(":input[id^='total_']").val(tprice - discountprice);
});
to calculate discount for all the item set having id attribute that starts with qty_, which actually does not seem to work properly.
here is my jsFiddle
I've modified this to remove all ids. This will clean up a lot of extra crap. Here is a fiddle: http://jsfiddle.net/B5T6R/1/
The solution involved event delegation. The problem with $(":input[id^='discount_']").on('change' is that the future trs don't exist yet, so there is nothing to bind to!
The solution is:
$("#InputsWrapper").on('change', '.discount'
Which will listen for all future changes on the InputsWrapper table as a whole, not just to the discount elements.
The problem is that the selectors you are using will always select the first input that matches the selector.
So, (":input[id^='qty_']") will always match the input on the first row.
I suggest:
Rebind the "change" event evertime AddButton is clicked. This will
require .unbind() as well.
Add class "discount" to all discount inputs.
Change the selectors for quantity, price, etc to be relative to the input that was changed.
IE:
$('.discount').unbind().change(function(){
var $parentRow = $(this).parent().parent();
var quantity=$(":input[id^='qty_']", $parentRow).val();
});
It's not a great idea to use all these id's: #qty_1, #qty_2, etc. Instead give all your inputs the same class names to hook into, for example:
<input class='discount' type='text' name='discount'/>
<input class='quantity' type='text' name='quantity'/>
Then use good ole Jquery to traverse the DOM and fetch the relevant data. In this case you have to climb to the closest td and then back down to get the .quantity class, as so:
$(".discount").change(function(){
var quantity = $(this).closest('td').find('.quantity').val();
});
Hope this helps.
You are running into a couple of problems.
First, only the ":input[id^='discount_']" that exist on your page when the DOM is initialized have this change handler added to them - all new rows added via the the Add More Field link will not have this handler bound. You can get around this by attaching the handler to the container all of your fields are in via .on, so that every change event fired within that container will be checked against the selector specified. I've forked your fiddle to demonstrate: http://jsfiddle.net/gLz9B/1/
$('#InputsWrapper').on("change", ":input[id^='discount_']", function(){
...
});
The second issue is that the qty_, total_, price_, and discount_ selectors you are using will return arrays, rather than being limited to the specific row where the change is occurring. In my fiddle fork I did a string replace to get the unique number attached to the id of the element, and then build the ids of all of the other inputs rather than using =^ to select them. This is not the only way to limit your scope, but it works given your sample code.
var id = this.id.replace('discount_','');
var quantity=$("#qty_" + id).val();
I have a series of textboxes with the following IDs:
118|1/9/2011
118|1/10/2011
118|1/11/2011
118|1/12/2011
118|1/13/2011
118|1/14/2011
118|1/15/2011
118|Total
Using jQuery or just javascript, I need to sum each textbox and assign the value to the total textbox. This needs to happen when a user tabs off or clicks off the textbox. It also needs to be generic enough to handle textboxes with similar IDs such as:
119|1/9/2011
119|1/10/2011
119|1/11/2011
119|1/12/2011
119|1/13/2011
119|1/14/2011
119|1/15/2011
119|Total
The format stays the same. Only the first numbers to the left of the | will change.
Any guidance would be greatly appreciated.
EDIT: I updated my answer to reflect the actual example HTML that Mike provided, which you can view in this fiddle. That link also contains the working javascript from below.
If you have a specific selector for the inputs you want to sum (like a class name), as well as one for the total, you should be able to do this (here's a fiddle link with this javascript in action: http://jsfiddle.net/avidal/zfjmD/):
$('input.sum').change(function() {
var sum = 0;
// we want to sum up the values of all input.sum elements that are in the same tr
// as this one
$(this).closest('tr').find('input.sum').each(function(i) {
var val = parseInt($(this).val(), 10);
/*
change the above line to:
var val = parseFloat($(this).val());
if the inputs will be floats
*/
if (isNaN(val) || val === undefined) {
return;
}
sum += val;
});
$(this).closest('tr').find('input.total').val(sum);
});
The important things to note are the .closest() function, and the .find() function.
First, we bind to the change event for all inputs with a class of sum. When one of those elements is changed (the value changes, then the user clicks/tabs out), we look for the closest tr element, then find the list of inputs with a class of sum that are children of that tr. For each of those inputs, we parse the value and accumulate the sum. After we've iterated over each of those inputs, we finally find the input with a class of total that's a descendant of the closest tr, and set the val of that input to the accumulated sum
Perfect!
Great question and great answer! This works perfectly! To answer Mike, I changed 'tr' to 'table' in the jQuery and it totals all the sums in a table across several tr's and td's. As long as the inputs have the class="sum" they will be totaled.