In my searches I have found plenty of questions/answers on how to find elements that end with a specific string. I've done a quick search and have not found anything specific about how to find elements that end with a variable. I did find this question/answer about how to use Javascript variables in jQuery selectors in general but I cannot get it to work and I wonder if it's because I'm trying to work against a set of elements I've already filtered down to.
Here are some id's of the elements I've already filtered:
["ms-goal-select-0", "ms-goal-input-0", "ms-goal-select-1", "ms-goal-input-1", "ms-goal-select-2", "ms-goal-input-2"]
And here is the (beginning of) the for loop I'd like to use to find and work with the select and input elements:
for (var x=0;;x++) { //will break when element(s) not found
selectEl = filteredElements.find('[id$="select-' + x + '"]');
inputEl = filteredElements.find('[id$="input-' + x + '"]');
....
But the above does not find the elements starting from the first iteration when x==0. What am I doing wrong?
Try using filter instead of find:
for (var x=0;;x++) { //will break when element(s) not found
selectEl = filteredElements.filter('[id$="select-' + x + '"]');
inputEl = filteredElements.filter('[id$="input-' + x + '"]');
....
Find only looks for matching children of the elements in filteredElements, whereas filter looks at the elements themselves.
jQuery's .find() only searches in descendants. I think you want to do a .filter() instead. I'd write this using the version of .filter() that takes a function and use a regular expression to match the elements you want:
var filteredElements = $("div");
var selectEl = filteredElements.filter(function() {
return this.id.match(/.-select-\d*$/);
});
var inputEl = filteredElements.filter(function() {
return this.id.match(/.-input-\d*$/);
});
console.log(selectEl.toArray());
console.log(inputEl.toArray());
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="ms-goal-select-0"></div>
<div id="ms-goal-input-0"></div>
<div id="ms-goal-select-1"></div>
<div id="ms-goal-input-1"></div>
<div id="ms-goal-select-2"></div>
<div id="ms-goal-input-2"></div>
Related
I have several classes with the names like so:
.x-string
.y-string
.z-string
A dynamic part and a constant one. I have made an array containing the dynamic parts (x, y, z).
I want to loop through the array, take each name, concatenate "-string" to the end of it, and pass it as a class to be selected in jQuery.
Sort of like:
$(classList).each(function () {
let newClass = '.' + this + '-string'
$('.this-string')...
}
Is this possible and how would I go about it? Cheers.
I want to loop through the array,
jQuery works with arrays differently than it works with it's on jQuery object wrapper. So to loop through an array you'd use jQuery.each() or $.each().
var myArray = ['x', 'y', 'z'];
$.each(myArray, function(idxArray, valArray) {
// code
});
concatenate "-string" to the end of it, and pass it as a class to be selected in jQuery
Now we can use the jQuery selector with .each() to find matching elements
var myArray = ['x', 'y', 'z'];
$.each(myArray, function(idxArray, valArray) {
var selector = "." + valArray = "-string";
$(selector).each(function(idxElement, valElement) {
var $this = $(valElement);
// or
var $this = $(this);
$this.fadeOut();
});
});
It's important to note that the second .each() should only be used if you have specific logic to run after an item is found. If the code is the same for every element, then each is not needed:
var selector = "." + valArray = "-string";
// fadeOut all matching elements
$(selector).fadeOut();
It's also important to note that if the logic is as simple as your example, you should not need to loop at all. You can create a comma delimited string containing all the selectors.
var myArray = ["a","b","c","d"];
var selector = myArray
.map(s => "." + s + "-string")
.join();
$(selector).css("color", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Black</div>
<div class="a-string">Red</div>
<div>Black</div>
<div class="b-string">Red</div>
<div>Black</div>
<div class="c-string">Red</div>
<div>Black</div>
<div class="d-string">Red</div>
JQuery
$.each is used for iteration of the array. Which takes two arguments [index, element].
The element is the element of an array. Don't use this because it's not recommended!
$(classList).each((idx, elem) => {
$('.'+elem+'-string')
});
Native
To use the native method we'll use the [].forEach or for...of iteration.
NOTE: for...of method has only support from ES6.
// for...of loop
for(i of elem)
$(`.${elem}-string`)
// forEach loop
elem.forEach(function(elem) {
$('.'+elem+'-string')
});
Some general issues with your usage of .each. Try:
$(classList).each(function(idx, cls) {
let newClass = '.' + cls + '-string';
$(newClass) ...
});
The objective is to create multiple sliders on the page by linking the slider to something. The slider must be activated by clicking or hovering the slider anchor. sliderList would be a array for making this process easier so i wouldn't have to link each other manually on the configs js file.
I need to get the attribute value from a element that is inside an array. In this case, holder is the array from where I want to extract the attribute value from the current array element. I tried doing this:
var holder = $('[slider-select]');
for (var i = 0; i < holder.length; i++) {
var sliderList = $('[slider-target='
+holder[i].attr('slider-select')
+']');
}
It looks like +holder[i].attr('slider-select') isn't working. I'm learning JavaScript/Jquery and it's crazy how things goes wrong even when it makes all sense, lol. Let me know if I wasn't clear enough.
The function attr is a built-in function from jQuery, it's a shorthand of function getAttribute and setAttribute.
In your case you want to do this:
var holder = $('[slider-select]');
for (var i = 0; i < holder.length; i++) {
var test = holder[i];
var sliderList = $('[slider-target=' + holder[i].getAttribute('slider-select') + ']');
} ^
A good approach is to use the jQuery built-in functions, so you can use this:
$('[slider-select]').each(function() {
var sliderList = $('[slider-target=' + $(this).attr('slider-select') + ']');
}); ^
Resources
.attr()
getAttribute
setAttribute
.each()
holder[i] contains a plain DOM element, but you're trying to use the jQuery attr method on it. You need to convert it into a jQuery object $(holder[i]) (or else use the native getAttribute on the DOM element):
var holder = $('[slider-select]');
for (var i = 0; i < holder.length; i++) {
// Splitting this up a bit just to make it more readable:
var val = $(holder[i]).attr('slider-select'); // instead of holder[i].attr(...)
var sliderList = $('[slider-target="' + val + '"]');
// confirm we got the element:
console.log(sliderList.text());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div slider-select="A">A</div>
<div slider-select="B">B</div>
<div slider-select="C">C</div>
<div slider-target="A">a</div>
<div slider-target="B">b</div>
<div slider-target="C">c</div>
The attr method is not a function on the JS element object. You'll want to wrap it in jquery to retrieve attribute values instead. For instance
$(holder[i]).attr("slider-select")
I have a div element with lots of descendent's elements, all with ids in the form "word1", for a simple example: id="moviment1" or id="type1".
I need to get only the written part of these ids (moviment or type), in order to concatenate their names with a increment of 1 (id="moviment2" or id="type2").
$clone.find('*').each(function() {
var id = $(this).prop('id');
var num = parseInt( $(this).prop("id").match(/\d+/g), 10 ) +1;
$(this).prop('id', id+num);
});
The way it is, I always get ids like id="moviment12". I already tried:
var id = $(this).prop('id').replace(/\d+/g, '');
or
var id = $(this).prop('id').match(/\w+/);
But I always get errors like "cannot read property 'replace'/'match' of undefined". So, what am I doing wrong? Any other ideas? Thank you very much!
Ideally you should use a template. Traversing and modifying parsed elements makes your code slow and hard to maintain.
If you want to increment the number part of the IDs by 1 you can use the replace method callback function:
$clone.find('[id]').prop('id', function(_, id) {
// Assuming `id` is `test_25_segment`
return id.replace(/(\d+)/, function(num) {
// |
// --- is 25
return +num + 1;
// |
// --- parses the matching string into integer
});
});
Here is a demo using the above snippet.
Easiest way, you could just add those values as data-attr:
<div id="type1" data-id="1" data-text="type"></div>
So you can easily get them separated just using .data('id') and .data('text').
You may select the elements by this way:
var all = [].filter.call(document.querySelectorAll('[id*=type]'), function(el) {
return (/\btype\d+\b/).test(el.id);
});
and then you can change the ids using methods like replace()
Try this...
var onlyAlphabets = id.split(/(\d)/)[0];
Using jQuery, if I have elements with the class test scattered throughout an HTML page, with no defined structure to indicate where they might be found, and if I have a variable called currentItem that contains <div class="test">This is a test.</div>, which is located halfway through the page, then how can I find the NEXT element with the test class that appears in the DOM?
You can use the jQuery .index() and .eq() methods:
var $testCollection = $('.test'),
i = $testCollection.index($yourElement);
var $next = $testCollection.eq(i + 1);
var $prev = $testCollection.eq(i - 1);
You have to use .eq() along with the .index() to achieve what you want.
Try,
var xElements = $('.test');
var xNextElement = xElements.eq(xElements.index(currentItem) + 1);
If you are searching for a next sibling then, try
var xNextElement = currentItem.nextAll('.test').first();
How to get all element parents using jquery? i want to save these parents in a variable so i can use later as a selector.
such as <div><a><img id="myImg"/></a></div>
GetParents('myImg'); will return "div a" something like that
/// Get an array of all the elements parents:
allParents = $("#myElement").parents("*")
/// Get the nested selector through an element's parents:
function GetParents(id) {
var parents = $("#" + id).parents("*");
var selector = "";
for (var i = parents.length-1; i >= 0; i--) {
selector += parents[i].tagName + " ";
}
selector += "#" + id;
return selector;
}
GetParents('myImage') will return your nested selector: HTML BODY DIV A #myImage
Note sure why you'd want this but its reuseable as a selector.
You don't need to grab their selectors, as you can use them directly with jQuery afterwards.
If you want to use all parents later, you can do something like:
var parents = $("#element").parents();
for(var i = 0; i < parents.length; i++){
$(parents[i]).dosomething();
}
Every element has only one real parent. To access and save it, write the following:
myParent = $("#myElement").parent();
If you need the parents parents too, use .parents()
See documentation for further information:
http://docs.jquery.com/Traversing/parent#expr
http://docs.jquery.com/Traversing/parents#expr
You can use parents() to get your immediate parent, and their parents on up the tree. you can also pass a selector as an arg to only get parents that match a certain criteria. For instance:
$('#myelement').parents('[id$=container]')
to get all parents who have an id attribute whose value ends with the text "container"
You can get all the tags of an element's parents like this:
var sParents = $('#myImg').parents('*').map(function() {
return this.tagName;
}).get().join(' ');
you can also replace this.tagName with this.id for example or other attributes