How to hide certain children(). of a parent(). div? - javascript

I want to display only div.card1 when a user clicks on a selection menu I have made
<table id="flowerTheme">
<tr>
<td>
<div class="card1">
<div class="guess"><img src="Test Pictures/QuestionMark.gif" /></div>
<div class="remember"><img src="Test Pictures/flower.gif" /></div>
</div>
</td>
<td>
<div class="card2">
<div class="guess"><img src="Test Pictures/QuestionMark.gif" /></div>
<div class="remember"><img src="Test Pictures/flower.gif" /></div>
</div>
</td>
</tr>
</table>
I have a function that toggles the class 'selected' when the user clicks on an image. The following works perfectly:
if($('.flowerThemePic').hasClass('selected') && $('.sixCardLayout').hasClass('selected')) {
$('#flowerTheme').css('display', 'inline');
However, as I stated before, I would like to have card2 to not be displayed. I have tried:
if($('.flowerThemePic').hasClass('selected') && $('.sixCardLayout').hasClass('selected')) {
$('#flowerTheme').not('.card2').css('display', 'inline')
But this does not do anything. I have also tried:
if($('.flowerThemePic').hasClass('selected') && $('.sixCardLayout').hasClass('selected')) {
$('#flowerTheme').find('div').not('.card2').css('display', 'inline')
But this hides both cards. What would be the right method of displaying card1 and not card2?

$('#flowerTheme').css('display', 'inline');
$('.card2').hide();

First of all, it looks to me that card1 and card2 should be id, not class. The difference is that IDs are supposed to be unique, while classes are supposed to be re-used. Since you're using card1 and card2 to uniquely identify those cards, they should be IDs. Furthermore, they probably need a class as well: probably class="card", so they can be referred to as a group.
Secondly, I think you should be using CSS, not jQuery for the actual hiding/showing. Consider this:
table#flowerTheme.selection-made :not(.selected) .card
{
display: none;
}
This would hide any element that has class="card" that doesn't have any parent with class="selected". Note the .selection-made on #flowerTheme -- this allows the default case to show every card, but then when someone clicks, you do $('#flowerTheme').addClass('selection-made'); and then $(this).addClass('selected'); (assuming you're using $(wherever selected goes).click() for this). It's a bit unclear from your question exactly where the selected class is being added, but I'd recommend doing it this way. It is far more easily maintained, jQuery has to do less work, and it leaves you with a very simple and easy way to expand the list of cards.

What about :
$('#flowerTheme .card2').hide();
?

You can write a javascript function to hide children...
function hideSpecificChildren(childClass){
var child = document.getElementByClass(childClass);
if(tab.style.display == "block") {
tab.style.display = "none";
}else {
tab.style.display = "block";
}
}

Try this:
$('#flowerTheme .card2').css('display','none').parent().show();
Demo
OR
$('#flowerTheme .card2').hide().parent().show();
Demo

Related

How to hide an element in if statement?

I am making an html change to a CMS that will affect all pages when the changes are live. I would like this html alert to only affect 1 specific page. I am attempting to do an if statement for the page title.
The logic is that if the page title is Test Article Two then show the html that I have put in place, if not then display=none. With this logic in place, I am viewing the html on all pages not just the one I want it to show.
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<!--page alert -->
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
<script>
function showAlert() {
if(#pageTitle === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
}else {
document.getElementById('alert-dialog').style.display = 'none';
}
}
</script>
I'd recommend changing a class on the body element so that you can use CSS for the styling.
HTML: nothing really changed here
<body>
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
</body>
javascript: just check the document.title and add the class the the body element
<script>
if(document.title === "Test Article Two") {
document.body.classList.add("show-alert");
}
</script>
Use CSS for the styling. Always hide #alert-dialog and only show it when we add the class to the body.
<style>
#alert-dialog {
display: none;
}
.show-alert #alert-dialog {
display: block;
}
</style>
If you are making static pages or using server side rendering, you could add logic to add a class to show or hide the alert element without adding more javascript to the page. It will have the relevant class(es) when the html is generated and delivered. This way you won't have to create a function, call it and manipulate the DOM after everything is rendered.
I may have missed this in the code above, are you calling the showAlert function anywhere? If not, your alert won't be shown (or will be shown depending on the default styles).
One thing I'd caution against is the imperative nature of the code here. If you wanted to reuse this alert functionality on another page, you'd have to add another more logic to detect another page title every time you wanted to use the alert. Since you are using a CMS, you might consider adding a flag to show the alert, and on this specific page, turn that flag on.
If you wanted to use the function strategy, I'd set your default alert styles:
#alert-dialog {
display: none;
}
.show {
display: block;
}
and try something like this:
<script>
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').classList.add('show');
}
}
document.addEventListener("DOMContentLoaded", showAlert);
</script>
Another alternative is to take a look at the path of the page this is supposed to be on (window.location.pathname) and using regex to see if it matches what you want. I'd recommend that over looking at the title since it's more likely the title of the page will change rather than the url.
In JavaScript, you can access the page title with document.title. You should change the script like this:
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
} else {
document.getElementById('alert-dialog').style.display = 'none';
}
}

