select.val returning undefined in array - javascript

I'm doing the following:
$('#clear-button').click(function () {
var clearableFieldArray = $('.clearable-field');
var array = Array.prototype.slice.call(clearableFieldArray);
for (var i = 0; i < 7; i++) {
if (i == 6) {
array[i].val('');
} else {
array[i].val('All');
}
}
});
when I do console.log(array[i]) it prints the correct elements and children, however when I try to access the .val() it keeps returning undefined, why is it doing that

You can wrap $(array[i]) with the jQuery selector because it looks like you are not selecting a jQuery object but a regular DOM object.

if its one of the first 6 elements, its a select, so set the value to "All" which is an option I have, otherwise the 7th element is a text input, so set the val to ""
In this case you can simplify your code without the need for arrays:
$('#clear-button').click(function () {
$('input.clearable-field').val('');
$('select.clearable-field').val('All');
});

Related

Loop works just 16 times instead of 36

Hello I am now at black out mode while trying to create this loop
The code is like this :
function finished() {
var summaryDiv = document.createElement("DIV");
summaryDiv.setAttribute("id","summary");
document.getElementById("main_content").appendChild(summaryDiv);
var summaryLabel = document.createElement("P");
summaryLabel.setAttribute("id","score");
document.getElementById("summary").appendChild(summaryLabel);
var radios = document.getElementsByTagName('input');
var value = 0;
for (var i = 0; i < radios.length; i++) {
if (radios[i].type === 'radio' && radios[i].checked && radios[i].value == "true") {
value += 1;
console.log(value);
} else {
console.log(value);
}
document.getElementsByClassName("qcontainer")[i].style.display = "none";
document.getElementById("score").innerHTML = value;
}
}
//The value of radios.length is 36, and it seems like it takes the value only of first 16 radio buttons, it doesnt matter if another 8 radio buttons have value TRUE it always returns only TRUEs from the first 16 radio Buttons, I know it might be a little bit confusing but I don't know what is wrong with this loop.
document.getElementsByTagName returns a live HtmlCollection. This means that when you remove an element from DOM, either through removeChild or by setting innerHTML of a parent the collection is updated.
A possible way to loop over a live HtmlCollection like this is to perform a while on the .length of the collection.
while (radios.length) {
// Use radios[0]
// Remove radios[0] from DOM
}

How to check for attribute value

