Iterate through elements with similar IDs - javascript

I want to get the id of a single <span> element during iteration.
Example scenario:
I have a few ids which start with AAA and end with BBB. The middle characters can vary:
<span id="AAA-LS-BBB">hi1</span>
<span id="AAA-LAS-BBB">hi2</span>
<span id="AAA-LBS-BBB">hi3</span>
<span id="AAA--LCS--BBB">hi4</span>
Here, first 3 digits of span id and last 3 digits of span id is same...only in middle it will vary. I want to generalized method to know ...each id using... $("#id").attr("id")
so, here
I am trying to find out iteration like below,
I want to write one iterator method to get the current id
$("span[id^='AAA-***-BBB']").each(function(){
var a = $("this").attr("id");
});
Hope my requirements are clear.
how ti use regular expression here.. to find out id?

Use .filter() combined with a regex:
$('span[id]').filter(function () {
return /^AAA.*BBB$/.test(this.id);
}).each(function () {
alert(this.id);
});
Alternatively, since you are using a .each() already, you can simply add an if condition inside it:
$('span[id]').each(function () {
if (/^AAA.*BBB$/.test(this.id)) {
alert(this.id);
}
});
Update: It looks like you can also combine both the Attribute-Starts-With and Attribute-Ends-With selectors on the same attribute:
$('div[id^="AAA"][id$="BBB"]').each(function () {
alert(this.id);
});
(See example: http://jsfiddle.net/2pz8X/)

Combining fellow contributors' suggestions, and making the regex more specific:
// first, at least get all <div>'s with id's that start with 'AAA'
$("div[id^='AAA']").filter(function(){
var regexp = /^A{3}(.*)B{3}$/; // regex
return (this.id.match(regexp));
});
This will return all the div's that you need to target.
Sample # http://jsfiddle.net/4ZNWJ/

Try this:
$("span[id^='AAA']").each(function(){
alert($(this).id);
});

Related

Get element by a word it contains

Is there a way to get an element by its content(a word it contains?)
For example, get all the elements with the letter "F," and put it in a array of elements
I highly recommand you to use jQuery for these kind of DOM elements searching.
Then you can use this:
var foos = $("div:contains('foo')" )
will make an array with all divs containing the word 'foo'.
One fairly easy way is to select the elements you're interested in and then use 'filter' to look at the innerText. You can make this case insensitive with toLowerCase
var result = $('div').filter( (i,e) => e.innerText.toLowerCase().indexOf("f")>-1);
console.log("Items with 'F':",result.length);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Forest</div>
<div>Fortnight</div>
<div>Trees</div>
<div>Africa</div>
The simpler way is using :contains('F') as a selector - but that is always case sensitive (which may be fine for your case).
You can use :contains as a selector. For example, to filter all divs of a special class that also contains your text, you can use $("div.myclass:contains('searched text')")
I think you can "bruteforce" it by iterating all DOM items. e.g.:
let arrayDom = Array.from(document.getElementsByTagName("*"));
arrayDom.forEach(element => {
if (element.innerHTML.contains('F')){
// Do something
}
})

Javascript RegExp unknown repeated matches

It's difficult to describe because I'm not an expert with regular expressions. So I tell you my case.
In HTML want to contribute class attributes into different data-xyz attributes. The problem is to get always all classes per match. For example the following HTML:
<span class="note-123 index-3 green">Hello</span> <span class="index-456 red">World<span>
Until now my regular expression is /<span class="([^\"\s]*)\s*/ and it matches the first class. In this case note-123 and index-456
But if I want to get all classes per element I could use /<span class="([^\"\s]*)\s*([^\"\s]*)\s*([^\"\s]*)\s*/. That works until three classes and the result for the second class return index-456, red and an empty string.
Is there a possibility to always get all classes per match no matter how many classes there are? Similar to a nested loop in Javascript?
I would be pleased to get any help from you guys.
You could get the classes without using a regex making use of querySelectorAll to find the elements that you want and use classList to get the class names.
Then use for example the add or remove methods.
Or use a DOMParser.
Note to close the last span.
let elms = document.querySelectorAll("span");
elms.forEach(e => {
for (let value of e.classList.values()) {
console.log(value);
}
});
<span class="note-123 index-3 green">Hello</span> <span class="index-456 red">World</span>
Use the regex to extract the value of the class attribute and split it at whitespace sequences:
let as_classes
, as_matches
, n_i
, re_classes
, s_test
;
re_classes = new RegExp ( "<span class=\u0022([^\\u0022]*)", "g" );
s_test = '<span class="note-123 index-3 green">Hello</span> <span class="index-456 red">World<span>';
n_i=0;
while ((as_matches = re_classes.exec(s_test)) !== null) {
n_i++;
s_classes = as_matches[1];
as_classes = s_classes.split(/[\s]+/g);
console.log(`match #${n_i}, classes: ${JSON.stringify(as_classes)}.`);
}
Warning
It is in general never a good approach to extract information from html with regexen.

Detect if a div with id including number is clicked

My html code has X elements, with their ids in this form:
viewer_mX
Here, X is a number from 1 to m (m can be different each time).
I want to use javascript to get the number X of the respective element when somebody clicks one of these elements.
I realise I should probably use a class (.viewer) and and id (#x) containing the number. However, I am using a library to generate the html elements and I am stuck with this protocol and will have to make the best of it.
This is the javascript I have so far:
$(document).ready(function () {
$("#viewer>...").click(function () {
x = ...
var number = x;
});
});
What's missing in this code (indicated by 3 dots) is that viewer is not the full ID, but could be post-pended with something. I want to store whatever is after the clicked div in number, but I can't figure out which function to use for that.
Try this,
$("[id^='viewer_']").click(function () {
var number = this.id.match(/\d+$/)[0];
});
Why not use class to identify elements and then data-attribute for storing your id (data-id for example) and then get value of this data-attribute?
Otherwise I would personally use something like this
$(this).attr('id').substr("viewer_m".length);
Either split or a reg exp
var id = this.id.split("_m")[1]
or
var id = this.id.match(/\d+$/)[0];
or better yet, use a data attribute
<div data-mid="123">
and reference it
$("[data-mid]").on("click", function () {
var id = $(this).data("mid");
});
A better approach to this, as #Wax Cage mentioned, is to use classes and data attributes for better organizing. Example:
<div class="viewer" data-viewer-id="1">...</div>
$('.viewer').on('click', function() {
var viewerId = $(this).data('viewerId');
// ...
});

jQuery .wrap() question

i'm having some problems with jQuery
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.filter("h1,h2").map(function(id) {
$(this).wrap('<span color="red"/>');
});
alert(foo.html());
});
This code outputs
<h1>Bar</h1><p>Hi</p><h1>Baz</h2><p>bye</p>
The span's are nowhere to be seen. What am I doing wrong?
It doesn't have any effect because .filter() filters elements at that level, you could need .find() to get descendants like this:
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.find("h1,h2").wrap('<span color="red"/>');
alert(foo.html());
});
You can test it out here. Also note you should use .each() instead of .map() for looping...but there's no need here, since you can just call .wrap() directly.
You don't want to use filter here, you want to use find. Also, why are you using map?
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h2><p>bye</p></div>");
foo.find("h1,h2").wrap('<span color="red"/>');
alert(foo.html());
});
Live test
First off: your markup is invalid (Baz is wrapped by an opening h1 and a closing h2). But the .map reference says you need to return the value.
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
var bar = foo.find("h1,h2").map(function(id) {
return $(this).wrap('<span color="red"/>');
});
});
You need .find() instead of .filter() since the heading elements are nested.
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.find("h1,h2").wrap('<div color="red"/>');
Also, I changed it to wrap using a <div> instead of a <span> since I don't think it is valid to have a <span> wrapped around heading elements.

