Hide the content based on Children class - javascript

I need one help with the code, I have two HTML div blocks with the same class name and there is one extra h2 tag with different class present in one div block. I want to hide if h2 class name is not present in that div and show if the h2 class name is present. Please find the below mentioned code that I have created.
-- First block Div --
<div class="course-content">
<h2 class="accesshide"></h2>
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="row">
<p>Content to Display</p>
</div>
</div>
-- Second block Div --
<div class="course-content">
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="single-section">
<p>Content to Display</p>
</div>
</div>
-- jQuery Code --
$(document).ready(function () {
if ($(".course-content").find(".accesshide")) {
$(".course-content").find(".topics").show();
} else if ($(".course-content").find(".single-section")) {
$(".course-content").find(".topics").hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="course-content">
<h2 class="accesshide"></h2>
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="row">
<p>Content to Display (this statement is inaccurate)</p>
</div>
</div>
<div class="course-content">
<ul class="topics">
<li class="data-list">Content not to Display (this statement is inaccurate)</li>
</ul>
<div class="single-section">
<p>Content to Display</p>
</div>
</div>

Since the controls are independent events, they should be evaluated separately. Therefore, two separate if blocks should be used. In the second event in the solution below, the first child element of the parent element of the selected element is hidden by selecting it.
$(document).ready(function () {
if ($(".course-content").find(".accesshide")) {
$(".course-content > .accesshide").find(".topics").show();
}
// Because both <div> elements have the ".topics" class style applied, the ".single-section"
// element is selected and the first child element of the parent element is hidden.
if ($(".course-content").find(".single-section")) {
$(".course-content > .single-section").parent().children(':first-child').hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="course-content">
<h2 class="accesshide"></h2>
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="row">
<p>Content to Display</p>
</div>
</div>
<hr>
<div class="course-content">
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="single-section">
<p>Content to Display</p>
</div>
</div>

This is trivial using a CSS child selector (>). Just find the collection of elements that are an accesshide child of a course-content and hide the topics child of their parents.
You could do something similar with a descendant selector ( ), but since you know it's a child for this case, the child selector is perhaps more accurate.
MDN's Child Combinator docs.
$(document).ready(function () {
$('.course-content>.accesshide').parent().find('.topics').hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="course-content">
<h2 class="accesshide"></h2>
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="row">
<p>Content to Display</p>
</div>
</div>
<div class="course-content">
<ul class="topics">
<li class="data-list">Content not to Display (this should actually be shown - there's no h2 in the parent div)</li>
</ul>
<div class="single-section">
<p>Content to Display</p>
</div>
</div>

I want to hide if h2 class name is not present in that div and show if the h2 class name is present.
You don't need any JS code, just only CSS with adjacent or general sibling combinator. For example:
.course-content .topics {
display: none;
}
.course-content .accesshide + .topics {
display: block;
}
When you have to use jQuery then you can use the same logic and the .next() method (or .nextAll()):
$(".course-content").find(".topics").hide();
$(".course-content").find(".accesshide").next(".topics").show();
If the controlled block can be both before and after the control block, the shortest way is to use the .siblings() method. If you need to show the .topics block if there is an .accesshide block or a .single-section block nearby, you can use this jQuery method for both cases:
$(document).ready(function () {
$(".course-content").find(".topics").hide();
$(".course-content").find(".accesshide, .single-section").siblings(".topics").show();
});
<div class="course-content">
<ul class="topics">
<li class="data-list">Content not to Display</li>
</ul>
<div class="row">
<p>There are no special blocks nearby</p>
</div>
</div>
<div class="course-content">
<h2 class="accesshide"></h2>
<ul class="topics">
<li class="data-list">Show because of the .accesshide block</li>
</ul>
<div class="row">
<p>Case 1</p>
</div>
</div>
<div class="course-content">
<ul class="topics">
<li class="data-list">Show because of the .single-section block</li>
</ul>
<div class="single-section">
<p>Case 2</p>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

How to set array or multiples var inside jquery .html() method?

I've got a array with content [a,b,c] and I need to put it inside a .html()
and my original place its 3 child
When i put it directly - this way:
$('#listProducts div ul li').html(newElements); (not esactly this code, but I short it)
whats happens (return like this [abc]):
<div id=listProducts>
<ul>
<li>A,B,C</li>
<li>A,B,C</li>
<li>A,B,C</li>
</ul></div>
result i want:
<div id=listProducts>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul></div>
I tried this:
$('#listProducts ul li ul li div').html(function(newElements){
for(let i = 0; i < newElements.length; i++){
newElements[i];
}
});
but i research about functions inside .html() and it seems only accept index parameters.
i think about something like
$().html(newElements[0],newElements[1],newElements[2]) or
separe in 3 variables $().html(element1,newElements2,newElements3) // but i guess its not possible with .html()
Is there a way to do that?
Ps: I cant change the HTML, and i cant just send directly someting like <li> + newElements[i]; because its atached with backend parameters uniques with every div, ul, etc.
Its my first question at SO, and english is not my first language. So if a make any mistake, please advice me and I'll change. Thank you so much!!
Edit1:
testing:
.html(function(i) {
return arr[i];
});
FULL CODE:
const arr = $('#listProducts ul li ul li div a').get().sort(function(a, b) {
return a.getAttribute('href') > b.getAttribute('href') ? 1 : -1;
}).map(function(el) {
return $(el).clone(true)[0];
});
$('#listProducts ul li ul li div').html(function(i) {
return arr[i];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
2TH ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
expected:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
2ND ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
ADD:
The .get().sort is to sort the results alphabetically, according to the URL and is working fine.
"another div 1" and "another div 2" are not the same as those "another div 1" and "another div 2" on the other li.
There are much more than 3 items.
If the <li> items are already in the <ul>, you can pass a function into .html() and use the index i it gives to access the content you want to place into each <li> like so:
const arr = ['A','B','C'];
$("#listProducts ul li").html(function(i) {
return arr[i];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=listProducts>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
If the <li>s aren't already inside your <ul> you can map your arr to a list of elements, and then use .html() to add these elements to the <ul>:
const arr = ['A','B','C'];
$("#listProducts ul").html($.map(arr, function(text) {
return $('<li>', {text});
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=listProducts>
<ul>
</ul>
</div>
EDIT:
You can get all the <li> and sort these by the anchor tags href attribute. You can then use .append() to append the sorted elements to your DOM. The purpose of using .append() rather than .html() is that .append() will insert the elements into the DOM, thus removing the old element and adding the new one (so no need to .clone())
const arr = $('#listProducts ul li ul li').get().sort(function(a, b) {
const anchorA = $("a", a);
const anchorB = $("a", b);
return anchorA.attr('href') > anchorB.attr('href') ? 1 : -1;
});
$('#listProducts ul li ul').append(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
2TH ELEMENT
<div class="another 1">1. another div 1</div>
<div class="another 2">1. another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">2. another div 1</div>
<div class="another 2">2. another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">3. another div 1</div>
<div class="another 2">3. another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>

css selector for visible only first section content

I have a JavaScript toggle so T need to tried to collapse all sections on load by default - by inserting
ul.section-content{
display:none;
}
and it is working. But when I tried to hide first-child or not first-child it is not working.
.cscr .csec .section ul:first-of-type {
display: none;
}
<div class="cscr">
<ul class="csec">
<li class="section">
<div class="section-header">
<div class="section-left">
<h5>section01</h5>
<p>hello1</p>
</div>
<div class="section-meta">
</div>
</div>
<ul class="section-content">
<li class="course-item">
<h1>lesson01</h1>
</li>
</ul>
</li>
<li class="section">
<div class="section-header">
<div class="section-left">
<h5>section02</h5>
<p>hello1</p>
</div>
<div class="section-meta">
</div>
</div>
<ul class="section-content"> /* to hide this */
<li class="course-item">
<h1>lesson02</h1>
</li>
</ul> /* to hide this */
</li>
</ul>
</div>
second case:
and how to display only first and not others with help of not-first-child
screenshot of what is needed
Do you want something like this? https://codepen.io/anon/pen/YOOXOv. Change the CSS properties to whatever you want.
Here you are selecting all sections except the first one and then selecting ul inside them.

Multiple layers of tabination within a webpage

I have a question about how to add layers of tabination inside one webpage.
Currently, the pages which I would like to edit have a jQuery tab function to swap between tabs with different content. I would like to go one step further and have an encompassing tabination system with a page entry tab containing initial content and a button to the next tab; and inside the next tab have the current active tab function. Check out the picture if this is confusing:
Image for Visualization Edit: In the image the 'layers' should be 'sections'.
My current code: One layer of tabination
jQuery in header.php
<script>
$(function() {
$('.tab-panels .tabs li').on('click', function(){
var $panel = $(this).closest('.tab-panels');
$panel.find('.tabs li.active').removeClass('active');
$(this).addClass('active');
// Figure out which panel to show
var panelToShow = $(this).attr('data-panelid');
// Hide current panel
$panel.find('.tab.active').hide(0, showNextPanel);
// Show next panel
function showNextPanel() {
$(this).removeClass('active');
$('#'+panelToShow).show(0, function() {
$(this).addClass('active');
});
}
});
});
</script>
Tabs include file
Styled as a horizontal bar.
<div class="tabs-container">
<ul class="tabs">
<li data-panelid="panel1" class="active">Tab 1</li>
<li data-panelid="panel2">Tab 2</li>
<li data-panelid="panel3">Tab 3</li>
<li data-panelid="panel4">Tab 4</li>
</ul>
</div>
HTML of the webpage
I have wrapped each of the encompassing tabs as 'SECTIONS', and the inside tabs as 'TABS'. The header (containing the jQuery), and this page are called in another php file.
<div class="section-wrap">
<div class="container section active" id="section1">
<div class="row">
<div class="col-md-12">
<div>CONTENT</div>
<div class="button-container">
<span>BUTTON TO NEXT SECTION</span>
</div>
</div>
</div>
</div>
<div class="container section" id="section2">
<div class="container tab-container">
<!-- Incluce Tabs -->
<?php include(ROOT_PATH . "/inc/tabs.php") ?>
<div class="row tab active" id="panel1">
<div class="col-md-12">
<h2>SUBTITLE</h2>
<p>CONTENT</p>
</div>
</div>
<div class="row tab" id="panel2">
<div class="col-md-12">
<h2>SUBTITLE</h2>
<ul>
<li>CONTENT</li>
<li>CONTENT</li>
<li>CONTENT</li>
<li>CONTENT</li>
</ul>
</div>
</div>
<div class="row tab" id="panel3">
<div class="col-md-12">
<h2>SUBTITLE</h2>
<h3>SUB SUBTITLE</h3>
<p>CONTENT</p>
<h3>SUB SUBTITLE</h3>
<p>CONTENT</p>
</div>
</div>
</div>
</div>
</div>
<div class="mobile-breadcrumb">
<!-- Include Breadcrumb -->
<?php include(ROOT_PATH . "/inc/breadcrumb.php") ?>
</div>
</div>
<!-- END PAGE CONTENTS -->
<!-- Include Footer -->
<?php include(ROOT_PATH . "/inc/footer.php") ?>
I imagine the same jQuery script could be used to switch between sections, however I'm not sure how to implement this and would love some help. The user would not need to go back to the initial page entry 'section'. Also, the reason why I do not wish to use a different web page entirely is that the pages that this system will be implemented on are already 4 layers deep in the website.
I hope this isn't too confusing, thanks in advance! :)
Definitely not the best way to do this but here is my current solution:
jQuery in header
$(function() {
$('#section1').show().siblings().hide();
$('.section-button').find('a').on('click', function(e){
e.preventDefault();
$(this.hash).show().siblings().hide();
})
});
</script>
HTML of page
<div class="section-wrap">
<div class="container section" id="section1">
<div class="row">
<div class="col-md-12">
<p>CONTENT</p>
<p>CONTENT</p>
<span class="section-button">GO TO SECTION 2</span>
</div>
</div>
</div>
<div class="container section" id="section2">
<p>CONTENT</p>
<p>CONTENT</p>
</div>
</div>

Changing div content on hover in another element

have been scratching my head over this for the past few days, basically the functionality I am going for is that I have a <ul> with 7 <li> elements and then I have another section with 7 <p> elements. What I am looking for is that when I hover on one of the <li> elements it puts the text from the corresponding <p> element. The thing is that I cannot play directly with the text or inject via jQuery, because the content in the <p> are references to yaml files. I have hidden all the elements except the first one which should appear on pageload, and then I guess there is a way of hiding the <p>'s and showing only the corresponding one. Thanks in advance! please find attached the code snippet:
<section class="container clearfix">
<div class="text-center">
<ul class="solutions-items">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</section>
<section class="container clearfix">
<div class="text-center solutions-text-p">
<p class="">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<p class="hidden">{% yaml reference %}</p>
<button class="solutions-learnmore-btn">{% yaml reference %}</button>
</div>
</section>
If you mean you want to show the corresponding p when hovering an li, you can do it by index, or by associating them with a data-* attribute.
Here's an example by index:
We hook mouseenter on the list, delegated so that we only receive the event when it relates to one of the lis
When we get the event, we get the index of that li relative to its siblings
Then we grab the paragraphs in the solutions-text-p div, make sure they all have the hidden class, then remove it from the one with the same index as the li
Live Copy - I've made the jQuery part fairly verbose for clarity:
$(".solutions-items").on("mouseenter", "li", function() {
var index = $(this).index();
var paras = $(".solutions-text-p p");
paras.addClass("hidden");
paras.eq(index).removeClass("hidden");
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section class="container clearfix">
<div class="text-center">
<ul class="solutions-items">
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
<li>Sixth</li>
<li>Seventh</li>
</ul>
</div>
</section>
<section class="container clearfix">
<div class="text-center solutions-text-p">
<p class="">First</p>
<p class="hidden">Second</p>
<p class="hidden">Third</p>
<p class="hidden">Fourth</p>
<p class="hidden">Fifth</p>
<p class="hidden">Sixth</p>
<p class="hidden">Seventh</p>
<button class="solutions-learnmore-btn">{% yaml reference %}</button>
</div>
</section>
Here's a less verbose version of the jQuery:
$(".solutions-items").on("mouseenter", "li", function() {
$(".solutions-text-p p")
.addClass("hidden")
.eq($(this).index())
.removeClass("hidden");
});
You can use the mouse enter event and index of the hovered element to show/hide the target elements
var $ps = $('.solutions-text-p p')
$('.solutions-items li').mouseenter(function() {
var $cur = $ps.eq($(this).index()).show();
$ps.not($cur).hide();
})
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section class="container clearfix">
<div class="text-center">
<ul class="solutions-items">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
</div>
</section>
<section class="container clearfix">
<div class="text-center solutions-text-p">
<p class="">1</p>
<p class="hidden">2</p>
<p class="hidden">3</p>
<p class="hidden">4</p>
<p class="hidden">5</p>
<p class="hidden">6</p>
<p class="hidden">7</p>
<button class="solutions-learnmore-btn">{% yaml reference %}</button>
</div>
</section>
$('.solutions-items li').mouseenter(function() {
$("#show_data").text($(this).data("text"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section class="container clearfix">
<div class="text-center">
<ul class="solutions-items">
<li data-text="bla_1">1</li>
<li data-text="bla_2">2</li>
<li data-text="bla_3">3</li>
<li data-text="bla_4">4</li>
<li data-text="bla_5">5</li>
<li data-text="bla_6">6</li>
<li data-text="bla_7">7</li>
</ul>
</div>
</section>
<section class="container clearfix">
<div class="text-center solutions-text-p">
<p id="show_data"></p>
<button class="solutions-learnmore-btn">{% yaml reference %}</button>
</div>
</section>

How can I separate div from another class?

In my WordPress based website a plugin automatically wraps every element in the post content with <ul></ul>. That wraps everything even the <div>s which is invalid.
I want to unwrap certain elements and tried jQuery .unwrap . But I am able to unwrap some elements except a few div elements.
Here is the code:
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
From the above code, I want to separate <div class="button-main-wrap"> from <ul class="plugin_class"> or stop the <ul class="plugin_class"> to wrap elements which doesn't belong to it. ex: the div <div class="button-main-wrap"> or other elements like <div class="number">.
I tried these:
jQuery("ul").find('.button-main-wrap').unwrap();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
This unwraps all the <ul> elements in .post-content which I don't want.
jQuery(".plugin_class").find('.button-main-wrap').unwrap();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
This doesn't do anything.
I put all the code together in this Fiddle.
How to separate the div and stop the to wrap elements un-necessarily?
It is because div is not a valid child of ul, so wrap the contents of the ul with li then unwrap the li elements so that the parent ul will get removed
$('.plugin_class > ul').each(function(){
$(this).wrapInner('<li />').contents().unwrap()
})
Demo: Before, After

Categories