jQuery selector: match array attribute's n-th value - javascript

I have an attribute for a set of HTML5 objects that is an array. Something like
<button attr=[1,0,0,0,1,1]>test</button>
<button attr=[1,1,0,0,1,1]>test</button>
...
How do I formulate a jQuery selector to match only elements whose n-th value of attr is 1? Something like $("attr[1]=1") that would only select the second button from this example (this syntax does not work, but I wrote it just to give an idea of what I need).
In my case I am not dealing with buttons but with other types of objects, I just wanted so simplify the context of the question.

You can use a custom filter to select only the matched elements.
<button data-attr="[1,0,0,0,1,1]">button 1</button>
<button data-attr="[1,1,0,0,1,1]">button 2</button>
Note that attr is not a valid html attribute for button. I'd suggest you use the data-attr instead. You can use .data('attr') to get the data back.
var selected = $('button').filter(function (idx) {
var attr = $(this).data('attr');
return attr && attr[1] == 1;
});
alert(selected.html());
jsFiddle Demo

You can write your own selector like this (i called it "array", you can use a better name here):
jQuery.expr[':'].array = function (elem, index, match) {
var params = match[3].replace(/^\s+|\s+$/g, '').split(/\s*,\s*/),
attribute = params[0],
arrayindex = parseInt(params[1]),
matchvalue = params[2],
value = JSON.parse($(elem)[attribute](attribute));
return value[arrayindex] == matchvalue;
};
Then, use it like any other selector where the first parameter is the name of the attribute, the second parameter is the index in your array and the third parameter is the expected value:
$('button:array(attr,1,1)');
Fiddle: http://jsfiddle.net/pascalockert/uDnK8/2/

Related

How do I retrieve an attribute's name using the nodeName property?

You can easily retrieve the tag name of an element using the nodeName, like this:
var atnode = document.getElementById("link-test");
alert(atnode.nodeName);
link
But how do I use the nodeName to get the attribute of the element instead?
Using the getAttribute() does not do what I want, because you have to insert the name of the attribute first, and then it just gives you back the value of the attribute. I want to get the name of the attribute just like I did with nodeName. I know nodeName can be used with attribute nodes too, but how?
const atnode = document.getElementById("link-test");
const nodes=[];
const values=[];
for (let att, i = 0, atts = atnode.attributes, n = atts.length; i < n; i++){
att = atts[i];
nodes.push(att.nodeName);
values.push(att.nodeValue);
console.log(att.nodeName + " - " + att.nodeValue);
}
link
After using attributes method you can use nodeName to get the attribute name and nodeValue to get the value of the attribute.
After pushing it to array you can get attribute and value of it using same index in both arrays.
You can get a list of the attributes with getAttributeNames() on the node. In your example, you could do like so:
atnode.getAttributeNames() This will return ["href", "id"].
Then you can loop through the list with getAttribute(<item from list as string>) to get the values of the element's attributes.
If I understood right, you just need to use the getAttributeNames method.
Follows an example:
const exampleElement = document.getElementsByTagName("example")[0];
console.log(exampleElement.getAttributeNames());
<example name="one" last="two"></example>

How to get value from text box by name which is dynamic

I need a value of text box for that I am using document.getElementsByName("elemntName") but the problem is the the name itself is dynamic, something like below.
for(temp = 0 ; temp < arracid.length ; temp++){
cell1=mynewrow.insertCell(4);
cell1.innerHTML="<input type='hidden' name='ACID"+index+"' class='tblrows' id='ACID"+index+"' value='"+arracid[temp]+"'>";
index++;
}
When I tried var acidCount = document.getElementsByName('ACID') its not working and I tried
var acidCount = document.getElementsByName('ACID"+index+"') still not working
For every loop the name is changing like ACID1,ACID2 etc.. can anyone help me how to get the value of this text box?
Since you are already assigning an ID to your inputs, it's recommended to use getElementsById which is faster than getElementsByName (and more accurate because the IDs are supposed to be unique, while the names don't have to be). Try this:
var acidCount = document.getElementById("ACID" + index);
If you still want to use getElementsByName, try this:
var acidCount = document.getElementsByName("ACID" + index);
But remember that getElementsByName returns a list of elements, but the list has only one element, because your names are unique. If you want to get that element in the list, you can use it's index like this:
var acidCount = document.getElementsByName("ACID" + index)[0];
Alternatively, if you want to get the list of all your inputs, first remove the index from the name:
cell1.innerHTML="<input type='hidden' name='ACID' class='tblrows' id='ACID"+index+"' value='"+arracid[temp]+"'>";
Then use:
var acidCount = document.getElementsByName("ACID");
Note: all the above return the DOM element(s). If you're only interested in the value, use the value property:
var acidCount = document.getElementById("ACID" + index).value;
or
var acidCount = document.getElementsByName("ACID" + index)[0].value;
(This is a jquery solution, since the question was initially tagged with jQuery)
You can use the selector of input elements with name starting with ^= ACID:
$("input[name^=ACID]").each(function(){
console.log($(this).val());
});
Issue is with single quoutes and double quotes :
var acidCount = document.getElementsByName("ACID"+index)
Since there can be more than one element with same name, so we need to get first element with that name, I have corrected your query check this, it will work.
var acidCount = document.getElementsByName('ACID'+index)[0].value
Try using wildcard * in the selector which will return all matched elements
document.querySelectorAll('[id*=ACID]')
You can try using class name.
$(document).find(".tblrows").each(function(){
console.log($(this).val());
});
Since you are naming your elements 'ACID' + index, you can utilize the querySelector method as follows:
for (var i=0; i < arracid.length; i++) {
var $el = document.querySelector('#ACID' + i));
}