an array of strings as a jQuery selector? [duplicate]

This question already has answers here:
Easy way to turn JavaScript array into comma-separated list?
(22 answers)
Closed 6 months ago.
I have an array of strings that are valid jQuery selectors (i.e. IDs of elements on the page):
["#p1", "#p2", "#p3", "#p4", "#p5"]
I want to select elements with those IDs into a jQuery array. This is probably elementary, but I can't find anything online. I could have a for-loop which creates a string "#p1,#p2,#p3,#p4,#p5" which could then be passed to jQuery as a single selector, but isn't there another way? Isn't there a way to pass an array of strings as a selector?
EDIT: Actually, there is an answer out there already.
Well, there's 'join':
["#p1", "#p2", "#p3", "#p4", "#p5"].join(", ")
EDIT - Extra info:
It is possible to select an array of elements, problem is here you don't have the elements yet, just the selector strings. Any way you slice it you're gonna have to execute a search like .getElementById or use an actual jQuery select.
Try the Array.join method:
var a = ["#p1", "#p2", "#p3", "#p4", "#p5"];
var s = a.join(", ");
//s should now be "#p1, #p2, #p3, ..."
$(s).whateverYouWant();
What about $(foo.join(", "))?
Use the array.join method to join them together
$(theArray.join(','));
Going to officially answer your question: with a one-liner:
//If this is only one use variable you can use
$(['#p1','#p2','#p3','#p4','#p5'].join(',')).methodToUse();
//if you DO need it as a variable you can
var joined = ['#p1','#p2','#p3','#p4','#p5'].join(',');
$(joined).methodsToUse();
If you want them to do something individually there is also .each();
In the example below, each p ids clicks makes any one of them red:
var peas = ['#p1','#p2','#p3','#p4','#p5'];
$.each(peas, i => {
$(peas[i]).click(() => {
$(peas[i]).css({'color':'red'});
});
});
When you throw 'i' into a function parameter, it finds the values inside the arrays appropriately. When you do '.each()' the format looks like this:
$.each(array, function(i){
// any code you wish as long as you have an array selector
//$(array[i]).whatever function
});
An even bigger example. Say you want to make the P you click on red, but want the other ps return to default color. Just make a function that removes the selected ID from the array and voila!
var peas = ['#p1','#p2','#p3','#p4','#p5'],
poppy=(v,i)=>peas.toString().replace(`,${v[i]}`,'').replace(`${v[i]},`,'');
(// get each pea index
$.each(peas,i=>///funciton(i){ code inside}
(//set up each individual index's functions
$('.peastock').append(`<p id="p${[i+1]}">I am ${peas[i]}</p>`),
$(peas[i]).click(()=>(
$(peas[i]).css({"color":"red","background-color":"rgba(128,0,0,0.1)"}),
$(poppy(peas,i)).css({'color':'black','background-color':'rgba(255,255,255,0.2)'}))))),
$('.peastock').append(`
<div id="ree">ES6 isnt suitable for all of jQuery's usage!</div>
<div>Since some functions inside of jQuery's methods dont require 'this' or 'return'</div>
<div>You can learn this by going here</div>
`),
$("*").css({"margin":"0 auto","padding":"1%"}),
$("* .peastock, .peastock, .peastock *").css({"background-color":"rgba(128,0,0,0.1)"})
);
I know someone is bound to want to know about each value array as jquery selectors. Hope everything goes well!
Source:
jQuery .each()
The fiddle in action (with updates!)
I think you're looking for join.
var arr = ["#p1", "#p2", "#p3", "#p4", "#p5"];
$(arr.join(","))
Shorter:
$( ["#p1", "#p2", "#p3", "#p4", "#p5"].toString() );

Categories

Resources