Pass string to jQuery selector - javascript

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) ...
});

Related

Impossible to bind an event to an array containing jquery objects

I create dynamically a list content:
for (var i = 0; i<length; i++) {
var $li = $('<li />', {
text: ....
}).appendTo($list);
myArray.push($li);
// This doesn't work
$(myArray).click(function (e) { alert('cc'); });
But when I get the parent of the created elements it works
// This works
$('ul.liste').first().find('li').click(function (e) {alert('cc'); });
What's the difference between between $(myArray) and $('ul.liste').first().find('li')?
How to correctly convert a js array to a jquery collection? I thought wrapping the array with $() would work but obviously not.
Instead of pushing, you can use add:
var $set = $();
for (var i = 0; i<length; i++) {
var $li = $('<li />', {
text: ....
}).appendTo($list);
$set = $set.add($li);
}
$set.click(...
If you prefer to build a native array and then convert it to a jQuery collection, then you can do
var $set = $.add.apply($(), myArray);
myArray is native array, You need jQuery object to bind event handler which $('ul.liste').first().find('li') returns thus it works.
You can use .add() to create collection of jQuery object then use it to bind event handler.
//Create empty jQuery object
var myArray = $([]);
var $list = $('.list')
for (var i = 0; i < 5; i++) {
var $li = $('<li />', {
text: i
}).appendTo($list);
myArray = myArray.add($li);
}
// This doesn't work
myArray.click(function(e) {
console.log(this.textContent);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='list'>
</ul>
You need to loop over the array instead,
Following is incorrect as it is not binding a click event on corresponding element.
$(myArray).click(function (e) { alert('cc'); });
Instead loop as,
$(myArray).each(function(){
$(this).click(function (e) { alert('cc'); });
});
1) What's the difference between between $(myArray) and $('ul.liste').first().find('li')?
Here, myArray is not any jQuery object but a normal array containing jQuery objects as its element. You never bind event to array or string or any other datatype. you always bind event to jQuery object (that contains some DOM elements). Therefore, instead of binding myArray, you should bind every element of myArray one by one.
When you use $('ul.liste'), it works fine because it is a jQuery object with some DOM element in it.
2) How to correctly convert a js array to a jquery collection? I thought wrapping the array with $() would work but obviously not.
You don't convert js Array to jQuery object. But you convert any DOM element to jQuery object as:
For eg,
var elem = document.getElementById("myElem"); // a DOM element
$(elem) //a jQuery object
Arrays are there just to save some data not for DOM manipulations.

Find elements that end with a variable

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>

jQuery - using inArray() to find index of jQuery object

I have a few divs that I'd like to put into an array.
When I try to use jQuery.inArray(), my div (as a jQuery object) isn't found. Why not?
var myArray = [ $("#div1"), $("#div2"), $("#div3") ];
alert(jQuery.inArray($("#div1"),myArray)); // returns -1
$ creates a new jQuery collection object each time, so var a = $("div"), b = $("div") will actually be two different objects that don't equal each other.
Instead you can just use the selectors or some other identifying feature of the element.
var myArray = ["#div1", "#div2", "#div3"];
However it really depends on your use case.
Two objects are never the same, so when you do
var object1 = $('#div1');
var object2 = $('#div1');
even if you have the same element, the objects are not the same
If you use the same object, it works
var div1 = $('#div1');
var div2 = $('#div2');
var div3 = $('#div3');
var myArray = [ div1, div2, div3 ];
jQuery.inArray( div1 , myArray); // returns 0
You can't use .inArray() for object comparison by content.
I like the approach outlined here. It's very clean.
It's probably because each invocation of the jQuery constructor results in a new instance referring to the same DOM node. What would effectively allow you to demonstrate inArray looks something like this:
var $div1 = $('#div1'),
$div2 = $('#div2'),
myArray = [ $div1, $div2 ];
alert(jQuery.inArray($div1,myArray));
You are not storing any references to the jQuery objects, $("#div1") will return a new jQuery object containing your dom element, you are comparing two different jQuery objects containing the same dom element. inArray will work just fine if you are using the same reference in the array as when you do use the inArray method.
var arr = [],
$d1 = $("#d1"),
$d2 = $("#d2"),
$d3 = $("#d3");
arr.push($d1, $d2, $d3);
console.log(jQuery.inArray($d3, arr));
or see http://jsfiddle.net/EQQ96/2/
You're better off creating an array of ids. When it you roll, you can then see if that id is in your array, and then move forward.
var possiblePositions = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
function randomSpin(sides) {
return Math.floor(Math.random() * (sides || 6) ) + 1;
}
var $currentPiece = $('piece.active');
var currentSpot = $currentPiece.attr('spotPosition');
var spin = randomSpin(6) + randomSpin(6);
var nextSpot = currentSpot + spin;
if (possiblePositions.indexOf(nextSpot)) {
$('#div' + nextSpot).append($currentPiece);
}
If you were to use purely jQuery to manipulate the jQuery Collection then you can use the jQuery index() method. However, the index returned is the position of the element in the dom, not the order in which it was added to the collection. If you need to deal with the order of adding then you're better of using selector strings rather than jQuery Collection:
var myArray = $([]).add( "#div4" ).add( "#div3" ).add( "#div1" ).add( '#div2' );
console.log( myArray.index( $('#div3') ) ); //Output: 2
JS FIDDLE DEMO

jQuery getting value from dynamic array

I have an array with divs ids (in my case its all divs ID values od parent div (#area) ):
jQuery.fn.getIdArray = function () {
var ret = [];
$('[id]', this).each(function () {
ret.push(this.id);
});
return ret;
};
var array = $("#area").getIdArray();
I need to get an array field value, something like this:
var lef = $("#array".[0]).css("left");
Taking a wild swing at it (see my comment on the question):
var array = $("#area").getIdArray();
var lef=$("#" + array[0]).css("left");
That assumes that getIdArray returns an array of strings, where each string is an id value for a DOM element, and that you want to get the left value for the first of those elements.
So for instance, if the array comes back as:
["foo", "bar", "charlie"]
then the selector created by "#" + array[0] is #foo, so you end up getting the left value for the foo element.
If you have an actual JS array within your variable array just use bracket notation to access each individual ID.
// I have the # before-hand since I'm assuming you have just the ID name
var lef = $('#' + array[0]) // this will access the 1st one in the array
I think you are looking for this :
var divYouWantToChange = $("#"+array[0]);
I try to formulate this as an answer because getIdArray is not a jquery function and we don't know what it does. If you'd like to apply a custom filter to the $("#area") collection you can do so using filter. This will return a jquery object where you can get the .css("left") from.
If you'd like to save both the id's and the left property you can do so with the following code:
var objects=[];
$("#area").filter(function(){
$this=$(this);//cache the object
objects.push({id:$this.attr("id"),
left:$this.css("left")
};
});
console.log(objects);

Javascript/jQuery Dynamic Array

I am trying to create a dynamic array using JS/jQuery. The HTML structure is:
<ul>
<li><img src="1"/></li>
<li><img src="2"/></li>
<li><img src="3"/></li>
</ul>
I am trying to create a new array of the image sources, so it ends up looking like:
var imagesArray = [1, 2, 3];
I thought I could use the jQuery .each() method...but I keep getting lost. If you can please provide an explanation I would really appreciate it.
thanks!
var imagesArray = $('img').map(function(){ return this.src; }).get();
Here's a demo: http://jsfiddle.net/pkeBZ/
jQuery's .map() method loops through all the elements, collects whatever is returned from your callback function, and creates a new array out of it.
However, the returned result behaves like an array, but is really an jQuery object (granted, it probably makes no difference in your use case).
If you want to convert a jQuery object into an array, you can use jQuery's .get() method.
You thought correct :) You can use the jQuery .each() method.. as below..
<script type="text/javascript">
$(document).ready(function(){
var imagesArray =new Array();
$("ul li img").each(function(){
imagesArray.push($(this).attr('src'));
});
console.log(imagesArray); // this returns ["1", "2", "3"]
});
</script>
Use this code snippet to loop an array in jquery
1) First we declare an arrray
var MapAreas = [];
2) Now we loop using foreach
$.each(MapAreas, function (index, value) {
alert(index + ':' + value);
}
3) To check if a value is already present in an array use this code snippet
if ($.inArray(value, MapAreas) >= 0) {}
4) To remove an item from the array use this function
RemoveItemFromArray(value, arr) {
return jQuery.grep(arr, function (elem, index) {
return elem !== value;
});
}

Categories

Resources