Please advise me if I am using correct syntax here for checking if “aria-expanded” is true for a particular set of elements with css class “classname”:
if ($(‘.classname’).hasAttribute('aria-expanded','true')) {
 output here
}
jQuery doesn't have a hasAttribute method, so I'm assuming $ = docuument.querySelector. (Note: not document.querySelectorAll; so, you're only considering a single element).
The hasAttribute method takes a single parameter: the name of the attribute you are checking for. To check that attribute's value, you'll need to use getAttribute and then compare that. So you might do:
if( $('.classname').getAttribute('aria-expanded') === 'true') {}
If you are using jQuery, then you can just use the attr method:
if ($('.classname').attr('aria-expanded') === 'true') {}
See also the MDN docs for hasAttribute.
If you're trying to check a set of elements, you could do something like this:
function allHaveAttribute(elements, attrName, attrValue) {
// First, check that all elements have the attribute
for (var i = 0; i < elements.length; i++) {
if (!elements[i].hasAttribute(attrName)) return false;
}
if (attrValue) { // if we're checking their value...
for (var i = 0; i < elements.length; i++) {
if (elements[i].getAttribute(attrName) !== attrValue)
return false;
}
return true;
} else { // we know all elements have the attribute
return true;
}
}
var els = document.querySelectorAll('.classname');
if (allHaveAttribute(els, 'aria-expanded', 'true') {
// action here
}
JSBin Example: http://jsbin.com/payaqijeqa/edit?js,console
jQuery doesn't have a .hasAttribute function
If it did, it would most likely only work on the first of the set
The following uses native JavaScript (ES5) to check that .every element in the set document.querySelectorAll('.classname') has that attribute set to true.
let allSet = [].every.call(document.querySelectorAll('.classname'), function(el) {
return el.getAttribute('aria-expanded') === 'true';
});
NB: the above test is case sensitive. It also ignore any elements that don't have that attribute at all. If the latter is an issue:
let allSet = [].every.call(document.querySelectorAll('.classname'), function(el) {
return el.hasAttribute('aria-expanded') && el.getAttribute('aria-expanded') === 'true';
});
You can check to see if every element with class "className" has the attribute "aria-expanded='true'" with:
if( $(".className").length === $(".className").filter("[aria-expanded='true']").length) {
//output here
}
CSS has attribute selectors that allow selection of elements with certain attributes. If you negate the selector (which is unique to jQuery), you can test if there are any elements that have the class but don't have the attribute value by using:
$(".className[aria-expanded!='true']").length == 0

Jquery length of matched query

How would I write both of these without using .each() and only using JQuery Selectors?
var xxxx = 0;
$('.clonedInput').each(function(index) {
if($(this).children().filter(':checked').length == 2)
xxxx++;
});
var num_normal_foods = 0;
$('[id^="amount_"]').each(function(index) {
if($(this).val() == '30.00')
num_normal_foods++;
});
Lets take this one step at a time.
You started with:
var xxxx = 0;
$('.clonedInput').each(function(index) {
if($(this).children().filter(':checked').length == 2)
xxxx++;
});
To me this looks like you're simply trying to filter a collection of .clonedInput elements and find out how many match the filter:
var xxxx;
function hasTwoCheckedChildren(i) {
return $(this).children(':checked').length == 2;
}
xxxx = $('.clonedInput').filter(hasTwoCheckedChildren).length;
Followed by:
var num_normal_foods = 0;
$('[id^="amount_"]').each(function(index) {
if($(this).val() == '30.00')
num_normal_foods++;
});
Again, this looks like a filtering function to me:
var num_normal_foods;
function valueIsThirty(i) {
return +$(this).val() === 30;
}
num_normal_foods = $('[id^="amount_"]').filter(valueIsThirty).length;
In the end, what matters is that the code does what you intend it to do. If the code you wrote with .each does what you want it to, then there's no need to change it. Behind-the-scenes filter uses each anyway.
jQuery selections have a .length property:
var len = $('.clonedInput :checked').length;
var len2 = $('[id^="amount_"][value="30.00"]').length;
the first query returns all of the checked children of any .clonedInput class, then counts them.
the second query finds all of the id's that begin with amount_ and have a value of "30.00". (property queries can be chained like that [][])
EDIT: to satisfy #Blazemonger
to get the value of any type of element (value works on some), use this:
var len2 = $('[id^="amount_"]').filter(function() {
return $(this).val() == "30.00";
}).length;
Double EDIT because i'm useless
var len = $('.clonedInput').filter(function(){
return $(this).children(':checked').length == 2;
}).length;

How to go over all inputs that have a custom attribute

I have a form with checkboxes.
All of the checkboxes have an attribute called att, which contains several numbers that are separated by commas.
I'd like to create a function that gets a number, goes over all the checkboxes and checks all the checkboxes that their att attribute contains that number.
Can please someone point me at the right direction?
Using jQuery you can do something like
function myfunc(num)
{
$(":checkbox[att!='']").each(function()
{
var i, l, values = $(this).attr("att").split(",");
for (i = 0, l = values.length; i < l; ++i)
{
if (values[i] == num)
{
$(this).attr("checked", "checked");
break;
}
}
});
}
With JQuery you would use the attribute-contains selector to get all elements where an attribute contains a certain value.
$('input[att*="100"]').val('input has 100 in it!');
This loops over all input elements and gives you an array containing the values of att (split using the comma), so I'd add some logic to pick out only checkboxes:
for (var i = 0; i < document.getElementsByTagName('input'); i++)
{
var att_array = document.getElementsByTagName('input')[i].getAttribute('att').split(',');
}
This will get you all inputs with the attribute ATTR and then alerts the val of each of those. You can, of course, do whatever you want with the val when you have it.
$("input[ATTR]").each(function(){
alert($(this).attr("ATTR"))
})
If you want to limit this to checkboxes, change the selector as is shown below
$(":checkbox[ATTR]").each(function(){
alert($(this).attr("ATTR"))
})

Is there a way to get jQuery selector expression text?

I have an array of selectors like :
var arr = [".discuss .title .post", ".post .desc" , ".eventlist .event"];
I want to loop through this array and attach a click event on it.
for(var i in arr){
$(arr[i]).click(function(){
//here I need the selector i.e. arr[i] expression - for some css work
});
}
Is there a way by which I can get this selector expression inside the click callback function?
I went through this post which has similar problem : How do I get a jQuery selector's expression as text?
But as said there, I couldn't find any "selector" attribute of jQuery object. I tried this way:
for(var i in arr){
$(arr[i]).click(function(){
console.log(jQuery(this).attr('selector')); //This gives undefined
});
}
Any help?
The correct syntax is $('.something').selector. However, .selector only works when a selector string is explicitly supplied - but there is no selector in $(this).
One workaround is to save a copy of the selector in a function surrounding the click function:
for (var i = 0; i < arr.length; i++) { // (Don't use "for-in loop" for arrays)
(function (selector) { // 2. a copy is saved as the argument "selector"
$(selector).click(function () {
console.log(selector);
});
}) (arr[i]); // 1. Pass in the selector
}
Another option is to compare $(this) to each selector in your array, using .is():
$(arr.join(',')).click(function () { // a quick way to select all selectors
var selector;
for (var i = 0; i < arr.length; i++) {
if ($(this).is(arr[i])) {
selector = arr[i];
break;
}
}
console.log(selector);
});
You can at least get the class value of each selected element:
$(this).attr("class");
Doesn't this provide sufficient info for what you intend to do?
I don't seem to get any error, its as though there is no .click() event, example here
But if you split your array and attach a click to every item in your array it seems to work for me.
// Trouble is you will attach two click's to a class="post" item:
var arr = [".discuss .title .post", ".post .desc" , ".eventlist .event"];
for(var a in arr){
var ar = arr[a].split(' ');
for(var i in ar){
$(ar[i]).click(function(e){
e.preventDefault();
var href = $(this).attr('href');
var sele = $(this).attr('selector');
console.log(href);
console.log(sele);
alert("HREF: "+href+" - Selector: "+sele);
});
}
}
Take a look at it in action here along with a solution to stopping adding two clicks.

Categories