I have a doropdown menu that should work when used/in view.
I would like to have a function that works only when the dropdown is used.
So Ideally navigation with dropdown and nav without.
the following fuctions will be added if dropdown exists.
The Click event doesn't seems to fire at all.
My assumption is that
const navLinks = dropDownBlock[i].querySelectorAll(".nav-items > li");
is't correct! or is not fired
I wan't to use as much as possible es6, and I wan't to make sure everything is reusable and works only when in view.
Demo here:
const dropDownBlock = document.querySelectorAll(".has-nav-panel");
let result = true;
for (let i = 0; i < dropDownBlock.length; i++) {
if (dropDownBlock[i] <= 0) {
result = false;
break;
}
const navLinks = dropDownBlock[i].querySelectorAll(".nav-items > li");
const dropdownCta = dropDownBlock[i].querySelector(".nav-panel-cta");
const dropdownPanel = dropDownBlock[i].querySelector(".nav-panel");
//-------------------------------------
//Doesn it have dropdown
//-------------------------------------
Array.prototype.forEach.call(navLinks, function (el, i) {
let currentNavLink = navLinks[i];
currentNavLink.addEventListener("click", function () {
console.log('click');
megaNavClickAndTouchHandler(navLinks, currentNavLink);
});
megaNavResetOnBreakPoint(navLinks, currentNavLink, mediaQuery);
});
function megaNavResetOnBreakPoint(elements, currentElement, mqNav) {
if (matchMedia) {
let navigationBar = currentElement.closest(".header");
let navigationItems = currentElement.closest(".nav-wrap");
mqNav.addListener(function () {
if (mqNav.matches) {
document.querySelectorAll("body")[0].classList.remove("is-no-scroll");
navigationBar.classList.remove("is-active");
navigationItems.classList.remove("is-active");
//navigationBar.querySelectorAll(".burger")[0].classList.remove("is-active");
megaNavClosePanels(elements);
} else {
megaNavClosePanels(elements);
}
});
}
}
function megaNavClickAndTouchHandler(elements, currentElement) {
let isSubNavLink = currentElement.classList.contains("has-nav-panel");
let isSubNavLinkActive = currentElement.classList.contains("is-active");
let navBarContainer = currentElement.closest(".header");
if (!isSubNavLink) {
window.location = currentElement.firstElementChild.getAttribute("href");
} else if (isSubNavLink && !isSubNavLinkActive) {
megaNavClosePanels(elements);
currentElement.classList.add("is-active");
dropdownCta.setAttribute("aria-expanded", true);
dropdownPanel.ariaHidden = "false";
} else {
megaNavClosePanels(elements);
}
}
function megaNavClosePanels(elements) {
for (let j = 0; j < elements.length; j++) {
if (elements[j].classList.contains("has-nav-panel")) {
elements[j].classList.remove("is-active");
dropdownCta.setAttribute("aria-expanded", false);
dropdownPanel.ariaHidden = "true";
}
}
}
//-------------------------------------
// end dropdown functions
//-------------------------------------
}
<header role="banner" class="header">
<div class="container-fluid g-0 bg-black">
<nav id="main-navigation" class="navigation">
<div class="container has-px-0 has-px-md-4">
<div class="nav-wrap" aria-label="main navigation">
<ul class="nav-items list-unstyled">
<li class="is-d-lg-flex active"><a class="nav-link" href="#">nav item</a></li>
<li class="is-d-lg-flex "><a class="nav-link" href="#">nav item</a></li>
<li class="is-d-lg-flex"><a class="nav-link" href="#">nav item</a></li>
<li class="has-nav-panel is-d-lg-flex is-align-center">
<button role="button" aria-expanded="false" class="nav-panel-cta has-pb-3 has-pt-3 has-px-4 has-p-lg-0"><span class="has-mr-2">Dropdown</span></button>
<div class="nav-panel" aria-hidden="true">
<div class="row no-gutters">
<div class="col-md-12">
<ul class="list-unstyled has-pl-3 has-pl-lg-0">
<li>nav item</li>
<li>nav item</li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</nav>
</div>
</header>
your html structure
<ul class="nav-items list-unstyled">
<li class="has-nav-panel is-d-lg-flex is-align-center">
but your script select the child then the parent
const dropDownBlock = document.querySelectorAll(".has-nav-panel");
.....
const navLinks = dropDownBlock[i].querySelectorAll(".nav-items > li");
I think you don't need to loop and here fix, replace
const dropDownBlock = document.querySelectorAll(".has-nav-panel");
let result = true;
for (let i = 0; i < dropDownBlock.length; i++) {
if (dropDownBlock[i] <= 0) {
result = false;
break;
}
const navLinks = dropDownBlock[i].querySelectorAll(".nav-items > li");
const dropdownCta = dropDownBlock[i].querySelector(".nav-panel-cta");
const dropdownPanel = dropDownBlock[i].querySelector(".nav-panel");
with
let result = true;
dropDown();
function dropDown() {
let dropDownBlock = document.querySelectorAll(".nav-items")
const navLinks = dropDownBlock[0].querySelectorAll(".has-nav-panel");
if (navLinks .length <= 0) {
result = false;
return;
}
const dropdownCta = dropDownBlock[0].querySelector(".nav-panel-cta");
const dropdownPanel = dropDownBlock[0].querySelector(".nav-panel");
Related
I have the following landing page
When the page loads I want the left page to be active as shown unfortunately for now when the page loads both the left menu and the right menu are active.If I click on the right menu it does not work.
Hosted site
https://leskoy.bonusgigs.com/
window.onload = function() {
document.getElementById('scarves').className = '';
document.getElementsByClassName('rightlinks')[0].className = 'active'
};
function openLeftMenu(menu) {
if (menu === 'scarves') {
document.getElementById('scarves').className = '';
document.getElementById('stockists').className = 'content';
document.getElementById('scarvesBtn').className = 'active';
document.getElementById('stockistsBtn').className = '';
}
if (menu === 'stockists') {
document.getElementById('stockists').className = '';
document.getElementById('scarves').className = 'content';
document.getElementById('stockistsBtn').className = 'active';
document.getElementById('scarvesBtn').className = '';
}
}
window.onload = function() {
document.getElementById('why').className = '';
document.getElementsByClassName('tablinks')[0].className = 'active'
};
function openMenu(menu) {
if (menu === 'why') {
document.getElementById('why').className = '';
document.getElementById('process').className = 'content';
document.getElementById('whyBtn').className = 'active';
document.getElementById('processBtn').className = '';
}
if (menu === 'process') {
document.getElementById('process').className = '';
document.getElementById('why').className = 'content';
document.getElementById('processBtn').className = 'active';
document.getElementById('whyBtn').className = '';
}
if (menu === 'connect') {
document.getElementById('connect').className = '';
document.getElementById('process').className = 'content';
document.getElementById('connectBtn').className = 'active';
document.getElementById('whyBtn').className = '';
}
if (menu === 'faq') {
document.getElementById('faq').className = '';
document.getElementById('process').className = 'content';
document.getElementById('faqBtn').className = 'active';
document.getElementById('whyBtn').className = '';
}
}
<div class="leftpane">
<nav style="margin-top: 30px;" id="menu">
<a class="tablinks " onclick="openMenu('why')" id="whyBtn">
<h2 class="cooler">why<span class="arrow"></span></h2>
</a>
<a class="tablinks" onclick="openMenu('process')" id="processBtn">
<h2 class="cooler">process<span class="arrow"></span></h2>
</a>
</nav>
</div>
<div class="middlepane">
<div class="content" id="why"></div>
<div class="content" id="process"></div>
<div class="content" id="scarves"></div>
<div class="content" id="stockists"></div>
</div>
<div class="rightpane">
<div style="margin-top: 60%;">
<nov id="menu">
<a class="rightlinks" onclick="openLeftMenu('scarves')" id="scarvesBtn">
<h2 class="drool">scarves<span class="arrow"></span></h2>
</a>
<a class="rightlinks" onclick="openLeftMenu('stockists')" id="stockistsBtn">
<h2 class="drool">stockists<span class="arrow"></span></h2>
</a>
</nov>
</div>
</div>
Here is how to do more than one thing in the onload.
Also note how I cache the elements and address the first of the class using querySelector
window.addEventListener("DOMContentLoaded", function() {
const scarves = document.getElementById('scarves');
const scarvesBtn = document.getElementById('scarvesBtn');
const stockists = document.getElementById('stockists');
const stockistsBtn = document.getElementById('stockistsBtn');
const why = document.getElementById('why');
const rightlinks = document.querySelector('.rightlinks');
const tablinks = document.querySelector('.tablinks')
const openLeftMenu = menu => {
scarves.classList.toggle("content", menu === 'stockists')
scarvesBtn.classList.toggle("active", menu === 'scarves')
stockists.classList.toggle("content", menu === 'scarves')
.classList.toggle("active", menu === 'stockists')
}
// init
scarves.classList.remove("active");
why.classList.remove("active");
rightlinks.classList.add("active");
tablinks.classList.add("active");
});
I have an list of items fetched as below:
<ul id="products" class="abcd" style="display: block;">
<li class="productslist">item1</li>
<li class="productslist">item2</li>
<li class="productslist">item3</li>
<li class="productslist">item4</li>
<li class="productslist">item5</li>
<li class="productslist">item6</li>
<li class="productslist">item7</li>
<li class="productslist">item8</li>
<li class="productslist">item9</li>
<li class="productslist">item10</li>
<li class="productslist">item11</li>
<li class="productslist">item12</li>
<li class="productslist">item13</li>
</ul>
Now I need to display 3 items per page after applying pagination. Kindly help me with Javascript.
This question is quite broad, however considering that this solution is not a great solution for longer lists, the code below will help you understand what to do.
const list = [...document.querySelectorAll('.productslist')];
let count = 0;
const items_per_page = 3;
const pagination_numbers_container = document.querySelector('.pagination-numbers');
const paginate = (p) => {
hideAll();
if(p === 'next') count += items_per_page;
else if(p === 'previous') count -= items_per_page;
else count = p;
if(count < 0 ) count = 0;
else if(count >= (list.length - items_per_page)) count = (list.length - items_per_page) + ((list.length+1) % items_per_page);
for(let i = count; i < (count+items_per_page); i++) {
if(list[i]) list[i].style.display = 'block';
}
}
const paginateNumberClickHandler = (evt) => {
const page = parseInt(evt.currentTarget.getAttribute('data-page'));
paginate(page * items_per_page)
}
const createPaginationNumbers = () => {
const total_pages_rest = list.length % items_per_page;
const total_pages = (list.length / items_per_page);
const pagination_numbers = [];
pagination_numbers_container.innerHTML = '';
for(let i = 0; i < total_pages; i++) {
pagination_numbers_container.innerHTML += `<button data-page="${i}" class="pag">${i+1}</button>`;
}
[...document.querySelectorAll('.pag')].forEach( (p) => p.addEventListener('click', paginateNumberClickHandler ));
}
const hideAll = () => list.forEach( (l) => l.style.display = 'none');
const next = document.querySelector('.next');
const previous = document.querySelector('.previous');
next.addEventListener('click', (e) => paginate("next"));
previous.addEventListener('click', (e) => paginate("previous"));
paginate(0);
createPaginationNumbers();
<ul id="products" class="abcd" style="display: block;">
<li class="productslist">item1</li>
<li class="productslist">item2</li>
<li class="productslist">item3</li>
<li class="productslist">item4</li>
<li class="productslist">item5</li>
<li class="productslist">item6</li>
<li class="productslist">item7</li>
<li class="productslist">item8</li>
<li class="productslist">item9</li>
<li class="productslist">item10</li>
<li class="productslist">item11</li>
<li class="productslist">item12</li>
<li class="productslist">item13</li>
</ul>
<div class="pagination-numbers">
</div>
<button class="previous">
Previous
</button>
<button class="next">
Next
</button>
i am new to angular 4 i want to develop a shopping cart functionality with some different render functionality in html. i can't able to find any solution till now.
already tried with jquery append function but it wont work in edit functionality in feature.
Below gif image shows my requirement
if i click any catagory it will directly append to top of the list with selected catagory.
Then if i click another catagory for same person it will apply after i click apply button
component.html
<ul class="selected-friends" id="appendtext">
</ul>
<ul class="list-friends" id="listFriends">
<div *ngFor="let data of result" [attr.id]="'FriendList' + data.id" #item>
<li class="checkedCatagory">
<div class="sf-left">
<h3>{{data.fullName}}</h3>
<span id="appendCatagoryList"></span>
</div>
<div class="sf-right">
<div class="edit-con sf-icon" data-toggle="collapse" [attr.data-target]="'#list' + data.id">
<i class="fa fa-list" aria-hidden="true"></i>
</div>
<div class="del-con sf-icon" [attr.id]="'#list' + data.id" (click)="delete(data.id)">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</div>
</div>
</li>
<!-- Main List started -->
<li class="mainlistname" data-toggle="collapse" [attr.data-target]="'#list' + data.id">
<label class="catagory_list" [attr.for]="data.id"><input type="checkbox" [attr.id]="data.id" [attr.value]="data.id">
{{data.fullName}}</label>
</li>
<ul class="sub-friends-list collapse" [attr.id]="'list'+data.id">
<p class="mainlistname">Assign Category to this participant</p>
<p class="checkedCatagory">Edit or Assign another category to this participant</p>
<li *ngFor="let catagoryDetail of catagoryList">
<label class="catagory_list">
<input type="checkbox" class="catagory_list_checkbox" (click)="resize(data.id, catagoryDetail.id);addToCart(data.id,catagoryDetail.id,data.fullName,catagoryDetail.title)" [value]="catagoryDetail.id" [attr.id]="'catagoryId'+catagoryDetail.id">
<span [attr.id]="'catagoryName'+catagoryDetail.id">{{catagoryDetail.title}}</span>
<span class="pull-right fnt-16">AED</span>
<span class="pull-right fnt-16" id="'fee'+catagoryDetail.id">{{catagoryDetail.fee}}</span>
<!-- <p>18-99 Years Male/Female</p> -->
<p *ngIf="catagoryDetail.gender === 1">{{catagoryDetail.ageMinMale}}-{{catagoryDetail.ageMaxMale}} Years Male</p>
<p *ngIf="catagoryDetail.gender === 2">{{catagoryDetail.ageMinFemale}}-{{catagoryDetail.ageMaxFemale}} Years Female</p>
<p *ngIf="catagoryDetail.gender === 3">{{catagoryDetail.ageMinFemale}}-{{catagoryDetail.ageMaxFemale}} Years Male/Female</p>
</label>
<span class="checkedCatagoryhidden">
<p *ngFor="let catagorySelected of catagoryList" [attr.id]="'catagorySelected'+catagorySelected.id">
{{catagorySelected.title}} :
<span *ngIf="catagorySelected.gender === 1">{{catagorySelected.ageMinMale}}-{{catagorySelected.ageMaxMale}} Years Male</span>
<span *ngIf="catagorySelected.gender === 2">{{catagorySelected.ageMinFemale}}-{{catagorySelected.ageMaxFemale}} Years Female</span>
<span *ngIf="catagorySelected.gender === 3">{{catagorySelected.ageMinFemale}}-{{catagorySelected.ageMaxFemale}} Years Male/Female</span>
<span class="pull-right fnt-16">AED {{catagorySelected.fee}}</span>
</p>
</span>
</li>
<li class="checkedCatagory" class="apply checkedCatagory quantity">
<span class="quantity_catagory">Qty: <span [attr.id]="'sectionquantity'+data.id"></span></span>
<span class="catagory_amount">Total: AED <span [attr.id]="'sectionprize'+data.id"></span></span>
<button class="btnapplyqnty">Apply</button>
</li>
</ul>
</div>
</ul>
component.ts
addToCart(id, catagoryId, fullName, catTitle){
var currentUserObj = <any>{};
var self = this;
var sum;
currentUserObj[id] = {};
currentUserObj[id].participantid = id;
currentUserObj[id].participantName = fullName;
// console.log(fullName)
this.cart.cartItems[id] = {};
if(jQuery("#catagoryId"+catagoryId).is(":checked")) {
currentUserObj[id]['categoryInfo'] = [];
currentUserObj[id]['categoryName'] = [];
currentUserObj[id]['categoryFee'] = [];
var totalPrize = 0;
jQuery('#list'+id).find('.catagory_list input:checked').each(function(){
var currentCategoryId = jQuery(this).val();
var currentCatagoryName = jQuery('.catagory_list input:checked+#catagoryName'+catagoryId).text();
currentUserObj[id]['categoryInfo'].push(currentCategoryId);
currentUserObj[id]['categoryName'].push(jQuery(this).next('').text());
currentUserObj[id]['categoryFee'].push(Number(jQuery(this).next().next().next().text()));
});
sum = currentUserObj[id]['categoryFee'].reduce(this.add, 0);
currentUserObj[id].quantity = currentUserObj[id]['categoryInfo'].length;
this.cart.cartItems[id] = currentUserObj[id];
currentUserObj[id].participantTotalPrize = sum;
console.log('sum',sum)
this.saveCart();
} else {
var currentCategoryId;
currentUserObj[id]['categoryInfo'] = [];
currentUserObj[id]['categoryName'] = [];
currentUserObj[id]['categoryFee'] = [];
jQuery('#list'+id).find('.catagory_list input:checked').each(function(){
currentCategoryId = jQuery(this).val();
currentUserObj[id]['categoryName'].push(jQuery(this).next().text());
currentUserObj[id]['categoryInfo'].push(currentCategoryId);
currentUserObj[id]['categoryFee'].push(Number(jQuery(this).next().next().next().text()));
});
sum = currentUserObj[id]['categoryFee'].reduce(this.add, 0);
currentUserObj[id].participantTotalPrize = sum;
currentUserObj[id].quantity = currentUserObj[id]['categoryInfo'].length;
this.cart.cartItems[id] = currentUserObj[id];
if(currentUserObj[id].quantity === 0) {
console.log("completed delete", this.cart.cartItems[id])
delete self.cart.cartItems[id];
}
this.saveCart();
}
}
add(a, b) {
return a + b;
}
saveCart() {
if (window.localStorage) {
console.log("tfgb",this.cart);
sessionStorage.setItem('cart',JSON.stringify(this.cart));
}
}
resize(id, catagoryId) {
let navObj = this;
var appendSelectedCatagory = document.getElementById('appendtext');
jQuery(appendSelectedCatagory).prepend(jQuery('#FriendList'+id));
if(jQuery("#catagoryId"+catagoryId).is(":checked")) {
this.displaySelectedList(id, catagoryId);
var totalPrize = 0;
navObj.quantity = 0;
jQuery('#list'+id).find('.catagory_list input:checked').each(function(){
var currentCategoryId = jQuery(this).val();
navObj.eventRegistrationService.getEventCatagoriesList(navObj.eventId)
.subscribe((res)=>{
for(let i in res.data){
var catList = res.data[i];
if(catList.id == currentCategoryId){
totalPrize += catList.fee
navObj.quantity += 1;
}
}
jQuery('#sectionprize'+id).html(totalPrize);
jQuery('#sectionquantity'+id).html(navObj.quantity);
})
})
} else {
this.eventChecked -= 1;
var totalPrize = 0;
navObj.quantity = 0;
jQuery('#list'+id).find('.catagory_list input:checked').each(function(){
var currentCategoryId = jQuery(this).val();
navObj.eventRegistrationService.getEventCatagoriesList(navObj.eventId)
.subscribe((res)=>{
for(let i in res.data){
var catList = res.data[i];
if(catList.id == currentCategoryId){
totalPrize += catList.fee
navObj.quantity += 1;
}
}
jQuery('#sectionprize'+id).html(totalPrize)
jQuery('#sectionquantity'+id).html(navObj.quantity)
})
})
this.checkedCatagory.pop(catagoryId);
let checkBoxList = '#appendtext #list'+id;
if(jQuery(checkBoxList+' :checkbox:checked').length == 0){
jQuery('#listFriends').append(jQuery('#FriendList'+id));
jQuery("#FriendList"+id+ " input[type='checkbox']").prop("checked", false);
sessionStorage.removeItem(id);
}
}
}
displaySelectedList(id, catagoryId){
this.eventChecked += 1;
let getselectList = sessionStorage.getItem('selectedFriends');
jQuery('#appendCatagoryList').append(jQuery('#catagorySelected'+catagoryId))
}
delete(id){
jQuery('#listFriends').append(jQuery('#FriendList'+id));
jQuery("#FriendList"+id+ " input[type='checkbox']").prop("checked", false);
console.log('asdasdsa',id);
//this.quantity = 0;
sessionStorage.removeItem(id);
}
I'm sorry if this is a duplicate questions, but I've spent over 8hrs trying to figure out how to implement this, but it seems I haven't succeded so far.
I've got a photo gallery, each foto contains multiple tags. If multiple tags are active, it needs to show only items that include all the selected tags.
<ul class="tags-list container">
<li class="tag toate">Toate</li>
<li class="tag">Tag 3</li>
<li class="tag">Tag 2</li>
<li class="tag">Tag 4</li>
</ul>
<div class="grid">
<div class="grid-sizer"></div>
<div id="grid-item-0" class="grid-item " data-tag=" tag-1 tag-3 tag-7"></div>
<div id="grid-item-1" class="grid-item " data-tag=" tag-2 tag-1"></div>
<div id="grid-item-2" class="grid-item big" data-tag=" tag-3"></div>
<div id="grid-item-3" class="grid-item " data-tag=" tag-4 tag-2 tag-1"></div>
</div>
and JS:
function Gallery() {
this.tag = $('.tags-list .tag');
this.gridItem = $('.grid .grid-item');
this.activeTags = ['toate'];
this.itemsList = [];
this.activeItems = [];
this.init();
}
Gallery.prototype.init = function () {
this.masonry();
this.itemsListGen();
};
Gallery.prototype.itemsListGen = function () {
var _this = this;
$(this.gridItem).each(function () {
var tags = $(this).attr('data-tag');
tags = tags.trim();
// creates an array of objects with every item's id and tags
_this.itemsList.push({
'id': $(this).attr('id'),
'tags': tags.split(' ')
});
});
};
Gallery.prototype.masonry = function () {
$('.grid').masonry({
// options
columnWidth: '.grid-sizer',
itemSelector: '.grid-item',
percentPosition: true
});
};
Gallery.prototype.tagClick = function (e) {
e.preventDefault();
// currentTag has the clicked tag
var currentTag = $(e.currentTarget).attr('data-tag-slug');
$(e.currentTarget).toggleClass('active');
if ($(e.currentTarget).attr('data-tag-slug') === 'toate') {
this.toateClick();
} else {
// refresh current filters
this.refreshTags(currentTag);
// return validated items based on filters
this.returnValidItems();
// refresh the layout with the current items
this.refreshMasonry();
}
};
Gallery.prototype.refreshTags = function (e) {
// checks if the current tag is already active
// if it's active, it removes it and checks if there is any other active tag or should trigger 'toate'
// if it's not active, it adds it to the activeTags and removes 'toate'
if (this.activeTags.includes(e)) {
this.activeTags.splice(this.activeTags.indexOf(e), 1);
if (this.activeTags.length < 1) {
this.showAll();
}
} else {
this.activeTags.push(e);
if (this.activeTags.includes('toate')) {
this.removeToate();
}
}
};
Gallery.prototype.returnValidItems = function () {
for (var i = 0; i < this.itemsList.length; i++) {
var itemTags = this.itemsList[i].tags;
for (var j = 0; j < this.activeTags.length; j++) {
if (itemTags.includes(this.activeTags[j])) {
this.activeItems.push(this.itemsList[i].id);
} else {
this.activeItems.splice(this.activeItems.indexOf(this.itemsList[i].id), 1);
break;
}
}
}
};
Gallery.prototype.refreshMasonry = function () {
$('.grid-item').hide();
for (var i = 0; i < this.activeItems.length; i++) {
$('#' + this.activeItems[i]).show();
}
$('.grid').masonry();
};
Gallery.prototype.showAll = function () {
console.log('show all');
this.activeTags = ['toate'];
this.activeItems = [];
$('.grid-item').show();
$('.tags-list').find('.toate a').addClass('active');
$('.grid').masonry();
};
Gallery.prototype.toateClick = function (e) {
console.log('toate click');
$('.tags-list').find('.active').removeClass('active');
$('.tags-list .toate a').addClass('active');
this.showAll();
};
Gallery.prototype.removeToate = function () {
$('.tags-list li.toate > a').removeClass('active');
this.activeTags.splice(this.activeTags.indexOf('toate'), 1);
};
I am not capable of doing it. Please help? :)
Besides of helping me with the problem, any feedback regarding my code is welcomed.
I need to toggle the text in the span element from [+] to [-] when the button is clicked with JavaScript. How can I achieve this with my current toggle function?
HTML
...
<ul>
...
<li>
<ul>
<h3>header</h3>
url-link
<p>description</p>
<ul>
<div class="department" style="display: none;">
<ul class="placemark"> ... </ul>
<ul class="contact"> ... </ul>
</div>
<button class="department-collapse" onclick="toggle(this)">
<span>[+]</span> Contact Information
</button>
</li>
...
<ul>
...
JavaScript
function toggle(self) {
var n = self.parentNode.childNodes;
for(var i = 0; i < n.length; i++) {
if (n[i].className == 'department') {
n[i].style.display = n[i].style.display == '' ? 'none' : '';
}
}
}
Inside your function, verify your span (JS code):
function toggle(self) {
var n = self.parentNode.childNodes;
for(var i = 0; i < n.length; i++) {
if (n[i].className == 'department') {
n[i].style.display = n[i].style.display == '' ? 'none' : '';
}
}
var mySpan = self.childNodes[0];
mySpan.innerHTML = mySpan.innerHTML == '[+]' ? '[-]' : '[+]';
}