Remove selector criteria in variable value

I'm creating an online shop, with specific links to products e.g. (http://example.com/products/phones/nexus-5).
I'm using the following code,
var get_product_availability_classname = $("[class$='_availability']").attr('class');
which selects (creates a variable with the value of) the element that has a class ending in "_availability".
Every product page has a different piece of text just before the _availability, like GOOGLENEXUS5_availability, SAMSUNG4KTV_availability, whatever_availability...
What I have to do now is to essentially remove the criteria I used to get that whole class name (i.e. class$='_availability'); using the example above it'd be trimmed from SAMSUNG4KTV_availability to SAMSUNG4KTV.
Possible solutions
I haven't figured how to, but we could use JavaScript's substring() or substr().
You will be best off using Regex in this situation. The following will look for the _availability in the classes string and if it finds it it will capture what came before.
var get_product_availability_classname = $("[class$='_availability']").attr('class');
var matches = /([^\s]*)_availability\b/g.exec(get_product_availability_classname)
if(matches.length > 1){
var your_id = matches[1];
}
Use attr() method with a callback and update the class name using String#replace method with word boundary regex.
Although use attribute contains selector since there is a chance to have multiple classes, in that case, the class can be at the start or between two classes.
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class',function(i,v){
return v.replace(/_availability\b/g,'');
});
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class', function(i, v) {
return v.replace(/_availability\b/, '');
});
console.log(document.body.innerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="abc_availability"></div>
<div class="abc_availability class"></div>
<div class="class abc_availability"></div>
<div class="class abc_availability class1"></div>
If there will only ever be a single _ in the class name
var get_product_availability_classname = $("[class$='_availability']").attr('class')
.split(' ') // split the class to individual classes
.filter(function(cls) { // filter ones with _availability
return cls.split('_').pop() == 'availability');
})[0]; // use first match
var product = get_product_availability_classname.split('_')[0]
.split('_') creates an array ["PRODUCT", "availability"] and the [0] selects the first item of this array
alternatively you could also
var product = get_product_availability_classname.split('_availability')[0]
this does the same thing, except it splits on the string _availability, and it doesn't matter how many _ in the prefix
If your string is always in the form x_y, where x and y don't contain an underscore, then you can use the split function to split on the underscore.
var str = "SAMSUNG4KTV_availability";
var result = str.split("_")[0];
console.log(result);
The split function returns an array of strings containing the substring in between each underscore, you use [0] to select the first element in the array.

How to extract onChange method's String parameters using Regex?

I have select elements as below
<select name="selectid1" id="selectid1" onChange="script.selectChange(this,'tr');">.......</select>
and
<select name="selectid2" id="selectid2" onChange="script.selectChange(this,'div');">.......</select>
I want to extract the selectChange method's String paramter (the 2nd paramter) tr and div of the onChange attribute of both the select elemets using regular expresssion.
I can get the value of onChange using
var selectid1 = $('#selectid1').attr('onChange'); //script.selectChange(this,'tr');
and
var selectid2 = $('#selectid2').attr('onChange'); //script.selectChange(this,'div');
What regex should I use in order to get strings 'tr' and 'div' from the variables?
If it's just for test case - use the following approach with String.match function:
var selectid1 = "script.selectChange(this,'tr')",
param = selectid1.match(/,\s?['"]([^)]+)['"]/)[1];
console.log(param); // tr
/onChange="script.selectChange\(this,'([^']*)'/g
Demo here --> https://regex101.com/r/uW2aQ6/1

Find element from jQuery matching objects

I have a click event listener as below:
$(".clickable").click(function (e) {
var results= $(e.currentTarget).closest('div.set').find('.clickable');
// returns
//[<label for=​"thumbnail" class=​"clickable">​1 Malaysia​</label>​,
//<div class=​"thumbnail clickable">​…​</div>​]
var label = $(results).find('label'); // returns [] (empty list)
}
My problem is, how can I select the label element from the results list ? Thanks !
Try to use .filter() instead of .find(),
var label = results.filter('label');
.find() will search for descendants, but here we are in need to filter out the required element from the collection, so use .filter(selector) here.
And also you could have simply used as satpal said like,
var results= $(e.currentTarget).closest('div.set').find('label.clickable');

Categories