I have a super simple fiddle... but when I do an inspect element, $("#cart table") and frankly $("#add"), $("#remove"), $("#cart") all return null even though these items are on the page... what am I doing wrong?
(Consequently what's breaking is my line $("#cart table").find("tr").length())
https://jsfiddle.net/qb3a6j31/
Basically, length is a property, not a function,
$("#cart table").find("tr").length
DEMO
Your full code would be,
$(document).on("click", "#add", function(e) {
e.preventDefault();
var next_item_number = parseInt($("#cart table").find("tr").length) + 1
var item =
'<tr>' +
'<td>Item #' + next_item_number + '</td>' +
'</tr>'
$("#cart table").append(item)
});
1) You're not loading jQuery in your jsFiddle
2) This won't work
$("#cart table").find("tr").length()
...because there are no table rows available when you initially click the add button.
3) When you do have rows, it's .length.
I would be inclined to write it like this. It gets the rows, and if there are some uses length, otherwise 1.
var $rows = $("#cart table").find("tr");
var next_item_number = parseInt($rows.length || 1, 10);
DEMO
You have used length as a function but it is a property. Use length instead of length()
$("#cart table").find("tr").length
UPDATED FIDDLE
Uncaught TypeError: $(...).find(...).length is not a function
length is a numeric property, not a function. Replace your code with this:
parseInt($("#cart table").find("tr").length)
And it will work. Note: You may want to add an explicit 10 radix parameter to parseInt.
Related
I'm not the best at using jQuery, but I do require it to be able to make my website user-friendly.
I have several tables involved in my website, and for each the user should be able to add/delete rows. I created a jquery function, with help from stackoverflow, and it successfully added/deleted rows. Now the only problem with this is the names for those input fields is slightly messed up. I would like each input field to be an array: so like name[0] for the first row, name[1] for the second row, etc. I have a bunch of tables all with different inputs, so how would I make jQuery adjust the names accordingly?
My function, doesn't work completely, but I do not know how to go about changing it.
My Jquery function looks like:
$(document).ready(function() {
$("body").on('click', '.add_row', function() {
var tr = $(this).closest('.row').prev('table').find('tr.ia_table:last');
var clone = tr.clone();
clone.find("input").val('');
clone.find("select").val('');
clone.find('input').each(function(i) {
$(this).attr('name', $(this).attr('name') + i);
});
clone.find('select').each(function(i) {
$(this).attr('name', $(this).attr('name') + i);
});
tr.after(clone);
});
$("body").on('click', '.delete_row', function() {
var rowCount = $(this).closest('.row').prev('table').find('tr.ia_table').length;
var tr = $(this).closest('.row').prev('table').find('tr.ia_table:last');
if (rowCount > 1) {
tr.remove();
};
});
});
I also created a jsFiddle here: https://jsfiddle.net/tareenmj/err73gLL/.
Any help is greatly appreciated.
UPDATE - Partial Working Solution
After help from a lot of users, I was able to create a function which does this:
$("body").on('click', '.add_row', function() {
var tr = $(this).closest('.row').prev('table').find('tr.ia_table:last');
var clone = tr.clone();
clone.find("input").val('');
clone.find("select").val('');
clone.find('input').each(function() {
var msg=$(this).attr('name');
var x=parseInt(msg.split('[').pop().split(']').shift());
var test=msg.substr(0,msg.indexOf('['))+"[";
x++;
x=x.toString();
test=test+x+"]";
$(this).attr('name', test);
});
clone.find('select').each(function() {
var msg1=$(this).attr('name');
var x1=parseInt(msg1.split('[').pop().split(']').shift());
var test1=msg1.substr(0,msg1.indexOf('['))+"[";
x1++;
x1=x1.toString();
test1=test1+x1+"]";
$(this).attr('name', test1);
});
tr.after(clone);
});
A working jsFiddle is here: https://jsfiddle.net/tareenmj/amojyjjn/2/
The only problem is that if I do not select any of the options in the select inputs, it doesn't provide me with a value of null, whereas it should. Any tips on fixing this issue?
I think I understand your problem. See if this fiddle works for you...
This is what I did, inside each of the clone.find() functions, I added the following logic...
clone.find('input').each(function(i) {
// extract the number part of the name
number = parseInt($(this).attr('name').substr($(this).attr('name').indexOf("_") + 1));
// increment the number
number += 1;
// extract the name itself (without the row index)
name = $(this).attr('name').substr(0, $(this).attr('name').indexOf('_'));
// add the row index to the string
$(this).attr('name', name + "_" + number);
});
In essence, I separate the name into 2 parts based on the _, the string and the row index. I increment the row index every time the add_row is called.
So each row will have something like the following structure when a row is added...
// row 1
sectionTB1_1
presentationTB1_1
percentageTB1_1
courseTB1_1
sessionTB1_1
reqElecTB1_1
// row 2
sectionTB1_2
presentationTB1_2
percentageTB1_2
courseTB1_2
sessionTB1_2
reqElecTB1_2
// etc.
Let me know if this is what you were looking for.
Full Working Solution for Anyone Who needs it
So after doing loads and loads of research, I found a very simple way on how to do this. Instead of manually adjusting the name of the array, I realised that the clone method will do it automatically for you if you supply an array as the name. So something like name="name[]" will end up working. The brackets without any text has to be there. Explanation can't possible describe the code fully, so here is the JQuery code required for this behaviour to work:
$(document).ready(function() {
$("body").on('click', '.add_row', function() {
var tr = $(this).closest('.row').prev('table').find('tr.ia_table:last');
var clone = tr.clone();
clone.find("input").val('');
tr.after(clone);
});
$("body").on('click', '.delete_row', function() {
var rowCount =
$(this).closest('.row').prev('table').find('tr.ia_table').length;
var tr = $(this).closest('.row').prev('table').find('tr.ia_table:last');
if (rowCount > 1) {
tr.remove();
};
});
});
A fully working JSfiddle is provided here: https://jsfiddle.net/tareenmj/amojyjjn/5/
Just a tip, that you have to be remove the disabled select since this will not pass a value of null.
I have a span field that has a number generated by counting items in a session array. when a user adds an item to the cart I need to increment this value by 1. I've tried the parseInt function but it doesn't seem to work. console shows the id is being selected. Just can't seem to increment by 1.
jQuery code is:
var checkout_number = parseInt($('#checkout-count').html());
console.log(checkout_number); // Shows value 2 etc
upon success increment by current checkout_number by 1:
$.parseInt($("#checkout-count").val(),10) + 1;
Any help would be great
In your example you're not actually incrementing the HTML value of the checkout-count element - try this instead:
// use the HTML of the checkout-count span as the current checkout number
var checkout_number = parseInt($('#checkout-count').html(), 10);
// replace the HTML of the checkout-count span with the old value plus one
$('#checkout-count').html(checkout_number + 1);
You need to use parseInt function to adding the value in jquery
var checkout_number = parseInt($('#checkout-count').text(), 10);
$('#checkout-count').text(checkout_number + 1);
Try this this works fine.
$('#checkout-count').text(parseInt($("#checkout-count").text()) + 1);
Working Demo
$(function() {
$('#checkout-count').text(function() {
return +(this.innerHTML) + 1;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<span id="checkout-count">2</span>
I am currently attempting to write a function that applies unique ids to list item dynamically by ticking checkboxes, though I have encountered a problem, when appending the unique id to the list item I get the following error message in the console:
Uncaught TypeError: Object SpTU 4, 183:false<br /> has no method 'append'
Here is the code that is causing the error:
strng += name+":"+val+"<br />";
var i = 1;
strng.append($({ type: "text", id:+i }));
I need help with this quickly so any help would be greatly appreciated!
Thanks in advance
-------EDIT----------
Here is the whole function so it is easier to understand, I am new to programming to it may be very messy and unproffesional.
var dataToShow = {};
function check(tickbox){
dataToShow[tickbox.value] = tickbox.checked == true;
showDataOnScreen(dataToShow);
function showDataOnScreen(dataToShow){
var $strng = "";
jQuery.each(dataToShow,function(name,val){
$strng += name+":"+val+"<br />";
var i = 1;
$strng.append($({ type: "text", id:+i }));
});
jQuery("#list").html(strng);
Ensure that strng is a JQUERY object, assuming you are using JQUERY
If you are trying to build a list of checked items, I would go about it this way.
// create an array to store the checked items
var checkedItems = new Array();
// loop through the checked check boxes contained in the list element
// and add them to the array
$("#list :checked").each(function (){
var item = { name: $(this).attr("name"), value: $(this).val() };
checkedItems.push(item);
});
Or, even better, if you plan on displaying the results in a different element, you can cut out the array.
// loop through the checked check boxes contained in the list element
// and add them to a different element
$("#list :checked").each(function (){
var item = "<div>"+ $(this).attr("name") + ": " + $(this).val() + "</div>";
$("#selectedList").append(item);
});
Here's a working example on jsFiddle.
References:
Array: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
jQuery each(): http://api.jquery.com/jQuery.each/
jQuery :checked selector: http://api.jquery.com/checked-selector/
jQuery append(): http://api.jquery.com/append/
This may have been answered before, but I cannot find a solution that works.
I need to add the subtotal input boxes up and output them as a grandTotal. Sounds simple, and I thought it would be, but for some reason I cannot get it to function properly.
To save time I have created a jsFiddle - http://jsfiddle.net/wgrills/hKxgU/4/
Edit: Sorry to be poor at posting the question.
I missed out most of the items because I wanted to speed the jsfiddle up. I have updated the jsFiddle - http://jsfiddle.net/wgrills/hKxgU/7/.
If you click on the + or - buttons the subtotal changes, that is all good. But I can't get the #grandTotal input to update. The problem appears to be with the:
var grandTotal = 0;
$(".subtotal").each(function() {
$(this).css("border-color","#f00");
grandTotal += $(this).val.split("£")[1];
});
$("#grandTotal").val("£" + grandTotal);
alert(grandTotal);
part of the js. Note the css border change and the alert is just there for me to make sure the script is working.
The code is all early days, this is just a quick mock up.
You gave two problems, very easy to solve!
You are correct that the piece above that you posted is part of the problem. In particular the line:
grandTotal += $(this).val.split("£")[1];
You missed the () after val, so the code WOULD have broken here, because it doesn't know what .val. is.
Also, the code you posted was after a return false; this effectively tells the function is has finished, don't bother doing anything after that line.
However, as you need that section of code in both functions (clicks) its worth wrapping it in a function of its own:
function updateGrandTotal() {
var grandTotal = 0;
$(".subtotal").each(function() {
$(this).css("border-color", "#f00");
grandTotal += parseFloat($(this).val().split("£")[1]);
});
$("#grandTotal").val("£" + grandTotal);
alert(grandTotal);
}
And calling it just before you inform the function its finished:
updateGrandTotal();
return false;
See it partially working here
However, while this will work on the plus of an item, you have another problem, when you are minusing an item, and the box gets to zero, instead of setting £0.00 you set it to 0, hence when it try's to split on the "£" it can't. To combat this simply copy the bit where you turn your price value into a price from the plus function into the minus function:
Replace:
newprice = price * x;
$('#' + update).val(x);
$('#' + update + '_subtotal').val(newprice);
With the working version:
newprice = (price * x) / 100;
newprice = newprice.toFixed(2);
newprice = '£' + newprice;
$('#' + update).val(x);
$('#' + update + '_subtotal').val(newprice);
See it fully working here
Your problem is with the following line:
grandTotal += $(this).val.split("£")[1];
val is a function, not a property on the returned object. You want the following instead:
grandTotal += $(this).val().split("£")[1];
Also in your fiddle you have a return false; in the middle of your function, which lies above the code you're calling val incorrectly on. Remove that return as well.
Here is the code.
function product_analysis_global() {
$(':checkbox:checked').each(function() {
$('#product_' + this.alt).load(this.title);
$('#product_quantity_PRI_' + this.alt).value = this.value;
});
}
All working except the last line that is not working, any ideas. Should return the value of the current checkbox to the appropriate field '#product_quantity_PRI_' + this.alt
Many Thanks.
.value isn't a jQuery object property (it's a DOM object one), it should be .val() like this:
$('#product_quantity_PRI_' + this.alt).val(this.value);
Or (more for illustration), the direct jQuery-less DOM method:
document.getElementById('product_quantity_PRI_' + this.alt).value = this.value;
Use the val() function.
var $this = $(this)
$('#product_quantity_PRI_' + $this.attr('alt')).val($this.val());