This question already has answers here:
jQuery selector for id starts with specific text [duplicate]
(4 answers)
Closed 6 years ago.
How I can change and add something to all ids in div child elements that have something like bi_ in his first. like this example:
<script>
var opts = '1';
$('.mm > #bi_name').attr('id', 'bi_name_'+opts);
$('.mm > #bi_email').attr('id', 'bi_email_'+opts);
$('.mm > #bi_expire').attr('id', 'bi_expire_'+opts);
$('.ss > #bi_ohhh').attr('id', 'bi_ohhh_'+opts);
$('.ss > #bi_bala').attr('id', 'bi_bala_'+opts);
$('.ss > #bi_ola').attr('id', 'bi_ola_'+opts);
.....
</script>
<div id="lol" class="mm">
<!-----I want to change all id below----->
<div id="profile">
<div class="about text-center">
<h1 id="bi_name">Banned player name</h1> //change and this id="bi_name" to id="bi_name_1"
</div>
<ul class="personal-info">
<li><label><i class="fa fa-envelope fa-fw fa-lg"></i> Email</label><span id="bi_email">EMAIL</span></li> //change and this id="bi_email" to id="bi_email_1"
<li><label><i class="fa fa-calendar fa-fw fa-lg"></i> Expire Time</label>
<span>
EXPIRE TIME //change and this id="bi_expire" to id="bi_expire_1"
</span>
</li>
</ul>
</div>
<div id="content" class="ss">
.....
</div>
<div id="gallery" class="gg">
....
</div>
<!-----I want to change all id above----->
</div>
You can use target all the elements using Attribute Starts With Selector [name^=”value”] then use .attr(attributeName, fn) to set the id
var opts = '1';
$('.mm [id^=bi_]').attr('id', function(_, val){
return val + '_' + opts;
});
Related
I am trying to do this:
Search for all the spans in my structure
Get the id value from each span
Update the parent with that text for test purposes
The reason for this work is that I am doing front-end customizations for an application and trying get some WAI-ARIA labelled-by values set on a parent element.
The problem is that many of the needed values come from an COTS application that I am working with/around. These needed input are not always set in a good sequence in the DOM.
I have been looking at a JS solution to get around this.
<div class="fluid-form-container">
<ul id="accordionGroup" class="Accordion" data-allow-multiple="">
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion1id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect1" id="accordion1id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="More_Info_Form_Section_Label">More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion2id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect2" id="accordion2id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="Even_More_Info_Form_Section_Label">Even More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
</div>
//My bad javaScript so far
var found_elements = [];
var outers = document.querySelectorAll('.FormSection');
for(var i=0; i<outers.length; i++) {
var elements_in_outer = outers[i].querySelectorAll("span");
var updateValue = elements_in_outer.getAttr("id");
outers[i].closest("h3").innerHTML = updateValue;
}
The expect results:
- parent tag innerHTML set to the id value of each span in the structure
Actual results:
- I'm getting errors because I am not sure what I need to use to get that id from each span found
querySelectorAll() returns a NodeList , so elements_in_outer.getAttr("id") won't work and should be replaced with querySelector()
there is no getAttr, use getAttribute
( i replaced your for with a forEach )
var found_elements = [];
var outers = document.querySelectorAll('.FormSection').forEach(div => {
var elements_in_outer = div.querySelector("span");
var updateValue = elements_in_outer.getAttribute("id");
div.closest("h3").innerHTML = updateValue;
});
<div class="fluid-form-container">
<ul id="accordionGroup" class="Accordion" data-allow-multiple="">
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion1id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect1" id="accordion1id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="More_Info_Form_Section_Label">More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
<li class="fluid-form-group-container">
<h3 aria-labelledby="accordion2id">
<button aria-expanded="true" class="Accordion-trigger" aria-controls="sect2" id="accordion2id">
<span class="Accordion-title"><div class="fluid-form-title">
<div class="FormSection">
<span id="Even_More_Info_Form_Section_Label">Even More Info</span>
</div>
</div>
</span>
</button>
</h3>
</li>
</div>
If you know beforehand that you will only use the span elements that have an id, then use [id] in the querySelectorAll selector likewise
document.querySelectorAll('span[id]')
If you will use that as an array, then you need
[... document.querySelectorAll('span[id]')]
Assigning the new value would be something like this:
[... document.querySelectorAll('span[id]')].forEach(s => s.closest("h3").innerHTML = s.id)
I'm trying to iterate through an array and clone and append an element to a div element for each item in the array.
Everything is working except when it's more than one element I get some unexpected results.
The array contains two element's and I've checked that the each loop only runs two times, but for some reason I get a third element in the result.
Am I using clone() and appendTo() correctly?
each loop:
let items = $(contentWrap).find(".lc-rating-modal-review-items-wrap");
$(items).empty();
$.each(data.items, function (index, review) {
let item = GenerateReviewItem(review);
$(item).appendTo(items);
});
GenerateReviewItem:
function GenerateReviewItem(review) {
let result = $(wrap).find(".lc-rating-review-item-template").clone();
$(result).find(".lc-rating-review-item-template-date").html(review.dateFormated);
$(result).find(".lc-rating-review-item-body-wrap").html(review.review);
$(result).find(".lc-rating-review-item-template-stars-rating-label").html("(" + review.rating + ")");
$(result).find(".lc-rating-review-item-template-star").each(function (index, star) {
if (review.rating >= (index + 1)) {
$(star).removeClass("fa-star-o").addClass("fa-star");
}
});
return result;
}
Html to clone:
<div style="display:none;">
<div class="lc-rating-review-item-template">
<div class="lc-rating-review-item-header-wrap">
<div class="lc-rating-review-item-template-stars-wrap">
<div>
<i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
</div>
<div>
<i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
</div>
<div>
<i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
</div>
<div>
<i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
</div>
<div>
<i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
</div>
<div>
<span class="lc-rating-review-item-template-stars-rating-label"></span>
</div>
</div>
<div style="text-align:right;">
<span class="lc-rating-review-item-template-date"></span>
</div>
</div>
<div class="lc-rating-review-item-body-wrap"></div>
</div>
</div>
I'd recommend storing the reference to your template node outside of your loop, and then doing the cloning inside of the loop.
Define this outside the loop:
let template = $(wrap).find(".lc-rating-review-item-template")
And then change this:
let result = $(wrap).find(".lc-rating-review-item-template").clone();
To this:
let result = template.clone();
As it is currently, when your loop executes a second time, $(wrap).find(".lc-rating-review-item-template") is likely finding two items instead of one.
It also appears that wrap, unless it is a global, is undefined within the context of the GenerateReviewItem(review) function.
I've code few line of jQuery for Hide/Show many elements on single click and it's working. But problem is; i've many more image class items, so my script going to long, my question is how to simplify or make short my script, i mean any alternatives or any new idea? please suggest.
HTML:
<div id="choose-color">
<span>
<i class="images-red" style="">Red Image</i>
<i class="images-blue" style="display: none;">Blue Image</i>
<i class="images-pink" style="display: none;">Pink Image</i>
<!-- many many images -->
</span>
<button class="red">Red</button>
<button class="blue">Blue</button>
<button class="pink">Pink</button>
</div>
JS: live demo >
$("button.red").click(function(){
$(".images-red").show();
$(".images-blue, .images-pink").hide();
});
$("button.blue").click(function(){
$(".images-red, .images-pink").hide();
$(".images-blue").show();
});
$("button.pink").click(function(){
$(".images-red, .images-blue").hide();
$(".images-pink").show();
});
Please suggest for short and simple code of my script. Thanks.
You can do it by adding just a common class to those buttons,
var iTags = $("#choose-color span i");
$("#choose-color button.button").click(function(){
iTags.hide().eq($(this).index("button.button")).show();
});
The concept behind the code is to bind click event for the buttons by using the common class. Now inside the event handler, hide all the i elements which has been cached already and show the one which has the same index as clicked button.
DEMO
For more details : .eq() and .index(selector)
And if your elements order are not same, both the i and button's. Then you can use the dataset feature of javascript to over come that issue.
var iTags = $("#choose-color span i");
$("#choose-color button.button").click(function(){
iTags.hide().filter(".images-" + this.dataset.class).show()
});
For implementing this you have to add data attribute to your buttons like,
<button data-class="red" class="button red">Red</button>
DEMO
This works
$("#choose-color button").click(function(){
var _class = $(this).attr('class');
$("#choose-color i").hide();
$(".images-"+_class).show();
});
https://jsfiddle.net/455k1hhh/5/
I know this might not be the prettiest solution, but it should do the job.
$("button").click(function(){
var classname = $(this).attr('class');
$("#choose-color span i").hide();
$(".images-"+classname).show();
});
You're making future extensibility a little difficult this way due to relying on class names but this would solve your immediate need:
<div id="myImages">
<i class="images-red" style="">Red Image</i>
<i class="images-blue" style="display: none;">Blue Image</i>
<i class="images-pink" style="display: none;">Pink Image</i>
<!-- Many many image -->
</div>
<div id="myButtons">
<button class="red">Red</button>
<button class="blue">Blue</button>
<button class="pink">Pink</button>
</div>
$("#myButtons button").click(function(){
var color = $(this).attr("class");
var imageClass = ".images-"+color;
$('#myImages').children("i").each(function () {
$(this).hide();
});
$(imageClass).show();
});
Here's a JSFiddle
Edit: Note how I wrapped the buttons and images in parent divs to allow you to isolate just the buttons/images you want to work with.
You can do the following using data-* attributes, because when you have more elements of the same color, using index of the button won't work. And simply using the whole class attribute won't work if you have to add more classes to the button in future.
$("button").click(function() {
var color = $(this).data('color');
var targets = $('.images-' + color);
targets.show();
$("span i").not(targets).hide();
});
.hidden {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br/>
<br/>
<div id="choose-color">
<span>
<i class="images-red">Red Image</i>
<i class="images-blue hidden">Blue Image</i>
<i class="images-pink hidden">Pink Image</i>
<!-- Many many image -->
</span>
<br/>
<br/>
<button data-color="red">Red</button>
<button data-color="blue">Blue</button>
<button data-color="pink">Pink</button>
</div>
It would make sense to have all images share a single class (.image for example). Then you just use a shared class for the button and the image; in this example I used the color name. Now, when any button is clicked, you can grab the class name of the image you want to show.
Give this a try:
$("button").click(function(){
$(".image").hide();
var className = $(this).attr("class");
$("." + className).show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br/><br/>
<div id="choose-color">
<span>
<i class="image red" style="">Red Image</i>
<i class="image blue" style="display: none;">Blue Image</i>
<i class="image pink" style="display: none;">Pink Image</i>
<!-- Many many image -->
</span>
<br/><br/>
<button class="red">Red</button>
<button class="blue">Blue</button>
<button class="pink">Pink</button>
</div>
You may try this:
<div id="choose-color">
<span>
<i class="images-red" style="">Red Image</i>
<i class="images-blue" style="display: none;">Blue Image</i>
<i class="images-pink" style="display: none;">Pink Image</i>
<!-- Many image -->
</span>
<br/><br/>
<button class="colour red" onclick="myFunction(this)">Red</button>
<button class="colour blue" onclick="myFunction(this)">Blue</button>
<button class="colour pink" onclick="myFunction(this)">Pink</button>
</div>
JS: see here
$(".colour").click(function(){
var colors = ["red", "blue", "pink"];
for (i = 0; i < colors.length; i++) {
if($(this).hasClass(colors[i])){
$(".images-"+colors[i]).show();
}else{
$(".images-"+colors[i]).hide();
}
}
});
I'd like to get the data-league values of all of those divs, and put them into an array.
What I want to do: Get all those values, save them, and then loop through them, and call a .click on those divs.
I don't know if there's an easier way to do this.
I guess it also has to loop through the divs where ID=128, and find the data-league values, right?
Honestly I'm completely stuck, so any help whatsoever would be appriciated.
Thank you.
Extra info: Basically the end result being, on click of a button, all those 'thumbnails' should open in a new tab. All tabs being different streams.
(See image)
In the example you provided the same id (128) has been used multiple times. This is not allowed. Iterating through the ids will not work.
This means you have to look for another possibility. Getting all div elements with a certain class would be possible, like in the example:
var divs = document.getElementsByClassName('videoPanel');
Now you can iterate through this collection, extract the values for the attribute data-league and save them somewhere, for example in an array:
var dataLeagueValues = [];
for (var i = 0; i < divs.length; i++) {
dataLeagueValues.push(divs[i].getAttribute('data-league'));
}
Now you have all values in the array dataLeagueValues. You can use them further in your script.
You could use the $('[attribute]') selector to select elements with data-league, you can then use .each(); to loop them.
The following example triggers a click on every element with a data-league attribute:
$('[data-league]').each(function() {
$(this).trigger('click');
});
You could also make the selector more specific to only match these elements by their shared class name videoPanel e.g.
$('.videoPanel[data-league]').each(...);
Will target all elements with a class of videoPanel and an attribute data-league
To match what you need the full example would be:
var leagues = [];
$('.videoPanel[data-league]').each(function() {
leagues.push($(this).attr('data-league'));
});
Following code snippet will your insert all data-league into an array.
var leagues=[];
$('.vedioPnnel').each(function() {
var league = $(this).data('league');
leagues.push(league);
});
console.log(leagues);
I propose to use the javascript forEach function like in the folowing snippet.
Alternatively you can use:
document.querySelectorAll('[id="127"]');
or
document.querySelectorAll('[data-league]')
function getAllDataLeague()
{
var leagues = [];
Array.prototype.forEach.call(document.getElementsByTagName('div'), function (value, index, traversed) {
var attrVal = value.getAttribute('data-league');
if (attrVal) {
leagues.push({'obj': value, 'data-league': attrVal});
}
});
return leagues;
}
var eleFound = getAllDataLeague();
// print result in the html body
document.body.innerHTML += '<p>To access elements: eleFound[index]["data-league"]</p>';
document.body.innerHTML += '<p>To trigger the click event: eleFound[index]["obj"].click()</p>';
document.body.innerHTML += '<p>Elements found:</p>';
for (var i = 0; i < eleFound.length; i++) {
document.body.innerHTML += '<div>data-league:' + eleFound[i]["data-league"] + '</div>';
}
<div class="game-listing-group">
<div class="bold game-listing-name">CS:GO</div><div class="videoPanel vu-channel-tab" id="127" data-channel="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf?channel=m0e_tv" data-league="1284">
<div class="video-thumbnail-con hidden-xs hidden-sm">
<img class="img-responsive video-thumbnail full-width" src="https://static-cdn.jtvnw.net/previews-ttv/live_user_m0e_tv-320x180.jpg">
</div>
<div class="videoPanelTextBg">
<p class="indexVideoPanelTitle">Dragon lore giveaway NOW</p>
<span class="indexVideoPanelGoldCount vu-league-gold pull-right" style="display: none;"></span>
</div>
<div class="indexVideoPanelGoldCount video-upcoming">
<i class="glyphicon glyphicon-time"></i>
<span class="vu-league-start"></span>
</div>
</div><div class="videoPanel vu-channel-tab" id="127" data-channel="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf?channel=freakazoid_tv" data-league="1296">
<div class="video-thumbnail-con hidden-xs hidden-sm videoPanelTextBgActive">
<img class="img-responsive video-thumbnail full-width" src="https://static-cdn.jtvnw.net/previews-ttv/live_user_freakazoid_tv-320x180.jpg">
</div>
<div class="videoPanelTextBg">
<p class="indexVideoPanelTitle">BIRTHDAY IN 24HOURS! #c9freakazoid</p>
<span class="indexVideoPanelGoldCount vu-league-gold pull-right" style="display: none;"></span>
</div>
<div class="indexVideoPanelGoldCount video-upcoming">
<i class="glyphicon glyphicon-time"></i>
<span class="vu-league-start"></span>
</div>
</div><div class="videoPanel vu-channel-tab" id="127" data-channel="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf?channel=gripex90" data-league="1301">
<div class="video-thumbnail-con hidden-xs hidden-sm">
<img class="img-responsive video-thumbnail full-width" src="https://static-cdn.jtvnw.net/previews-ttv/live_user_gripex90-320x180.jpg">
</div>
<div class="videoPanelTextBg">
<p class="indexVideoPanelTitle">Gripex - Most dedicated Lee sin! Top 50 Challenger</p>
<span class="indexVideoPanelGoldCount vu-league-gold pull-right" style="display: none;"></span>
</div>
<div class="indexVideoPanelGoldCount video-upcoming">
<i class="glyphicon glyphicon-time"></i>
<span class="vu-league-start"></span>
</div>
</div><div class="videoPanel vu-channel-tab" id="127" data-channel="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf?channel=phantoml0rd" data-league="1346">
<div class="video-thumbnail-con hidden-xs hidden-sm">
<img class="img-responsive video-thumbnail full-width" src="https://static-cdn.jtvnw.net/previews-ttv/live_user_phantoml0rd-320x180.jpg">
</div>
<div class="videoPanelTextBg">
<p class="indexVideoPanelTitle">Level 400 Gambler LOL - Cycled over 3,000,000 in s</p>
<span class="indexVideoPanelGoldCount vu-league-gold pull-right" style="display: none;"></span>
</div>
<div class="indexVideoPanelGoldCount video-upcoming">
<i class="glyphicon glyphicon-time"></i>
<span class="vu-league-start"></span>
</div>
</div></div>
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Getting text within element excluding decendants
I have the following function:
function initCBox(){
CB_Init();
var img1 = $(select.currentImg).attr('src');
var label = $(select.currentImg).attr('alt');
var desc = $('.item.active .caption').not($('.description')).text();
CB_Open('href=' + img1 + ',,title=' + label + ',,comment=' + desc +'');
}
with the following html:
<div class="item" title="Light" href="Light.jpg" >
<img class="content" alt="Amber Light" src="slides/Light.jpg"/>
<div class="caption">Light
<ul class="icon">
<li class="ui-state-default ui-corner-all" title="More Info">
<div class="description ui-icon ui-icon-comment">
<div class="description_holder" style="display:none">Amber Light
<br />Enter Text or HTML Here</div>
</div> </li>
</ul>
</div></div>
I want my var = desc to only show the text in the class "caption", not anything in the <ul class="icon"> ( for simplicity, I only include one <li> item but I have others in the <ul>). Need help with my excluding all but the caption text. Hope I haven't been too confusing!
You can do a string find and replace:
var desc = $('.caption').text(), // The caption and stuff you don't want
noWant = $('.icon').text(); // Only stuff you don't want
desc = desc.replace(noWant,""); // Find stuff you don't want and replace w ""
The advantage if this way over excluding descendants, is that it will grab the entire text of your description even if includes <span>s, <strong>s, etc.