I have a webshop and with jquery i need to check when adding a product if it exists in cart, then it should increase quantity instead of creating a new row.
The code i use to check if it exists in cart is the following:
if ($(".store-purchase-list-quantity-plus").attr('part') != SalesNO)
If this is true, it should add a new row. If its false it should add quantity.
SalesNO is the product id.
This works only for the first product in cart, then it just keeps adding a new row. It seems to me the if statement only checks the first ".store-purchase-list-quantity-plus", even if there are multiple of them in the DOM.
How do i change my if statement so it checks all .store-purchase-list-quantity-plus" after (attr = salesNO)
It's working exactly as it should. That's just not how you expect it to work.
From the documentation:
The .attr() method gets the attribute value for only the first element in the matched set. To get the value for each element individually, use a looping construct such as jQuery's .each() or .map() method.
There are a number of looping constructs available in jQuery, though given your particular need - finding out if there's an element that has a specific attribute value in a set of matched elements - using .filter() is probably the best choice.
var partExists = $(".store-purchase-list-quantity-plus").filter(function() {
return $(this).attr('part') == SalesNO;
}).length > 0; // there's an element with a part attribute matching SalesNO
if(partExists) {
// increase quantity
}
else {
// add new entry
}
if there are more matches on the page with class store-purchase-list-quantity-plus, you will still only select the first with $(".store-purchase-list-quantity-plus").
Make a loop to check all.
Related
I have a page where users input quantities for items and various totals are calculated using information pertaining to said items. I'm attempting to display aggregates of the items' totals and in order to properly obtain the values I need, I'm checking to make sure each element involved in the calculation has some kind of value before attempting to do anything. However, when I attempt to check, an error is thrown saying that the method is undefined.
if(itemTotals[i].innerHTML != "" && itemMaps[i].innerHTML != "" && itemCogs[i].innerHTML != "" && itemQuantities[i].value != ""){
//Increment totals
}
The itemQuantities[i].value part is what throws the error. I've tried using .val() and .attr("value") but none of them work. I merely get the message that whatever I tried isn't a function. How can I retrieve each input field's value in this context? Am I retrieving the input fields improperly?
The array is initialized as follows.
var itemQuantities = document.getElementsByClassName("inputQty");
The other arrays involved in calculations use the same .getElementsByClassName method and according to the console, all of the table cells pertaining to the class names I specified (they're not important to this scenario) are retrieved without error.
I just noted that you are indexing the variables with a "i" indexer, so if these lists doesn't have the same length, you are in trouble.
Just make sure that these lists are symmetrical and have the same length.
.val() and .attr() are jQuery methods. They don't exist in normal Javascript.
You get the elements with this:
var itemQuantities = document.getElementsByClassName("inputQty");
getElementsByClassName is a 'normal' javascript method. So you don't get jQuery additions to the elements by default.
try this way:
var itemQuantities = $('.inputQty');
then use the .val() and .attr() methods on them.
and instead of using index to iterate through the list you can do it like this:
itemQuantities.each(function(item) {
...
doWhateverYouWantWithEach($(item));
...
});
or
itemQuantities.each(function() {
...
doWhateverYouWantWithEachItem($(this));
...
});
The .value attribute works. I just wasn't properly checking to see if the input was empty. The input in the quantity boxes is used to multiply various costs in order to determine certain aggregates. I wound up using isNaN() to achieve the desired result.
I wish to change the name attribute at dynamic in JavaScript, but I couldn't change the name attribute using either element.name or the setAttribute() method. Is there any other way to set the name attribute?
var status_Element = document.getElementsByName("BD_task_status_"+old_id+"[]");
var final_status_Element = document.getElementsByName("BD_final_task_status_"+old_id+"[]");
for(var in_count=0;in_count<status_Element.length;in_count++)
{
status_Element[in_count].name="BD_task_status_level"+inner_count+"[]";
final_status_Element[in_count].name="BD_final_task_status_level"+inner_count+"[]";
}
Setting the name property as in your example will work (other than the inner_count vs in_count typo). The issue is that getElementsByName returns a live collection of elements. When you change the name of the element at index 0, it no longer belongs in the collection and the collection drops it; then the element that used to be at index 1 is now at index 0. But in the meantime, you've incremented in_count and so you never end up changing that element. Half of them will end up not being changed.
Either:
Loop backward through the collection to change the names (since then the element that disappears is at the end and you don't care), or
Use querySelectorAll instead, which gives you a snapshot collection (not a live one). (querySelectorAll is supported on all modern browsers, and also IE8.)
In the javascript, there are two arrays:tags[] and tags_java[]. I use .splice to delete certain items, which of the same index in the two arrays. The tags[] works fine, but tags_java doesn't, it seems always delete the last item.
Here is the code and the jsfiddle link.
var tag = $(this).text();
var index = $.inArray(tag, tags);
tags.splice(index,1);
tags_java.splice(index,1);
Nah, both don't work, because you're not actually finding the correct index of your tag.
Why not? Because $(this).text() includes the delete mark you added, Ă— - e.g. "MorningĂ—". Since that's not in your tags array, index will be -1. tags.splice(-1, 1); will remove 1 item from the end of the array.
In general, it's never a good idea to use presentation text (i.e. the text of your tag element) as data (e.g. using that text as a lookup value in an array). It's very likely that it'll be broken when something changes in the presentation - like here. So a suggestion would be to store the data (what you need to look up the tags) as data - e.g. using the jQuery-provided data() API - even if it seems redundant.
Here's a quick example - just adding/replacing two lines, which I've marked with comments starting with "JT": JSFiddle
Now, instead of looking up by $(this).text(), we're looking up by the data value "tagValue" stored with $(this).data() - that way, the lookup value is still bound to the element, but we're not relying on presentation text.
If the tag is not in the tags array, $.inArray will return -1, which would then cause the last item to be deleted.
You have to make sure that the item is actually in the array.
I have a <SELECT multiple="multiple"> box with options.
I store the selected options in a JS variable - selectedFeatures.
I want to pass selectedFeatures array variable of options to jQuery.inArray() - but the function is designed to take and check for one value only.
I can show/hide( or filter ) the markers on my map if I actually specify an index of an element like so: selectedFeatures[0] inside inArray()
..but since I may select multiple options from a select box this method of filtering doesn't work.
How can I check if an array of items in found inside another array with JS/jQuery?
// store selected options as an array of string elements inside the variable
var selectedFeatures = $("#features").val();
// for every element inside 'markers.houses' array...
$(markers.houses).each(function(index, elem){
// check if any of the values inside the 'selectedFeatures' array are found
// also inside a sub-array 'features' inside every element of 'markers.houses'
// array. if 'true' show that particular marker, otherwise hide the marker
if(jQuery.inArray(selectedFeatures, elem.features) !== -1 || jQuery.inArray(selectedFeatures, elem.features) > -1){
markers.houseMarkers[index].setVisible(true);
}else{
markers.houseMarkers[index].setVisible(false);
}
});
Fig 1.1 - store selected options in an array variable and use it with jQuery.inArray()
What you are asking for can be solved with PHP's array_diff function. I know you're not using PHP, but that's why there is array_diff on PHPJS, a project dedicated to porting PHP functions into JavaScript.
Anyway, to solve this you basically want to call array_diff(selectedFeatures,elem.features).length == 0. (You may need to swap the arguments around, I'm not sure which array is which in your question)
array_diff returns the elements of the first array that are not present in the others. If all of the elements in the first array are also in the second array (ie. array1 is a subset of array2), then the returned array will be empty, hence its length is zero.
Check this library: underscore.js
And you could use _.difference(array, *others).
Or you can create your own function to check if values from one array are in another array.
I'm trying to append all the selected items from listbox 1 to listbox 2, and it's working fine. The problem is that I want to set the item values of the listitems on listbox 2 to an ID i get from JSON.
I have the ID from JSON, but I'm not sure how to set the values when I use appendTo.
Here's the code I'm using now, when the values is set to "0":
$('#ListBox1 option:selected').appendTo('#ListBox2');
I think I have to do something like this:
var numberOfSelectedItems = $('#ListBox1 option:selected').length;
for(int i = 0; i < numberOfSelectedItems; i++)
{
var ID = data.array[i].ID; //This is the ID value from JSON.
//TODO: Set the ID as value on each selected item
}
Please help =)
You should be able to set use the .attr() jQuery function to set the id on each item, perhaps combined with using Javascript's helpful array functions to the next ID in the list.
Something like...
$('#ListBox1 option:selected')
.attr('id', data.array.shift())
.appendTo('#ListBox2');
JQuery allows you to chain together successive operations on a given selection, so you can set the id attribute on each before appending it to your second list.
data.array.shift just removes and returns the first item in the array, so each time this is called (for each list item) you'll get the next id assigned to the list item being processed.
Of course, if you need use data.array afterwards you may need to copy it first.