Toggle visibility for multiple divs for navigation bar

Earlier, I did an assignment where I was supposed to write code in Javascript in order to toggle visibility for the submenus each belonging to their own topmenu in a navigation bar for a webpage. The visibility should be set to hidden by default and should be shown when a topmenu is clicked on. I know how to toggle visibility for ONE submenu belonging to a topmenu, but fail to make my code work for multiple elements. With help from here, I got my code to work. However, my teacher was not pleased over the fact that I used onclick in my HTML-code. So my question is now: How do I move all functionality to javascript, and thereby not use onclick in my HTML?
Note: Of course I gave it a try myself but I cannot make the pairing between header and div work correctly... By the pairing I mean that visibility of the div with the class "left_submenu_1" should be toggled when you click the topmenu "left_top1". Thus should the visibilily of the div with the class "left_submenu_2" be toggled when you click the topmenu "left_top2".
I guess I should start something like this:
var left_headings = document.getElementsByClassName("left_top");
for(var k = 0; k < left_headings.length; k++) {
??????
}
Earlier related question: Toggle visibility for multiple divs with one function: navigation bar
HTML
<a class="left_top" onclick = "toggle('.left_submenu_1')">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top" onclick = "toggle('.left_submenu_2')">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
Javascript
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
Please note: We are NOT allowed to use jQuery or to give the topmenus id:s, as the idea is to use one general function to toggle the visibility.
EDIT: Changing the html was out of the question, updated answer.
Instead of using onclick to handle the event, assign the eventhandler via javascript, like this (Note that I added IDs to the elements in order to be able to select them properly):
jsfiddle: https://jsfiddle.net/pkptn4gf/
<a class="left_top">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
var clickables = document.getElementsByClassName("left_top");
clickables[0].addEventListener("click", function(){
toggle('.left_submenu_1');
});
clickables[1].addEventListener("click", function(){
toggle('.left_submenu_2');
});

Sorting through div class via opacity

So I'm using classes to sort different content, but I'm not actually sure how to apply this sorting.
<div class="class1"><div class="heads">Title</div>
<div class="description"><p>Class 1 Item 1</p></div></div>
<div class="class2"><div class="heads">Title</div>
<div class="description"><p>Class 2 Item 1</p></div></div>
<div class="class2"><div class="heads">Title</div>
<div class="description"><p>Class 2 Item 2</p></div></div>
<div class="class3"><div class="heads">Title</div>
<div class="description"><p>Class 3 Item 1</p></div></div>
So let's say the user clicks a button that says 'Class 2'. I want the opacity of everything that is not class 2 to be, say, .5 while class 2's opacity stays at 1. I've tried using .not(), but I'm not familiar with it and most examples use it in conjunction with .siblings(), and I don't want the siblings to fade either. Help? I'm not sure what to do.
Edit: Sorry about the orphan s. ^_^; Fixed them!
http://jsfiddle.net/orjj65g0/7/
$("#container button").click(function() {
var className = $(this)[0].className;
$("#container button").each(function() {
if($(this)[0].className !== className) {
$(this).next().addClass("op05");
$(this).next().removeClass("op1");
} else {
$(this).next().addClass("op15");
$(this).next().removeClass("op05");
}
});
});
With $("#container button").click(...) you access every button in #container.
$(this).[0].className is the class name of the button you have clicked.
After you have clicked the button, you go through every button in the container:
$("#container button").each(...)
In the container you compare the class names with the clicked class name. If there are not the same, than add the class "op05" to the div after the button and remove the class "op1" from the div after the button:
(Example:
<button class="classN">click</button>
<div class="content">div after button</div>
$(".classN").next()...
)
Here:
$(this).next()...
And with all the div's after the button(s), that have the same class name happens the same with the 'opposite' class names.
$("div").not(".class2").css("opacity", "0.5")
will set opacity of all divs except for ones with class class2 to 0.5.
If you are using a container:
$('.container>div:not(.class2)').css('opacity', 0.5);
1. You have invalid HTML. a tag opening is missing. Based on my assumptions, that's how it should look like:
<div class="classX">
Title
</div>
<div class="description">
<p>Class X Item 1</p>
</div>
But it's very unintuitive syntax. What is .description content for? I suggest you to rewrite syntax. For example:
<div class="classX">
Title
<div class="description">
<p>Class X Item 1</p>
</div>
</div>
2. You can use .not() method or :not() selector in jQuery
According to my version of HTML. Let's code!
$("a").on('click', function(){
var $t = $(this).parent(); // clicked div.class2 for example
$t.css("opacity", 1).siblings().css("opacity", 1); // undo selection
$t.siblings().not("."+$t.attr("class")).css("opacity", 0.5);
// hide other classes. Equivalent with selector:
//$t.siblings(":not(."+$t.attr("class")+")").css("opacity", 0.5);
});
Check it that's what you want: http://jsfiddle.net/Tymek/2k85m8r9/

