There a 'load more/load less' function running on this page which I'm attempting to debug. https://maes-mynan.cogitoprojectx.com/holiday-homes/the-llewellyn-lodge-lodge/
You can see it the section with the heading "More About The Llewellyn Lodge"
The text is displayed via an Advanced Custom Fields WYSIWYG field [WordPress].
I've been playing around with numbers in lines i.e. .length>4 with no effect.
As far as I can see, the code is set to truncate the text after the fourth paragraph and on-click show the full text. However, instead of just truncating the text, it seems to remove the fourth paragraph entirely.
In essence, it displays paragraphs 1 - 3, [misses 4] and then displays paragraph 5 onwards.
I've been changing the value of the number in line e.g. .length>4 with no effect.
Any help, to stop the paragraph disappearing entirely will be gratefully appreciated.
jQuery(document).ready(function() {
jQuery('.read-more2').each(function() {
if (jQuery(this).children('p').length > 4) {
jQuery(this).children('p:lt(3)').show();
jQuery(this).append('<button class="loadMore btn btn-primary">Show More</button>');
}
});
jQuery('.read-more2').on("click", '.loadMore', function() {
jQuery(this).parent('.read-more2').children('p:gt(3)').show(); // use gt instead of lt
jQuery(this).removeClass('loadMore').addClass('loadLess').text('Show Less');
});
jQuery('.read-more2').on("click", '.loadLess', function() {
jQuery(this).parent('.read-more2').children('p:gt(3)').hide(); // use gt instead of lt
jQuery(this).removeClass('loadLess').addClass('loadMore').text('Show More');
});
});
Assuming the reason for SHOWING initially is that all p's are hidden, we need to hide the gt(2) when we toggle.
the code could be shortened by having the button use .toggle(this.textContent==='Show More') instead of having two event handlers and two class names
$(document).ready(function() {
$('.read-more2').each(function() {
if ($(this).children('p').length > 4) {
$(this).children('p:lt(3)').show(); // because they were hidden
$(this).append('<button class="loadMore btn btn-primary">Show More</button>');
}
});
$('.read-more2').on("click", '.loadMore', function() {
$(this).parent('.read-more2').children('p').show(); // use p to show all
$(this).removeClass('loadMore').addClass('loadLess').text('Show Less');
});
$('.read-more2').on("click", '.loadLess', function() {
$(this).parent('.read-more2').children('p:gt(2)').hide(); // use gt 2 instead
$(this).removeClass('loadLess').addClass('loadMore').text('Show More');
});
});
.read-more2 > p { display:none }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="read-more2">
<p>p1</p>
<p>p2</p>
<p>p3</p>
<p>p4</p>
<p>p5</p>
<p>p6</p>
</div>
<div class="read-more2">
<p>p1</p>
<p>p2</p>
<p>p3</p>
<p>p4</p>
<p>p5</p>
<p>p6</p>
</div>
$(document).ready(function() {
$('.read-more-spec').each(function() {
if ($(this).find('ul li').length > 4) {
$(this).find('ul li:lt(3)').show(); // because they were hidden
$(this).append('<button class="loadMore btn btn-primary">Show More</button>');
}
});
$('.read-more-spec').on("click", '.loadMore', function() {
$(this).parent('.read-more-spec').find('ul li').show(); // use p to show all
$(this).removeClass('loadMore').addClass('loadLess').text('Show Less');
});
$('.read-more-spec').on("click", '.loadLess', function() {
$(this).parent('.read-more-spec').find('ul li:gt(2)').hide(); // use gt 2 instead
$(this).removeClass('loadLess').addClass('loadMore').text('Show More');
});
});
.read-more-spec ul li { display:none }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-6 read-more-spec black">
<h3>LODGE FEATURES</h3>
<div>
<ul>
<li>Vaulted ceiling to lounge, kitchen and diner</li>
<li>Two sets of French doors to the front elevation</li>
<li>Overhanging eaves with discreet lighting to the external front elevation</li>
<li>Colour coordinated curtains, blinds and carpets</li>
<li>Fully fitted country style kitchen with four burner gas hob, built under oven and integrated dishwasher and fridge/freezer</li>
<li>Centre island/breakfast bar with two high backed chairs</li>
<li>Utility cupboard with under counter washing machine, condensing dryer, hooks, shelves and boot drying area under boiler</li>
<li>Solid wood dining table top with four painted white chairs</li>
<li>One large comfortable sofa and two armchairs – both in a classical design</li>
<li>Coffee table and lamp table also feature in the lounge area</li>
<li>Fireplace mantel and, electric log burner style fire</li>
<li>5ft King sized bed in master bedroom with gas lift under-bed storage</li>
<li>Freestanding bedroom furniture which includes large wardrobe, mirror, dressing table, dressing stool and bedside tables</li>
<li>Ensuite bathroom with tiled corner shower and heated towel rail</li>
<li>Bath in main bathroom with overhead shower and heated towel rail</li>
<li>Wall mirrors in both bathrooms</li>
<li>TV points in lounge and master bedroom</li>
<li>Energy efficient A Rated boiler with radiators and central heating throughout</li>
<li>Built to British Standard 3632 – residential specification</li>
<li>Timber frame structure</li>
<li>10 year structural warranty</li>
<li>Horizontal Sierra Canexel Cladding to the exterior for easy maintenance</li>
<li>Anthracite grey UPVC double glazed doors and windows</li>
<li>Large decking in complementing grey composite board and handrail with two lockable gates (ideal for dog owners) to front and side. Steps down into the side garden area</li>
<!-- <button class="loadMore btn btn-primary">Show More</button> -->
</ul>
</div>
Related
I'm working on making a word search for whatever word is entered into the input box. I'm trying to create a div element that would show a string consisting of all words found at least once in each paragraph, for successive searches, below the input box. I also want to create a span element that maintains a count of the words that are found in all paragraphs for all searches. I'm just pretty lost with all of it and unsure where to even start.
/*window.onload = function()
{
document.getElementById("searchbutton").onclick = searchClick;
};
I needed to bring this one line lower to work on commenting out */
but1 = document.querySelector("#searchbutton");
but1.addEventListener('click', searchClick);
// Called when the Search button is clicked.
// Looks for paragraphs matching a search string and highlights them.
function searchClick() {
var searchPhrase = document.getElementById("searchtext").value;
/*var main = document.querySelector("#main");*/
var mainParas = document.getElementsByTagName("p");
for (var i = 0; i < mainParas.length; i++) {
if (mainParas[i].textContent.indexOf(searchPhrase) >= 0) { mainParas[i].className = "highlighted"; } // highlight
else {
mainParas[i].className = null; // un-highlight
}
}
}
<body>
<div id="main">
<p>The Phoenix Suns are a professional basketball team based in
Phoenix, Arizona. They are members of the ...</p>
<p>The Suns have been generally successful since they began play as an
expansion team in 1968. In forty years of play they have posted ...</p>
<p>On January 22, 1968, the NBA awarded expansion franchises to an
ownership group from Phoenix and one from Milwaukee. ...</p>
<ul>
<li>Richard L. Bloch, investment broker/real estate developer...</li>
<li>Karl Eller, outdoor advertising company owner and former...</li>
<li>Donald Pitt, Tucson-based attorney;</li>
<li>Don Diamond, Tucson-based real estate investor.</li>
</ul>
</div>
<p>Page by Marty Stepp. <br />
Some (all) information taken from Wikipedia.</p>
<hr />
<div>
Search for text:
<input id="searchtext" type="text" />
<button id="searchbutton">Search</button>
</div>
</body>
Your problem seems to be that document.querySelector("#searchbutton") returns null so that but1.addEventListener('click', searchClick); fails. Instead of searching for the reason I skipped adding a listener and directly attached the onclick function with
<button id="searchbutton" onclick="searchClick()">Search</button>
in the html. This worked, but I had to define a css rule for highlighting that wasn't posted in your code.
Edit 01.05.2021 - I didn't cover counting the matches, so here it is completely:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style>
p.highlighted { background-color: Yellow; }
</style>
</head>
<body>
<body>
<script type="text/javascript">
function searchClick() {
var count = 0;
var searchPhrase = document.getElementById("searchtext").value;
var mainParas = document.getElementsByTagName("p");
for (var i = 0; i < mainParas.length; i++) {
if (mainParas[i].textContent.indexOf(searchPhrase) >= 0) {
mainParas[i].className = "highlighted"; // highlight
count += mainParas[i].textContent.split(searchPhrase).length - 1;
} else {
mainParas[i].className = null; // un-highlight
}
}
document.getElementById("found").textContent = count + " matches found";
}
</script>
<div id="main">
<p>The Phoenix Suns are a professional basketball team based in Phoenix, Arizona. They are members of the ...</p>
<p>The Suns have been generally successful since they began play as an expansion team in 1968. In forty years of play they have posted ...</p>
<p>On January 22, 1968, the NBA awarded expansion franchises to an ownership group from Phoenix and one from Milwaukee. ...</p>
<ul>
<li>Richard L. Bloch, investment broker/real estate developer...</li>
<li>Karl Eller, outdoor advertising company owner and former...</li>
<li>Donald Pitt, Tucson-based attorney;</li>
<li>Don Diamond, Tucson-based real estate investor.</li>
</ul>
</div>
<p>Page by Marty Stepp. <br />
Some (all) information taken from Wikipedia.</p>
<hr />
<div>Search for text:
<input id="searchtext" type="text" />
<button id="searchbutton" onclick="searchClick()">Search</button>
<span id="found"></span>
</div>
</body>
</html>
The counting happens with the loop checking the paragraphs. Before, a variable count is defined, inside it gets increased if matches occur, and after the loop the span id="found" is updated with the value of that variable.
For counting matches of the phrase and not numbers of paragraphs with matches, the text content is split up using the search phrase as delimiter. Then the number of pieces minus one is the number of occurences. Counted are phrases, not words. The phrase "the" is found in both " the " and " they ", but not in "The". Case sensitivity wasn't asked and isn't hard to implement. Just uppercase both the search phrase and the text being searched.
For simplicity, I put together HTML, Javascript and CSS into one file.
So I have a button in my HTML and when I click that button, I want to remove some elements from the page.
currently I have a function something like this which sets the listener for that button.
function addListener_close(elem,i){
console.log("IN BUTTON");
elem.addEventListener("click", function(){
console.log("clicked");
//this returns 'block' which is the current display
console.log(document.getElementById("newsentry-author").style.display);
//set the display to none
document.getElementById("newsentry-author").style.display = "none";
//this returns 'none' which is the new value
console.log(document.getElementById("newsentry-author").style.display);
});}
However, in my HTML page, none of the elements' style changed after I click the button.
Where did I do wrong?
UPDATE HTML CODE
<div class="newsentry-clicked">
<img class= "newsimage" src="https://dynaimage.cdn.cnn.com/cnn/digital-images/org/044409cb-e6f2-4c5b-8eaf-26078a4edef2.jpg">
<div class="newsentry-text">
<div class="newsentry-title">Commuting in the time of coronavirus in the nation's largest subway system</div>
<div class="newsentry-author"><span style="font-weight: bold">Author: </span>Lebron James</div>
<div class="newsentry-source"><span style="font-weight: bold">Source: </span>google.com</div>
<div class="newsentry-date"><span style="font-weight: bold">Date: </span>2020/03/02</div>
<div class="newsentry-desc-clicked">Crowded trains each weekday carry more than 5 million people hardened by terror threats and track-dwelling rats, daylight assaults and diluvial water main breaks. COVID-19 is their latest worry. The spread of the virus has unleashed anxiety across the nation'…</div>
See Original Post
</div>
<div class="close-button">×</div>
The function is bound to .close-button using javascript addEventListener
I must use a for loop to go through the h2 elements in the array and remove the class attribute for all h2 elements that aren’t the one that has been clicked. I also need to remove the class attributes for all of the div siblings of the h2 elements that weren’t clicked, but I am not sure how to do this. The code I am trying to use is under the "//remove all other answers" comment. Please help me out, thanks!
var toggle = function() {
var h2 = this; // clicked h2 tag
var div = h2.nextElementSibling; // h2 tag's sibling div tag
// toggle plus and minus image in h2 elements by adding or removing a class
if (h2.hasAttribute("class")) {
h2.removeAttribute("class");
} else {
h2.setAttribute("class", "minus");
}
// toggle div visibility by adding or removing a class
if (div.hasAttribute("class")) {
div.removeAttribute("class");
} else {
div.setAttribute("class", "open");
}
//remove all other answers
var faqs = $("faqs");
var h2Elements = faqs.getElementsByTagName("h2");
for (var i = 0; i < h2Elements.length; i++ ) {
if(!h2Elements.onclick) {
h2.removeAttribute("class", "minus");
} else {
h2Elements.onclick;
}
}
};
<body>
<main id="faqs">
<h1>JavaScript FAQs</h1>
<h2><a href="#" >What is JavaScript?</a></h2>
<div id="1">
<p>JavaScript is a is a browser-based programming language
that makes web pages more responsive and saves round trips to the server.
</p>
</div>
<h2>What is jQuery?</h2>
<div id="2">
<p>jQuery is a library of the JavaScript functions that you're most likely
to need as you develop websites.
</p>
</div>
<h2>Why is jQuery becoming so popular?</h2>
<div id="3">
<p>Three reasons:</p>
<ul>
<li>It's free.</li>
<li>It lets you get more done in less time.</li>
<li>All of its functions are cross-browser compatible.</li>
</ul>
</div>
</main>
</body>
This example should accomplish what you've outlined in your question. Here I'm looping through all H2 elements and processing the one that was clicked separately.
$('h2').on('click',function(){
var thisH2 = this;
$('h2').each(function(){
if (this === thisH2){
if ($(this).next().is(":visible")){
$(this).removeClass('plus').addClass('minus');
$(this).next().hide();
}else{
$(this).removeClass('minus').addClass('plus');
$(this).next().toggle();
}
}else{
$(this).removeClass('plus').addClass('minus');
$(this).next().hide();
}
});
});
h2{
cursor:pointer;
}
h2:hover{
text-decoration:underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<main id="faqs">
<h1>JavaScript FAQs</h1>
<h2 class="minus">What is JavaScript?</h2>
<div class="answer" style='display:none'>
<p>JavaScript is a is a browser-based programming language
that makes web pages more responsive and saves round trips to the server.
</p>
</div>
<h2 class="minus">What is jQuery?</h2>
<div class="answer" style='display:none'>
<p>jQuery is a library of the JavaScript functions that you're most likely
to need as you develop websites.
</p>
</div>
<h2 class="minus">Why is jQuery becoming so popular?</h2>
<div class="answer" style='display:none'>
<p>Three reasons:</p>
<ul>
<li>It's free.</li>
<li>It lets you get more done in less time.</li>
<li>All of its functions are cross-browser compatible.</li>
</ul>
</div>
</main>
</body>
There is an easy common pattern for your type of problem. Give all questions a single, shared classname. Then on click
use document.getElementsByClassName with the shared classname and apply css display:"none" (or a class that achieves this style) on all elements
set display:"block" or display:"inline" on the current selection
You've wrapped all this code in your toggle function, but the function is not called anywhere.
You should attach the event listener to your h2 tags after defining them with jQuery.
The order of your set/remove attributes is a little off.
Try coming this working example to your code:
var h2 = $("h2");
h2.on('click', function() {
for (var i = 0; i < h2.length; i++) {
if (h2[i] !== this) {
h2[i].setAttribute('class', 'red');
} else {
h2[i].removeAttribute('class', 'red');
}
}
})
I've use the example class red here if you wanted to say, toggle the color in your CSS. You can use whatever class here in place of my example.
Hope this helps. What I have done is I hide all div(and remove class red from all h2 tag other than one which is click in for loop) and toggle clicked h2 and it's sibling.
function func(e){
var x=document.getElementsByClassName("ans");
for(var i=0;i<x.length;i++){
if(x[i].classList.value.indexOf("hide")<0 && x[i]!==e.nextElementSibling){
x[i].classList.toggle("hide");
x[i].previousElementSibling.classList.toggle("red");
}
}
e.classList.toggle("red");
e.nextElementSibling.classList.toggle("hide");
}
.red{
background-color:red;
}
.hide{
display:none;
}
<body>
<main id="faqs">
<h1>JavaScript FAQs</h1>
<h2 onclick="func(this)"><a href="#" >What is JavaScript?</a></h2>
<div id="1" class="ans hide">
<p>JavaScript is a is a browser-based programming language
that makes web pages more responsive and saves round trips to the server.
</p>
</div>
<h2 onclick="func(this)">What is jQuery?</h2>
<div id="2" class="ans hide">
<p>jQuery is a library of the JavaScript functions that you're most likely
to need as you develop websites.
</p>
</div>
<h2 onclick="func(this)">Why is jQuery becoming so popular?</h2>
<div id="3" class="ans hide">
<p>Three reasons:</p>
<ul>
<li>It's free.</li>
<li>It lets you get more done in less time.</li>
<li>All of its functions are cross-browser compatible.</li>
</ul>
</div>
</main>
</body>
To help you identify your sections from your Subheadings
Add this to all sections you can use different identifiers
I'd suggest adding a class or attribute
<h2>What is JavaScript?</h2>
<div class="section" id="1">
This will enable us to select all the divs will the class section
const sections = document.querySelectorAll('.section')
Then we can loop over them all and add the minus class I'd suggest just adding this in the mark up if you intend this to be your default state.
sections.forEach(el => {
el.classList.add('minus')
});
Now we can loop over all your anchor tags I'd suggest giving them an identifier such as a class to separate them from other anchor tags but the example i'll just select all the anchor tags.
We attach a function reference to the on click of the element called openSection which we'll define shortly.
document.querySelectorAll('a').forEach((el, index) => {
el.onclick = openSection;
})
Now, this is the function that will toggle your minus and remove it from other items
Your function gets passed an event which will contain the information we need to get the correct section to hide. We loop through the sections and remove minus with toggle if it matches the element clicked and then any other item if it doesn't have minus it gets added on to make sure it's hidden.
function openSection(e) {
// we use - 1 because lists start at 0
const el = e.srcElement.classList.value - 1;
sections.forEach((section, index) => {
if (index === el) {
section.classList.toggle('minus')
} else if (!section.classList.contains('minus')) {
section.classList.add('minus')
}
})
}
Working example
https://codepen.io/anon/pen/KoWgwm
Stuff used
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
I need to make sure only one of the .togglecontent divs show up at once, so when one slides down the other should slide up.
Here is what I have so far
(function($) {
$(document).ready(function() {
$('.toggler h3').click(function() {
var currentContent = $(this).siblings('.togglecontent');
$('.togglecontent').not(currentContent).slideUp();
currentContent.slideToggle();
});
});
})(jQuery);
<div class="toggler-wrap">
<div class="toggler">
<h3><span class="fa fa-angle-double-right"></span> What I offer employees</h3>
<div class="togglecontent">
I have extensive experience litigating a full range of employment claims:
<ul>
<li>discrimination, harassment, retaliation, and wrongful termination</li>
<li>claims involving disability, religious, and pregnancy accommodations</li>
<li>California’s complex leave laws</li>
<li>the California Fair Employment and Housing Act (FEHA)</li>
<li>the California Family Rights Act (CFRA)</li>
<li>the Pregnancy Disability Leave Law (PDLL)</li>
<li>Title VII</li>
<li>the Family and Medical Leave Act (FMLA)</li>
<li>the Americans with Disabilities Act (ADA)</li>
<li>invasion of privacy claims under California law</li>
</ul>
</div>
</div>
<div class="toggler">
<h3><span class="fa fa-angle-double-right"></span> Consulting services for business</h3>
<div class="togglecontent">
For your business, prevention is the key to successful employment practices. I have years of experience helping businesses comply with federal and California employment laws, as well as those in other states.
<ul>
<li>I counsel business on a wide range of policies:
<ul>
<li>leaves of absence
<li>disability accommodation
<li>hiring and dismissal decisions
<li>performance management, policies and handbooks, and
<li>background checks.
</ul>
<li>I’ve conducted nearly 100 workplace training sessions on a wide range of subjects.
<li>If a problem arises, I can give you an independent evaluation.
<li>I’ve also conducted hundreds of workplace investigations.
</ul>
</div>
</div>
</div>
Here is a demo http://jsfiddle.net/4ae6afmj/
You can do something like this
$('.toggler h3').click(function() {
var currentContent = $(this).siblings('.togglecontent');
$('.togglecontent').not(currentContent).slideUp(); // <--- slide up all other .togglecontent except the current one
currentContent.slideToggle();
});
Here is a demo http://jsfiddle.net/dhirajbodicherla/4ae6afmj/3/
use can use .not()
(function($) {
$(document).ready(function() {
$('.toggler h3').click(function() {
$('.togglecontent').not($(this).closest('.toggler').find(' .togglecontent')).slideUp(0);
$(this).closest('.toggler').find('.togglecontent').slideToggle();
});
});
})(jQuery);
DEMO
and you can use
(function($) {
$(document).ready(function() {
$('.toggler h3').click(function() {
var thisContent = $(this).closest('.toggler').find(' .togglecontent');
$('.togglecontent').not(thisContent).slideUp(0);
thisContent.slideToggle();
});
});
})(jQuery);
DEMO
Check this DEMO : http://jsfiddle.net/4ae6afmj/5/
JQUERY
(function ($) {
$(document).ready(function () {
$('.toggler h3').click(function () {
$('.togglecontent').slideUp();
if($(this).siblings('div').css('display') === 'none')
$(this).siblings('div').slideDown();
else
$(this).siblings('div').slideUp();
});
});
})(jQuery);
I am 95% finished with this (I hope). I am working on an accordion function that changes the text in the head of the accordion depending if the accordion is opened or closed. (I've got a plus and minus image working).
At present if the client clicks on the accordion to open and close it the title changes correctly, but if the client opens a different accordion the original accordion will slide up, but the title is not updated. I've tried a couple of options I thought would work, but no success as yet.
I've made a jsfiddle here
jquery is:
$(document).ready(function() {
// accordion functionality
$('.accordion-head').click(function(e){
var content = $(this).parent().find('.accordion-content');
var head = $(this).parent().find('.accordion-head');
var $showMore = "Show me more";
var $hideContent = "Hide this offer";
content.addClass('actual');
$('.accordion-content').not('.actual').each(function(){
if ($(this).hasClass('accordion-opened')){
$(this).slideUp(200,function(){
$(this).toggleClass('accordion-opened');
$(this).parent().find('.accordion-head').toggleClass('accordion-open');
});
}
});
$(this).toggleClass('accordion-open');
content.removeClass('actual');
if($(this).hasClass('accordion-open')){
content.slideDown(200,function(){
content.toggleClass('accordion-opened');
head.html($hideContent);
});
}else{
content.slideUp(200,function(){
content.toggleClass('accordion-opened');
head.html($showMore);
});
}
e.preventDefault();
});
});
HTML looks like this:
<div class="accordion">
<div class="accordion-head">
<a href="#">
<span class="accordion-heading">Show me more</span>
</a>
</div>
<div class="accordion-content">
Including Thames Water, Severn Trent, Anglian Water, Yorkshire Water and many more, plus all council tax local authorities. Cashback on mortgage payments up to maximum monthly mortgage payment of £1,000.
</div>
</div>
<span class="spacer"></span>
<div class="accordion">
<div class="accordion-head">
<a href="#">
<span class="accordion-heading">Show me more</span>
</a>
</div>
<div class="accordion-content">
Including British Gas, SSE, EDF Energy, E.ON, npower and many more.
</div>
</div>
<span class="spacer"></span>
etc.
Hope someone can help.
You could rewrite the header during the collapse loop by removing head.html($showMore) & changing
$(this).parent().find('.accordion-head').toggleClass('accordion-open');
to
$(this).parent().find('.accordion-head').toggleClass('accordion-open').html($showMore);
You can also insert $('.accordion-head').html($showMore); inside click function , which will update all the headers intially to show more and then update the individual headers according to the conditions.
var $showMore = "Show me more";
var $hideContent = "Hide this offer";
$('.accordion-head').html($showMore);
content.addClass('actual');