I would like to make sure which method is the best and if my code is valid and good.
I did not succeed in renaming the text "hide contact" / "'show contact" to see the result.
.style.display = 'none'; seems a bit too brutal to me without an exit animation.
I opted for the "hide button" version
but if you know how to rename the button it will be a bonus.
I also have jerks on mobile (chrome), I can't understand why .slideToggle is not smooth everywhere.
Method 1 : not working
/* Show/hide rename button text */
jQuery(document).on('click', '#TEST_BTN', function(event) {
event.preventDefault();
$(document).ready(function(){
$("TEST_BTN").click(function(){
if ($(this).text() == 'show contact'){
$(this).html('hide contact;')
}else{
$(this).html('show contact');
}
jQuery('#hidden-content').slideToggle('250','swing','hide');
});
Method 2 : working
/* Hide show contact button */
document.addEventListener("DOMContentLoaded", function(event) {
jQuery('#TEST_BTN').click(function(){
event.preventDefault();
document.getElementById("TEST_BTN").style.display = 'none';
jQuery( '#hidden-content' ).slideToggle('250','swing','hide');
});
});
mmm click inside click for the same element?! it'll not work like this it will add another click event each time you click the element and this is what you'll get after some clicks
var i = 0;
$('button').on('click' , function(){
$('button').click(function(){
console.log(i++);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click Inside Click</button>
Your code should looks like
/* Show/hide rename button text */
$(document).ready(function(){
$("#TEST_BTN").click(function(){
$(this).text($(this).text() == 'show contact' ? 'hide contact': 'show contact')
$('#hidden-content').slideToggle('250','swing','hide');
});
});
I prefer to use classes instead of ids in this case .. It'll much easier especially if you've more than one card .. see the next simple example
/* Show/hide rename button text */
$(document).ready(function(){
$(".TEST_BTN").click(function(){
$(this).text($(this).text().toLowerCase().trim() == 'show contact' ? 'hide contact': 'show contact')
$(this).closest('.card').find('.hidden_content').slideToggle('250','swing','hide');
});
});
.hidden_content{
display : none;
height : 100px;
background : #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
Note: For event.preventDefault() you need to use function(event){ event.preventDefault();
Related
I am trying to trigger the visibility of a DIV via a button.
My code looks like this:
function myFunction() {
var moreText = document.getElementById("csrmore");
var x = document.getElementById("myDIV");
let ishidden = x.classList.contains("hidden")
if (ishidden == true) {
x.classList.remove("hidden");
x.classList.add("shown");
moreText.innerHTML = "Show less";
}
else {
x.classList.remove("shown");
x.classList.add("hidden");
moreText.innerHTML = "Show more";
}
}
div {
width: 100px;
height: 100px;
}
.hidden {
display:none
}
.shown {
display:block;
}
<button id="csrmore" onclick="myFunction()">
Show more
</button>
<div id="myDIV" class="hidden">
This is the triggerable content.
</div>
Fiddle: https://jsfiddle.net/6zxa0Lg2/
It works fine, however since I am a JS starter, I was wondering if this is bad practice or is it a totally fine piece of code?
Thanks for every help :)
Here's another way to go about it. Make it all relative. The button is clicked and the javascript finds the content associated to that button to show/hide. This way you don't need any ID tags and you can have as many show/hide buttons as you want on the page.
document.addEventListener('DOMContentLoaded', () => {
// after the page loads...
document.querySelectorAll('.csrmore').forEach(button => {
// find all the 'show more' buttons and for each one...
button.addEventListener('click', e => {
// when someone clicks this button
let content = e.target.closest('.container').querySelector('.content');
// find the content div associated with this button
content.classList.toggle('hidden');
// toggle on or off the content
e.target.innerText = content.classList.contains('hidden') ? 'Show more' : 'Hide';
// change the text of the button
})
})
})
div {
width: 100px;
height: 100px;
}
.hidden {
display: none
}
<div class='container'>
<button class="csrmore">
Show more
</button>
<div class="content hidden">
This is the triggerable content.
</div>
</div>
<hr>
<div class='container'>
<button class="csrmore">
Show more
</button>
<div class="content hidden">
This is the triggerable content.
</div>
</div>
This is a fine way to do this! This is not the solution I would not have come up with, but it is actually pretty clever. I would have thought to have done it by toggling TARGET.style.visibility to either "hidden" or "visible" when clicking the button. Again though, your code looks perfectly fine!
Okay, I have tried a few ways of doing this but nothing has worked. I am hoping someone here can tell me what I am doing wrong. Below is a step-by-step of what I am trying to achieve.
#info-NUMBER-btn displays Click to display more information.
#info-NUMBER CSS is set to display: none.
When #info-NUMBER-btn is clicked:
- Corresponding #info-NUMBER-btn displays Click to display less information.
- Corresponding #info-NUMBER CSS is set to display: inline-block.
/* Jquery */
$(document).ready(function() {
$("#info-1-btn").text("Click to display more information");
$("#info-2-btn").text("Click to display more information");
$("#info-3-btn").text("Click to display more information");
$("#info-4-btn").text("Click to display more information");
$("#info-5-btn").text("Click to display more information");
if($("#info-1-btn").text("Click to display more information")) {
$("#info-1-btn").click(function () {
$(this).text("Click to display less information");
$("#info-1").css("display", "inline-block");
});
} else if($("#info-1").text("Click to display less information")) {
$("#info-1-btn").click(function() {
$(this).text("Click to display more information");
$("#info-1").css("display", "none");
});
}
if($("#info-2-btn").text("Click to display more information")) {
$("#info-2-btn").click(function () {
$(this).text("Click to display less information");
$("#info-2").css("display", "inline-block");
});
} else {
$("#info-2-btn").click(function() {
$(this).text("Click to display more information");
$("#info-2").css("display", "none");
});
}
if($("#info-5-btn").text("Click to display more information")) {
$("#info-5-btn").click(function () {
$(this).text("Click to display less information");
$("#info-5").css("display", "inline-block");
});
} else {
$("#info-5-btn").click(function() {
$(this).text("Click to display more information");
$("#info-5").css("display", "none");
});
}
});
<!-- HTML -->
<div id="info-5" class="hire-equipment-more-information">
<table class="hire-equipment-more-information-table" cellpadding="15px">
<tr>
<th>Length:</th>
<th>Material:</th>
<th>HP:</th>
</tr>
<tr>
<td>7.5m</td>
<td>Aluminium</td>
<td>225</td>
</tr>
</table>
</div>
<br />
<a id="info-5-btn" class="hire-equipment-item-link"></a>
You could make it a lot more easy for yourself, by binding not to the element id's, but to use your class hire-equipment.
This way you don't have to bind to 5 different buttons that in essence do the same thing.
Once you hit the eventHandler, you can use the first argument of the function, to check from which button you are coming and take the appropriate action.
As an example, I just created the 5 elements, and 1 event handler.
The $(selector).click() will bind to all elements sharing the selector ( in my case hire-equipment), and then, it will check from which button it's coming, select the parent node (the div surrounding the button, title and description), search the description element, and toggle it's hidden class. The buttons text will then change depending on it's text.
It's not fully how your example is built, but it's an example of making your event handlers a bit more generic.
$('.hire-equipment').click(function(event) {
var sourceElement = $(event.target);
$(sourceElement).parent().find('.description').toggleClass('hidden');
if ($(sourceElement).text() === 'Show more information') {
$(sourceElement).text('Show less information');
} else {
$(sourceElement).text('Show more information');
}
});
.hidden {
display: none;
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<p class="title">Title of item</p>
<div class="description hidden">This is a description</div>
<button type="button" class="hire-equipment">Show more information</button>
</div>
<div>
<p class="title">Title of item</p>
<div class="description hidden">This is a description</div>
<button type="button" class="hire-equipment">Show more information</button>
</div>
<div>
<p class="title">Title of item</p>
<div class="description hidden">This is a description</div>
<button type="button" class="hire-equipment">Show more information</button>
</div>
<div>
<p class="title">Title of item</p>
<div class="description hidden">This is a description</div>
<button type="button" class="hire-equipment">Show more information</button>
</div>
Lets examine this line of code
if($("#info-1-btn").text("Click to display more information")) {
This should be:
if($("#info-1-btn").text() === "Click to display more information")) {
The text function is an overloaded function. If you pass in no value, it will return you the text inside the element.
If you pass in a value, it will modify the text, and return the jQuery object again (which will be a truthy value).
Now lets look at your overall logic.
Your code is testing the state of the buttons once, when the document loads. It should be testing the state of the button as part of the click handler.
See this complete code example: http://plnkr.co/edit/HLsLcKrRY3OqK6w44bXp?p=preview
It might not match your requirements exactly, but it demonstrates how you test the state of the button inside a click handler.
It also demonstrates how you can use a custom attribute (in this case, data-target) to link a button to a div block.
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#*" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
</head>
<body>
<button class="toggleButton" data-target="buttonOneInfo"></button>
<br />
<div class="toggleTarget" id="buttonOneInfo">
Here's some information about the first item
</div>
<button class="toggleButton" data-target="buttonTwoInfo"></button>
<br />
<div class="toggleTarget" id="buttonTwoInfo">
Here's some information about the second item
</div>
<button class="toggleButton" data-target="buttonThreeInfo"></button>
<br />
<div class="toggleTarget" id="buttonThreeInfo">
Here's some information about the third item
</div>
</body>
<script type="text/javascript">
$(function() {
$('.toggleTarget').hide();
$(".toggleButton")
.text("Click to display more information")
.click(function() {
var toggleTargetId = $(this).attr('data-target');
var toggleTarget = $(document.getElementById(toggleTargetId));
if ($(this).text() === 'Click to display more information') {
$(this).text('Click to display less information');
toggleTarget.show();
} else {
$(this).text('Click to display more information');
toggleTarget.hide();
}
});
});
</script>
</html>
Trimmed the fat off of OP's jQuery. The following procedure is roughly outlined here:
Primary method used is toggleClass()
At least 2 classes are required to indicate a state of .info-btn
The big advantage of using classes is that you can add more styles to each class that would enhance .info-btn's state. ex. color, background-color
Further details are commented in the source of the Snippet below:
SNIPPET
/* jQuery */
// Alternate styntax for $(document).ready(
$(function() {
// Click on ANYTHING with the class .info-btn
$(".info-btn").on("click", function(e) {
// Prevent .info-btn from jumping when clicked
e.preventDefault();
/* `this` or .info-btn will toggle between the
| classes of .more and .less
| See CSS for details of expected behavior of
| .info-btn in both states
*/
$(this).toggleClass('more less');
});
});
.info-btn {
cursor: pointer;
}
/* Both classes use the :after pseudo-selector
| The value of content will complete the
| string: "Click to display"...
*/
a.more:after {
content: ' more information';
}
a.less:after {
content: ' less information';
}
button.less:before {
content: 'less ';
}
button.less:after {
content: ' more';
}
button.more:before {
content: 'more ';
}
button.more:after {
content: ' less';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- HTML -->
<div id="info-5" class="rental-info">
<table class="rental-info-table" cellpadding="15px">
<tr>
<th>Length:</th>
<th>Material:</th>
<th>HP:</th>
</tr>
<tr>
<td>7.5m</td>
<td>Aluminium</td>
<td>225</td>
</tr>
</table>
</div>
<br />
<a class="info-btn rental-link more">Click to display</a>
<br/>
<button class='info-btn less'>is</button>
<br/>
I'm trying to learn jQuery... everything is going slow & steady. Not complaining. However I like to challenge myself to do something different whenever that tutorial I'm doing is showing me something.
So this is what I have:
A HTML page with some DIVs.
I want to dynamically add a SHOW/HIDE button at the end of each DIV.
If I click that button that DIV above that show/hide button should disappear.
The HIDE button should become SHOW. If I click it again it should show the DIV again.
I know how to add a show/hide button at the end of each div.
I don't know how to tell each button that the DIV above him should be hidden.
The divs do not have an unique ID so I'm thinking that I should also add an unique ID to each DIV. I want to do this with jQuery.
So I'm thinking that I should do some kind of foreach loop. I should go trough each DIV, add an unique ID, add the unique show/hide button that would tell the exact DIV number to hide/show.
Did I got the logic right? Can anyone show me the exact syntax? I'm not only looking for the right code but also see if I have the right logic.
Thank You
$('button').click(function() {
$(this).parent().prev().toggle();
if ($(this).text() == 'Show') {
$(this).text('Hide');
} else {
$(this).text('Show');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>a
<button>Hide</button>
</div>
<div>b
<button>Hide</button>
</div>
<div>c
<button>Hide</button>
</div>
<div>d
<button>Hide</button>
</div>
Or did you mean like this:
$('button').click(function() {
$(this).prev().toggle();
if ($(this).text() == 'Show') {
$(this).text('Hide');
} else {
$(this).text('Show');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><span>a</span>
<button>Hide</button>
</div>
<div><span>b</span>
<button>Hide</button>
</div>
<div><span>c</span>
<button>Hide</button>
</div>
<div><span>d</span>
<button>Hide</button>
</div>
or like this:
$('button').click(function() {
$(this).prev().toggle();
if ($(this).text() == 'Show') {
$(this).text('Hide');
} else {
$(this).text('Show');
}
});
div {display: inline}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>a</div>
<button>Hide</button><br/>
<div>b</div>
<button>Hide</button><br/>
<div>c</div>
<button>Hide</button><br/>
<div>d</div>
<button>Hide</button><br/>
I have a series of text links that toggle visibility of a div element. The text links are styled to look like buttons and the text is being changed when the div is visible or invisible.
The problem is that when the first link is pressed, it toggles the visibility of it's own div plus all the other hidden divs and what is needed is that each link toggles the visibility of it's own div.
My question is what is the best way to solve this problem using only one function. Below is my code. Thanks!
The code can be also tested here:
http://jsfiddle.net/Bradg/eBfxB/
HTML:
<div>
See all
</div>
<div class="slidingDiv" style="display: block;">
<h2>Content One</h2>
</div>
<div>
See all
</div>
<div class="slidingDiv" style="display: block;">
<h2>Content Two</h2>
</div>
JS:
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').toggle(function(){
$(".slidingDiv").slideDown(
function(){
$("#plus").text("Hide all")
}
);
},function(){
$(".slidingDiv").slideUp(
function(){
$("#plus").text("See all")
}
);
});
});
CSS:
.show_hide {
display: none;
}
The version of toggle() that accepts two callbacks have been deprecated and removed, so you'll have to use click instead and do something like this
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').on('click', function(e){
e.preventDefault();
var self = this,
sliding = $(this).closest('div').next('.slidingDiv').slideToggle(function(){
$(self).text(function(_,txt) {
return txt == "Hide all" ? "See all" : "Hide all";
});
});
});
});
FIDDLE
Note the use of the classes only (ID's must be unique) and the this keyword
I want to make a function that hides/shows a div when clicking on a button. The idea would be to be able to pass the ID of the div I want to hide through the event. But I'm not quite sure how to do it.
This is what I have done until now:
<div onmousedown="toogleDiv(badges)"> //clicking here should hide div id=badges
Icons v
</div>
<div id="badges">
</div>
<div onmousedown="toogleDiv(items)"> //clicking here should hide div id=items
Items v
</div>
<div id="items">
</div>
<script>
// Hide/show div;
function toogleDiv()
{
}
</script>
function toogleDiv(id){
var s = document.getElementById(id).style;
s.display = s.display === 'none' ? 'block' : 'none';
}
Then you can pass the id in as a string IE instead of toggleDiv(items) use toggleDiv('items')
Example
try
function hideDiv(id)
{
document.getElementById(id).style.display="none";
}