How to change a specific HTML string with jQuery

Here is my HTML code:
<th>
Click<br/>
<img class="magnifier" height="66" src="../Images/magnifier-zoom.png" width="75"><br/>
To Enlarge
</th>
I have a jQuery script that when clicked it toggles an enlarge class, so when someone clicks to enlarge I want to change the enlarge word to shrink would there be any simple way of doing this in jQuery?
Or do you guys think I am better off having 2 <div>'s or even <span> elements and toggle the display of each element?
There are numerous ways to do this. You could leverage pseudo-element content, do string manipulation with JavaScript, and more. In the end, the best approach is to probably just toggle the visibility of a couple nested elements:
I've placed a default "shrink" class on my td element. Within, I have a couple span elements customized with explicit data-do attributes indicating the purpose of each:
<td class="shrink">
Click to
<span data-do="enlarge">Enlarge</span>
<span data-do="shrink">Shrink</span>
<img src="..." />
</td>
We target the data-do attributes that are nested within elements that have corresponding classes, and we disable the display of these elements:
.shrink [data-do='shrink'],
.enlarge [data-do='enlarge'] {
display: none;
}
In order to toggle the class of the td element, we bind up some simple jQuery:
$("td").on("click", function () {
$(this).toggleClass("shrink enlarge");
});
Anytime a td is clicked (you can make the selector specific to a single td), we add toggle the "shrink" and "enlarge" classes. If "enlarge" was present to begin with, it is removed; otherwise it will be added. The same goes for "shrink".
Change your HTML to
<th>
<div>Click</div>
<img class="magnifier" height="66" src="../Images/magnifier-zoom.png" width="75">
<div>To Enlarge</div>
</th>
To have elements instead of text nodes.
Then you can do simple:
$('.magnifier').click(function() {
var $next = $(this).next();
$next.text($next.text() == 'To Enlarge' ? 'To Shrink' : 'To Enlarge');
})
Demo: http://jsfiddle.net/B7GDQ/
This is the direct answer to your questions, although not the best method:
$(".magnifier").on("click", function () {
if ($(this).hasClass('enlarge')) {
$(this).removeClass('enlarge');
this.parentNode.lastChild.textContent = 'To Enlarge'
}else{
$(this).addClass('enlarge');
this.parentNode.lastChild.textContent = 'To Shrink';
}
});
The ideal method would be to use pseudo elements:
Codepen
HTML:
<div class="magnifier">
Click<br/>
<img height="66" src="../Images/magnifier-zoom.png" width="75"><br/>
</div>
CSS:
.magnifier::after {
content: 'To Enlarge';
}
.magnifier.enlarge::after {
content: 'To Shrink';
}
JS:
$(".magnifier").on("click", function () {
$(this).toggleClass('enlarge');
});

Javascript change div content upon a click

I'm pulling a content from PHP array and I have a situation like this:
<div class="weight-display">
<span>04/25/2011</span> <span>100lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
<div class="weight-display">
<span>04/27/2011</span> <span>150lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
etc...
Now when somebody clicks on Edit within, let's say, first div where weight is 100lbs, I just need that "div" to change and to have input field instead of simple text where weight is (while others will remain the same) and to be like this:
<div class="weight-display">
<span>04/25/2011</span> <input type="text" value="100" /> <span>Save</span> <span>Cancel</span>
</div>
<div class="weight-display">
<span>04/27/2011</span> <span>150lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
etc..
So basically div has to "reload itself" and change content. Now I really need some very simple Javascript solution. Preferably I would like a solution with a hidden div beneath original one, so they just swap places when user clicks on EDIT and in a case if CANCEL is pressed to swap places again so original div with text is displayed...
Thanks,
Peter
<style type="text/css">
/* Normal mode */
.weight-display div.edit {display:none}
/* Editor mode */
.weight-edit div.show {display:none}
</style>
<div class="weight-display">
<button onclick="toggle(this)">Edit this!</button>
<div class="edit"><input type="text" value="Test" /></div>
<div class="show">Test</div>
</div>
<script type="text/javascript">
function toggle(button)
{
// Change the button caption
button.innerHTML = button.innerHTML=='Edit this!' ? 'Cancel' : 'Edit this!';
// Change the parent div's CSS class
var div = button.parentNode;
div.className = div.className=='weight-display' ? 'weight-edit' : 'weight-display';
}
</script>
What you suggest is basically correct. I would generate two div's one for display and one edit. The edit div will initially have display: none. When the Edit is clicked, hide the display div and show the edit div.
How about something like:
onClick event calls a function (EDITED to be a little smarter than my original brute force method):
function swapdivs ( id_of_topdiv, id_of_bottomdiv ) {
var topdiv = getRefToDiv( id_of_topdiv );
var bottomdiv = getRefToDiv( id_of_bottomdiv );
var temp = topdiv.style.zIndex;
topdiv = bottomdiv.style.zIndex;
bottomdiv = temp.style.zIndex;
}
Could that or similar work for you? Or am I missing some subtle yet crucial requirement?

Categories