JS hiding a div while targeting anchor - javascript

I have multiple divs (class="profile") wich are hidden by default. Each div is only shown when targeted. I want all divs with class="employeeul" to be hidden when one of the profile divs is targeted. I don't get this working with css, does anyone know why? A JS solution is good as well. (I think I can't use something like onclick, because the divs must hide when the anchors are accessed from other sites.)
This is my code (I removed the divs content):
<div class="narrow_content">
<div class="profile" id="m_empfang0"></div>
<div class="profile" id="m_empfang1"></div>
<div class="profile" id="m_mitarbeiter0"></div>
<div class="profile" id="m_mitarbeiter1"></div>
<div class="profile" id="m_mitarbeiter2"></div>
<div class="profile" id="m_mitarbeiter3"></div>
<div class="profile" id="m_mieter0"></div>
<div class="profile" id="m_mieter1"></div>
<div class="profile" id="m_mieter2"></div>
<div class="employeeul">
<ul> <!-- Empfang -->
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
<div class="employeeul">
<ul> <!-- Mitarbeiter -->
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
<div class="employeeul">
<ul> <!-- Mieter -->
<li class="employee"></li>
<li class="employee"></li>
<li class="employee"></li>
</ul>
</div>
</div>

It seems like you just need the syntax for displaying/hiding items dynamically when the page has a specific url. In that case, here is a simple JS solution:
//get an array of elements with the class we're interested in working with
var employeeuls = document.getElementsByClassName("employeeul");
//get the current url
var url = window.location.href;
//if the current url is equal to example.php#profile, hide some elements
if(url == "example.php#profile")
{
//iterate over the array and apply the style to hide the elements
for(i=0; i < employeeuls.length; i++)
{
employeeuls[i].style.display = "none";
}
}
//otherwise, the elements should be hidden
else
{
//iterate over the array and apply the style to hide the elements
for(i=0; i < employeeuls.length; i++)
{
employeeuls[i].style.display = "block";
}
}
NOTE: "block" is the default display property for unordered lists.
I understand you're not using jQuery, but I'm going to include the jQuery equivalent for anyone viewing this post in the future:
//variable assigned to all elements with class "employeeul"
var employeeuls = $(".employeeul");
//get the current url
var url = $(location).attr("href");
//apply the style change
if(url == example.php#profile)
{
employeeuls.hide();
}
else employeeuls.show();

If by targeting, you mean the hash value in the URL, you just need to write some JS to grab that hash value and toggle the css. Then toggle show/hide (or a visibility class via jQuery).
$(document).ready(function(){
var $profiles = $('.profile'); // Store all the profiles in a query
var hashTarget = location.hash.replace('#', ''); // Returns hash value
function showTargetedDiv(){
$profiles.hide(); // Hide any divs that may previously be showing
$('#' + hashTarget).show();
}
showTargetedDiv();
$(window).on('hashchange', showTargetedDiv); // Event handler
});

Related

How to use jQuery toggle method dynamically?

In my project, there are so many jQuery toggles needed for changing text and icons. Now I’m doing that using:
$("#id1").click(function () {
//Code to toggle display and change icon and text
});
$("#id2").click(function () {
//Same Code to toggle display and change icon and text as above except change in id
});
The problem is that I got so many to toggle, the code is quite long but all I change for each one is the id. So I was wondering if there is any way to make this simple.
Below is a sample pic. I got so many more in single page.
There are two issues here.
How to run the same action on multiple elements
How to know which element you've clicked so that you can run a relevant action on it. (most of the existing answers skip this part).
The first is to use a class for each of the elements you want to click, rather than wire up via an id. You can use a selector similar to [id^=id] but it's just cleaner to use a class.
<div id="id1" class="toggler">...
which allows you to:
$(".toggler").click(function() ...
the second is it associate the clickable with the item you want to toggle. There are many ways to do this, my preferred option is to associate them with data- attributes, eg:
<div class="togger" data-toggle="#toggle1">...
which allows you to:
$(".toggler").click(function() {
$($(this).data("toggle")).toggle();
});
The key here is that this is the element being clicked, so you can do anything else with this such as show/hide an icon inside or change colour.
Example:
$(".toggler").click(function() {
$($(this).data("toggle")).toggle();
$(this).toggleClass("toggled");
});
.toggler { cursor: pointer }
.toggled { background-color: green }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="toggler" data-toggle="#t1">T1</div>
<div class="toggler" data-toggle="#t2">T2</div>
<div class="toggler" data-toggle="#t3">T3</div>
<hr/>
<div id="t1" style='display:none;'>T1 content</div>
<div id="t2" style='display:none;'>T2 content</div>
<div id="t3" style='display:none;'>T3 content</div>
Oh,Can you use a class instead of id?
<ul>
<li class="idx">A</li>
<li class="idx">B</li>
<li class="idx">C</li>
</ul>
$(".idx").click(function(e){
//Code to toggle display and change icon and text
let target = e.target;
//You can do all what you want just base on the `target`;
});
You can store the queries in an array, and iterate over them to perform the same JQuery operation on all of them
let ids = ["#id1", "#id2", "#id3", "#randomID"]
ids.forEach((id) => {
console.log($(id).html())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
<li id="randomID">D</li>
</ul>
Or (If like your example) and all of the id's are actually id1, id2, id3, ... etc.
let id = "id";
let n = 3; //amount of id's
for (let i = 1; i <= n; i++) {
console.log($("#" + id + i).html())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
</ul>
You can try the below code.
var num = $("#myList").find("li").length;
console.log(num)
for(i=0;i<num;i++){
$("#id"+ i).click(function(e){
let target = e.target;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<ul id="myList">
<li id="id1">A</li>
<li id="id2">B</li>
<li id="id3">C</li>
</ul>

How to find certain text on child nodes using JavaScript when selecting by class name

I have multiple divs with the same structure as follows, I need to check for a text within the child nodes on each main div tag
<div class="s4-wpcell-plain">
<div class="ms-chrome">
<div class="ms-chrome-title" id="WPWPQ6_ChromeTitle">
<span title="My Content" id="WPTitleWPQ6" class="js-wp-titleCell">
<h2 style="text-align:justify;" class="ms-wp-titleText">Results (0)</h2>
</span>
</div>
<div wpid="50348231-8acb-4794-af32-d481915fc127" haspers="false" id="WPWPQ6" width="100%" class="ms-WPBody ms-WPBorder noindex ms-wpContentDivSpace " allowdelete="false" style="">
<div style="display: none;">
</div>
<div componentid="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr" id="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr">
<div class="containerForStyle">
<ul class="cbs-List">
<div class="ms-srch-result-noResults">There are no items to show. </div>
</ul>
</div>
</div>
</div>
</div>
</div>
In this case I'm selecting the main div with document.getElementsByClassName("s4-wpcell-plain") from there I need to check for the text "There are no items to show" and hide the corresponding main div.
I have tried to use
document.getElementsByClassName("s4-wpcell-plain").getElementsByTagName("*")
and after this, I will scan on each element on innerText but it is not getting the elements, any help would be appreciated.
I wasn't sure if you wanted .s4-wpcell-plain to disappear or the element that has the text so I wrote code for both objectives and commented out the part that hides .s4-wpcell-plain.
Trying to find a text in DOM is inefficient, you need to use whatever this widget uses and I can assure you it isn't the text it generates. The pattern looks like if there's no items to show the message would be in a div with the className of:
.ms-srch-result-noResults
I don't know how your widget works so I'm assuming that whenever there's no items to show then it creates:
<div class="ms-srch-result-noResults">There are no items to show. </div>
The Demo:
Collects all .ms-srch-result-noResults into a NodeList with document.querySelectorAll()
Makes that NodeList into an array with Array.from()
Runs the array thru forEach() array method.
On each .ms-srch-result-noResults is sets style.display to none
There's also an alternate forEach() method setup to use closest() to find .s4-wpcell-plain and then hide that instead.
Demo
Details commented in Demo
/* Collect all .ms-srch-result-noResults into a NodeList
|| then convert that NodeList into an array
*/
var noResults = Array.from(document.querySelectorAll('.ms-srch-result-noResults'));
/* Run the array thru forEach() method
|| hide each .ms-srch-result-noResults
*/
noResults.forEach(function(v, i) {
v.style.display = 'none';
});
/*//Or do the same thing but hide the .s4-wpcell-plain instead
noResults.forEach(function(v, i) {
var main = v.closest('.s4-wpcell-plain');
main.style.display = 'none';
});
*/
<div class="s4-wpcell-plain">
<div class="ms-chrome">
<div class="ms-chrome-title" id="WPWPQ6_ChromeTitle">
<span title="My Content" id="WPTitleWPQ6" class="js-wp-titleCell">
<h2 style="text-align:justify;" class="ms-wp-titleText">Results (0)</h2>
</span>
</div>
<div wpid="50348231-8acb-4794-af32-d481915fc127" haspers="false" id="WPWPQ6" width="100%" class="ms-WPBody ms-WPBorder noindex ms-wpContentDivSpace " allowdelete="false" style="">
<div style="display: none;">
</div>
<div componentid="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr" id="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr">
<div class="containerForStyle">
<ul class="cbs-List">
<li class="ms-srch-result-noResults">There are no items to show. </li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-results">There are items to show. </li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-results">There are items to show. </li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-noResults">There are no items to show. </li>
</ul>
</div>
</div>
innerText returns text content of all of its nested childrens
try:
var elements = document.getElementsByClassName("s4-wpcell-plain");
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerText.indexOf('There are no items to show') !== -1) {
elements[i].style.display = 'none';
}
}
So here are the things you may follow,
1 - Get the list of elements with document.getElementsByTagName
2 - You can use iterate over, to filter out with the innerText && ClassName for each element
CODE:
// Get the elements list by ClassName
var allEles = documents.getElementsByTagName("*");
var templateString = 'Something';
var wantedClassName = 'ClassName';
// Iterate over all the elements
for(var key in allEles) {
if( (a[key].className === wantedClassName) && (a[key].innerText) === templateString ) {
/* Do Whatever you want with this element => a[key] */
}
}
`

Only show certain <div> if there's a certain element on the page

I'm trying to get the company I'm at a Help Centre set up, using Zendesk.
I've managed to implement a sidenav, but I'm struggling to make it show different anchor links depending on the category of the Help Centre the user is on. Zendesk only allows you to edit the HTML of the category page template, and I'm unable to dynamically load in the links.
Can anyone please advise on how to show DIV_1, only if the page contains <li title="Using ProductName">? I've searched but can't seem to find anything relevant.
From there I'll do the same for the other sections in the same way (e.g. only show DIV_2 if the page contains <li title="Developer Portal".
For reference, I have access to the category's HTML template, the CSS and JS.
Thanks in advance!
<div class="container">
<nav class="sub-nav">
<ol class="breadcrumbs">
<li title="Help Centre">
Help Centre
</li>
<li title="Using ProductName">
Using ProductName
</li>
</ol>
<div id="DIV_1">
<ul id="UL_2">
<li id="LI_1">
Admin and Settings
</li>
<li id="LI_1">
Getting Started
</li>
<li id="LI_1">
Content Types and Sources
</li>
<li id="LI_1">
Content Management
</li>
<li id="LI_1">
Content Publishing
</li>
<li id="LI_1">
Apps
</li>
<li id="LI_1">
Analytics
</li>
<li id="LI_1">
Troubleshooting
</li>
</ul>
</div>
</div>
</div>
You can use the built-in DOM query methods to accomplish this. In this case, you'd want to combine an if condition with the query, something like so:
if (document.querySelector('li[title="Using ProductName"]')) {
// make #DIV_1 visible however you please here
document.querySelector('#DIV_1').display = 'block';
}
If the li with the title Using ProductName does not exist, #DIV_1 will stay invisible; if it does, it will be shown.
You can do a quick for loop check:
var items = document.getElementsByTagName('li');
for (var i = 0; i < items.length; i++) {
if (items[i].title == titleToCheckFor) { showElement(); }
}
You can fill in titleToCheckFor with the title you're looking for ("Using _____") and the showElement function would display the div, or you could just show the div right in the loop.
Using DOM query method querySelector you can search the target element, by default we set all div's hidden, and then we show only the required.
<style>
.module {
display:none;
}
</style>
<script>
// by default we show MODULE A else show module B
var module = "DIV_1";
if (document.querySelector('li[title="Developer Portal"]')) {
module = "DIV_2";
}
// we show the respective DIV
document.querySelector('.' + module).display = 'block';
</script>
<div class="module DIV_1" id="DIV_1">
...
</div>
<div class="module DIV_2" id="DIV_2">
....
</div>
You can achieve this via CSS classes.
SOLUTION 1:
This being the sample HTML:
<div id="Div_1" class="menu-div using-productname">
</div>
<div id="Div_2" class="menu-div help-centre">
</div>
<div id="Div_3" class="menu-div other-tab">
</div>
Now you should setup your css like:
.menu-div {
display: none;
}
So all menu divs are hidden by default when the page loads
Now when you move to some tab suppose "Using ProductName", all you need to do is
var title = "Using ProductName"; //Get the title
var className = title.split(" ").join("-").toLowerCase(); //Convert it to the correct class which matches with your Divs in the menu
document.querySelector(".menu-div").style.display = "none"; //Set all menu divs to hidden
document.querySelector("." + className).style.display = "block"; //Show the desired menu div
SOLUTION 2:
This being the sample HTML:
<div class="parent-div">
<div id="Div_1" class="menu-div">
</div>
<div id="Div_2" class="menu-div">
</div>
<div id="Div_3" class="menu-div">
</div>
Now you should setup your css like:
.parent-div .menu-div {
display: none;
}
.parent-div.using-productname #Div_1 {
display: block;
}
.parent-div.help-centre #Div_2 {
display: block;
}
.parent-div.other-tab #Div_3 {
display: block;
}
Now when you move to some tab suppose "Using ProductName", all you need to do is
var title = "Using ProductName"; //Get the title
var className = title.split(" ").join("-").toLowerCase(); //Convert it to the correct class which you will add to the parent
document.querySelector(".parent-div").className = "parent-div " + className; //Set the parent div class to the className - the css will take care of the rest!
NOTE - Also you should use different ids on your different LIs and A tags.
You can use jQuery in Zendesk Help Centers so
var test = $('.breadcrumbs').children(':contains(amy)')
if(test.length > 0) {
do something here like
$('#LI_1').hide();
}
It's kind of simple brute force, but it works.

Retrieving the values in an un - ordered list and list items

I have html rendered in the format below.
I want to be able to get the values 13,14,15 and store in different variables.
I want to be able to get the value id=9 as well for this row.
I will be updating a table and needs this Id together with the other rows.
Here is the html rendered
<li class="main">
<ul class="sub">
<li id="9">
<div class="innera">13</div>
<div class="innerb">14</div>
<div class="innerc">15</div>
<div class="innerpencil">
<img class="modify" src="/images/icon-pencil" />
</div>
</li>
</ul>
<li>
Here is the jquery I am trying to write
$(document).on("click", "img.modify", function () {
var rowA = $("ul[class='sub'] li[div.class innera]")
var rowB = $("ul[class='sub'] li[div.class innerb]")
var rowB = $("ul[class='sub'] li[div.class innerc]")
var Id of row ?
});
Right now I am not getting anything for the variables? Kindly assist.
I think you just need to review the jQuery (CSS) selectors: https://api.jquery.com/category/selectors/
$("ul[class='sub'] li[div.class innera]") won't match anything.
$('ul.sub>li>div.innera') would work, but maybe you want something a little different. Take a look at the selectors docs, and some trial and error :)
Can't you use a foreach loop on the li tag?
Like this?
$(document).on("click", "img.modify", function () {
var id = $('.sub > li').first().attr("id");
console.log(id);
$('#'+id+' > .divValue').each(function () {
var variableName = $(this).text();
console.log(variableName);
});
});
}
I would add an class to the elements value you want.
Like this:
<li class="main">
<ul class="sub">
<li id="9">
<div class="innera divValue">13</div>
<div class="innerb divValue">14</div>
<div class="innerc divValue">15</div>
<div class="innerpencil">
<img class="modify" src="/images/icon-pencil" />
</div>
</li>
</ul>
<li>

Weird behavior with .parents() and .closest() when trying to return parent <ul> element id in jQuery

So I've got 2 <ul> containers each with id's. Inside of them are a list of <li> elements.
The first <ul> is <ul id="coaches-list">. The second is <ul id="players-list">.
There are tags within each <li> that have an id called close (which is a link that I'm using as my selector), which will delete each <li> node once clicked. I'm trying to target each <ul> container to see where it is coming from.
My HTML is:
<!-- coaches box -->
<div class="box">
<div class="heading">
<h3 id="coaches-heading">Coaches</h3>
<a id="coaches" class="filter-align-right">clear all</a>
</div>
<ul id="coaches-list" class="list">
<li><span>Hue Jackson<a class="close"></a></span></li>
<li class="red"><span>Steve Mariuchi<a class="close"></a> </span></li>
</ul>
</div>
<!-- players box -->
<div class="box">
<div class="heading">
<h3 id="players-heading">Players</h3>
<a id="players" class="filter-align-right">clear all</a>
</div>
<ul id="players-list" class="list">
<li><span>Steve Young<a class="close"></a></span></li>
<li><span>Gary Plummer<a class="close"></a></span></li>
<li><span>Jerry Rice<a class="close"></a></span></li>
</ul>
</div>
My remove tag function in jQuery is:
function removeSingleTag() {
$(".close").click(function() {
var $currentId = $(".close").closest("ul").attr("id");
alert($currentId);
// find the closest li element and remove it
$(this).closest("li").fadeOut("normal", function() {
$(this).remove();
return;
});
});
}
Whenever I click on each specific tag, it's removing the proper one I clicked on, although when I'm alerting $currentId, if I have:
var $currentId = $(".close").closest("ul").attr("id");
It alerts 'coaches-list' when I'm clicking on a close selector in both <ul id="coaches-list" class="list"></ul> and <ul id="players-list" class="list"></ul>
If I change that to:
var $currentId = $(".close").parents("ul").attr("id");
It has the same behavior as above, but alerts 'players-list', instead.
So when using closest(), it's returning the very first <ul> id, but when using parents(), it's returning the very last <ul> id.
Anyone know what is going on with this whacky behavior?
It's expected behavior.
You should use:
var $currentId = $(this).closest("ul").attr("id");
$(this) points at the clicked .close.
$(".close") points at the first one found.
It's because you run that selector from click handler you should use this instead:
var $currentId = $(this).closest("ul").attr("id");
Try using this function to get the parent:
var $currentId = $(this).parents().first();
I've never used the .closest() function but according to jQuery what you have specified should work. Either way, try that out and tell me how it goes.
You also need to make it so that it selects the current element by using $(this)

Categories