Change text in multiple divs with same class onclick [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a list of football matches and would like to replace all scores with "?-?" when pressing a button and toggle back to show the score when pressing again.
div {
display: table;
}
div div {
display: table-row;
}
div div div {
display: table-cell;
}
.score {
color: blue;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Hide scores!</button>
<br> <br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score">1-1</div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score">2-0</div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score">1-4</div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score">3-0</div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score">0-1</div>
<div class="team2">Marseille</div>
</div>
</div>
I have experimented with getElementById and innerHTML, but due to the large number of matches I would prefer to use getElementsByClassName instead. I've seen people recommending querySelectorAll() for this, but I can't get the scripts to work.
An alternative would be to run a script replacing all numbers with a question mark inside divs with the same class.
Please help me out by using this fiddle

Here's a solution that uses querySelector only to select the button and the .table element to toggle a class.
The rest is all CSS, so no looping is needed.
Note that this exchanges your .score text content for a data-score attribute.
document.querySelector("button")
.addEventListener("click", function() {
document.querySelector("div.table").classList.toggle("hide-score");
});
.table .score:after {
content: attr(data-score);
}
.table.hide-score .score:after {
content: "?-?";
}
<button>Hide scores!</button>
<br>
<br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score" data-score="1-1"></div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score" data-score="2-0"></div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score" data-score="1-4"></div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score" data-score="3-0"></div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score" data-score="0-1"></div>
<div class="team2">Marseille</div>
</div>
</div>
To support older browsers, you could instead keep the score as text content, but put it in a span with another <span>?-?</span> next to it, and then configure the CSS to hide the :first-child and show the rest as needed.

If you don't want to change your html code
$.each($('.score'), function(key, score) {
var score_text = $(score).text();
$(score).data('score', score_text)
})
$('button').click(function() {
if ($(this).data('hiding-score')) {
$(this).data('hiding-score', false);
$.each($('.score'), function () {
$(this).text($(this).data('score'));
});
} else {
$(this).data('hiding-score', true);
$('.score').text('?-?');
}
})
div { display:table; }
div div { display:table-row; }
div div div { display:table-cell; }
.score { color:blue; padding:10px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Hide scores!</button>
<br>
<br>
<div class="table">
<div class="match">
<div class="team1">Manchester United</div>
<div class="score">1-1</div>
<div class="team2">Liverpool</div>
</div>
<div class="match">
<div class="team1">Juventus</div>
<div class="score">2-0</div>
<div class="team2">Inter Milan</div>
</div>
<div class="match">
<div class="team1">Real Madrid</div>
<div class="score">1-4</div>
<div class="team2">Barcelona</div>
</div>
<div class="match">
<div class="team1">Dortmund</div>
<div class="score">3-0</div>
<div class="team2">Bayern Munich</div>
</div>
<div class="match">
<div class="team1">PSG</div>
<div class="score">0-1</div>
<div class="team2">Marseille</div>
</div>
</div>

Here is a fiddle with plain old Javascript.
But I have to admit, #SkinnyPete's way is way better and easier to understand ! You shouls use it if you're only to hide the score. This is the best way to go.
// Mandatory JS code

const score = document.getElementsByClassName('score')
const button = document.getElementById("hide")
const initialState = []
for(let i = 0; i < score.length; i++){
initialState.push({initial : score[i].innerHTML})
}
button.addEventListener('click', (e) => {
const dynamicScore = document.getElementsByClassName('score')
for(let i = 0; i < dynamicScore.length; i++){
if(dynamicScore[i].innerText === initialState[i].initial){
dynamicScore[i].innerHTML = "?-?"
}else{
dynamicScore[i].innerHTML = initialState[i].initial
}
}
})
i added an id "hide" to your button this works fine

The solution I would recommend is that you make use of data attributes on the divs to store the scores. i.e. <div class="score" data-for="1" data-against="1">1-1</div>. Then it's easier to toggle the values. Since you're using jQuery,
// Set the values to ?-?
$('.match .score').html('?-?');
// set the actual scores
$('.match .score').each(function(){
$(this).html($(this).data('for') + '-' + $(this).data('against'));
});

My solution:
I would use the temporary storage. U can set the values for each element with the data()-Method
//STORE DATA IN TEMP STORAGE
$( ".score" ).each(function( index ) {
$(this).data("score-temp", $(this).text());
});
On Click-Event I would add a class "hide-score" to distinguish between both states. And if hide-score is already set, than you reset the values from the temporary storage
$("button").click(function() {
if ($(".table").hasClass( "hide-score" )) {
$(".table").removeClass("hide-score");
//set VALUE FROM TEMP STORAGE
$( ".score" ).each(function( index ) {
var score_temp = $(this).data("score-temp" );
$(this).text(score_temp);
});
}
else {
$( ".score" ).text("?-?");
$(".table").addClass("hide-score");
}
});

Related

How to get number of div left after deleting?

In my HTML there are eight div. I was able to get the number of the div using jQuery and insert it into the .num div element.
However when I delete one of the div by clicking the delete button, the number of divs in the span retrieved through jQuery won't update to the current number of divs remaining. It will still show 8.
How can I get the current number of div elements left in the DOM immediately after clicking the button?
setTimeout(() => {
if ($(".delete div").length > 0) {
$(".num span").html($(".delete div").length);
}
}, 100);
$("button").click(function() {
$(".delete div:last-child").remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
```
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>
The problem is because you're using setTimeout(), which only runs once after the specified delay.
For the pattern you're using to work you need to use setInterval() instead, which will run repeatedly at the set delay:
setInterval(() => {
if ($(".delete div").length > 0) {
$(".num span").html($(".delete div").length);
}
}, 100);
$("button").click(function() {
$(".delete div:last-child").remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>
However, using a timer for this is not ideal. As the number of div elements is only affected when the button is clicked, just update the .num span element in that event handler:
var $span = $(".num span").html($(".delete div").length);
$("button").click(function() {
$(".delete div:last-child").remove();
$span.html($(".delete div").length);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>

Could I get to an element using two ids?

Here's my code:
<div id='layer1'>
<div id='a'>
<div id='b'>
<div id='layer2'>
<div id='a'>
<div id='b'>
<div id='layer3'>
<div id='a'>
<div id='b'>
I want to try to get the element [a] of layer1.
Could I do this using pure javascript and withOUT jquery and other stuff?
An ID uniquely identifies one single element on the page. The behavior you described is more like "a class" inside of an ID:
document.querySelector("#counter-for-drinks .up-arrow")
and so if you want a different up-arrow, it is:
document.querySelector("#counter-for-burgers .up-arrow")
document.querySelector() is what is similar to jQuery $(" "). It also has the form document.querySelectorAll() for getting all matched elements.
Your HTML is missing closing tags. You can always validate your code here.
Also, you should use class instead of id.
<div id='layer1'>
<div class='a'></div>
<div class='b'></div>
</div>
<div id='layer2'>
<div class='a'></div>
<div class='b'></div>
</div>
<div id='layer3'>
<div class='a'></div>
<div class='b'></div>
</div>
You can use javascript to get elements:
document.querySelector("#layer1 .a")
var firstA = document.querySelectorAll('#layer1 #a');
var nodeString = '';
if (firstA.length > 0) {
for (var i = 0; i < firstA.length; i++) {
nodeString = nodeString + firstA[i].innerText + '<br/>';
}
}
document.getElementById('founded-nodes').innerHTML = nodeString;
#founded-nodes {
color: brown;
}
<div id='layer1'>
<div id='a'>layer1 aaa</div>
<div id='b'>layer1 bbb</div>
</div>
<div id='layer2'>
<div id='a'>layer2 aaa</div>
<div id='b'>layer2 bbb</div>
</div>
<div id='layer3'>
<div id='a'>layer3 aaa</div>
<div id='b'>layer3 bbb</div>
</div>
<div id="founded-nodes"></div>
As all said in above over comments and answers, one must use a single id on the same page, or else the use of classes is a must. But if you want to achieve this, you can have a look at code.

how can I show a div based on content in another div jQuery

I have multiple divs in html such:
<div class="litter">
<div class="litter-1">
<div class="status">Available</div>
<div class="available"><img /></div>
</div>
<div class="litter-2">
<div class="status">Available</div>
<div class="available"><img /></div>
</div>
</div>
The status text will vary based on user input. If the status is available the available class should not show. But if the status is unavailable then it should. The image is present all the time but only displaying if the status changes.
I can get the jQuery to either hide all of the images, or show them all, but not based on the html value of the status.
jQuery
if($('.litter > .status').html()==="Available") {
$(this).next('.available').hide();
} else {
$('.available').show();
}
Any help?
You could use a loop using jQuery .each():
// change selector to '.litter .status'
$('.litter .status').each(function() {
// loop through each .status element
// get partner img container .available
var imgContainer = $(this).parent().find('.available');
if ($(this).text() === "Available")
{
imgContainer.hide();
}
else
{
imgContainer.show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="litter">
<div class="litter-1">
<div class="status">Available</div>
<div class="available"><img src="https://via.placeholder.com/150/" alt="placeholder1" /></div>
</div>
<div class="litter-2">
<div class="status">Other status</div>
<div class="available"><img src="https://via.placeholder.com/150/" alt="placeholder2" /></div>
</div>
</div>
You can toggle a single class, status-available, and combine it with the adjacent sibling combinator to control the display of the image.
<!-- Image will show -->
<div class="status status-available">…</div>
vs.
<!-- Image will not show -->
<div class="status">…</div>
Example
/* Image is hidden by default */
.available > img {
display: none;
}
/* Adjacent sibling combinator in action */
.status-available + .available > img {
display: block;
}
<div class="litter">
<div class="litter-1">
<div class="status status-available">Available</div>
<div class="available">
<img src="http://placekitten.com/150/150" alt="Cute cat" />
</div>
</div>
<div class="litter-2">
<div class="status">Available</div>
<div class="available">
<img src="http://placekitten.com/150/150" alt="Cute cat" />
</div>
</div>
</div>
Ok, so Haldo put me on the right track, but in order to make it all come together with the string. Instead of if ($(this).text() === ("Available") I had to use this if ($(this).text().indexOf('Needs a Forever Home') > -1)
The rest of the code stays the same as Haldo's.

Detach and append divs/html jquery

I thought this would be kinda straightforward but i cant wrap my head around this. I got to following html:
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
I need to grab/detach the div's .test and put/append them into the .item div's. So the first div .test needs to go in the first div .item, the second div .test to the second div .item etc. So it becomes:
<div id="foo">
<div class="item">1<div class="test">test1</div></div>
<div class="item">2<div class="test">test2</div></div>
<div class="item">3<div class="test">test3</div></div>
<div class="item">4<div class="test">test4</div></div>
</div>
Now i found some jquery code and i came to this:
var child = $('#bar').find("div").eq(0);
var parent = $('#foo').eq(0);
child.detach();
parent.append( child );
This works but as suspected, it detaches/appends the first div. Now i need to detach/append them all one by one and from reading a lot of topics, i think i need to put a loop/each in there somewhere but i have no idea how and im not getting any closer after screwing around for hours.
Anyone who can put me in the right direction with this?
You can move all of them easily by just using the append() method and selecting all the divs:
$('#bar').append( $('#foo div') )
/* This is just for showing that the elements actually moved. */
#foo { background:red; }
#bar { background:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
<div>
Alternatively, if you want to do something with each element, you can use .each():
$('#foo div').each(function(i, elem) {
var $elem = $(elem);
//Do stuff
$('#bar').append($elem);
});
/* This is just for showing that the elements actually moved. */
#foo { background:red; }
#bar { background:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="foo">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div id="bar">
<div class="test">test1</div>
<div class="test">test2</div>
<div class="test">test3</div>
<div class="test">test4</div>
</div>
<div>
On solution is to get both collections and iterate over one of the collections. Also note that you don't need to use .detach. .append will already do that.
var $fooItems = $("#foo .item");
var $barTests = $("#bar .test");
$fooItems.each(function(index, el) {
$(this).append($barTests.eq(index));
});
Example Fiddle
I think there are two solutions for your issue : .childern() function or usiing jQuery selectors
For example using selector :
$("#bar > div")
or using children() function :
$("#bar").children("div");
also look at this post, you may have your answer here : jQuery - get all divs inside a div with class ".container"

jQuery for each identical parent div toggle nested divs if more than 3 using :nth-child

I have 2 identical parent divs with different content. If parent div has more than 3 child divs, at the end of the div should be displayed "show more" text that would slide all remaining hidden divs. I am new to JavaScript and jQuery and I couldn't completely understand selectors. Here is my code:
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>
<span class="showhide">Show-hide</span>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
</div>
<span class="showhide">Show-hide</span>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
<span class="showhide">Show-hide</span>
the result should display like this:
1
2
3
show-hide
1
2
1
2
3
show-hide
Here is the script:
$('.parent div:nth-child(n+4)').hide();
var l = $('.parent div').length;
if (l > 3) {
$('.showhide').show();
} else {
$('.showhide').hide();
}
$(".showhide").click(function() {
$this.find(".parent div:nth-child(n+4)").toggle('slide');
});
Only the first part of the code works. It hides divs more than 3 in each parent div. But the hiding text and toggle don't work.
I have tried multiple variations, like placing the span inside parent div, changing selectors to .closest, also tried to use :gt() instead of :nth-child but none worked.
You can do like this,
$(".parent").each(function() {
$(this).find(".child:gt(2)").hide();
});
$(".showhide").click(function() {
$(this).prev().find(".child:gt(2)").slideToggle();
});
Fiddle
.gt() selector will return the elements whose index is greater than the specified parameter
If you want to change the text after toggling, use this code,
$(".parent").each(function() {
$(this).find(".child:gt(2)").hide();
});
$(".showhide").click(function() {
var obj = this;
$(this).prev().find(".child:gt(2)").slideToggle(function() {
if ($(this).is(":visible"))
$(obj).text("hide");
else
$(obj).text("show more");
});
});
Edited Fiddle
Note that, you need to use the call back function of slideToggle to change the text, since slideToggle is asynchronous.
Final Fiddle
You can hide it with css:
.parent div:nth-child(n+4) {
display: none;
}
and use jquery to toggle the class to make it visible/hidden.
$('.parent').filter(function(){
return $(this).children().length <= 2;
}).next('.showhide').hide();
$('.showhide').click(function() {
$(this).text(function(i, txt) {
console.log(txt);
return txt === "Show" ? "Hide" : "Show";
});
$(this).prev('.parent').find('div:hidden, div.show').toggleClass('show').stop().slideToggle();
});
span {
cursor: pointer;
}
.parent div:nth-child(n+4) {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>
<span class="showhide">Show</span>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
</div>
<span class="showhide">Show</span>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
<span class="showhide">Show</span>

Categories

Resources