I have a list of questions and answers. I want a Plus/Minus icon to toggle, and when it is clicked, the answer appears below. I have written up the basic code, but when I click the Plus button for one of the questions, it toggles the answer to display on all of the questions rather than just that specific one. Please see the jsfiddle.
JS:
$(".plus").click(function(){
$(this).toggleClass("minus plus");
});
$(".plus").click(function(){
$(".answer").toggle();
});
How do I get it so that if I press the icon for Question 1, it only shows me Answer 1, and doesn't toggle the other icons?
Here's an updated JSfiddle: https://jsfiddle.net/ocm81sv8/7/
I would do your script like this:
JavaScript
$(".plus").click(function(){
var $this = $(this);
$this.toggleClass("minus plus");
$this.parent().next(".answer").toggle();
});
HTML
<div class="faq-block">
<ul>
<li class="question">
<p><span class="plus"></span>Question 1</p>
<p class="answer" style="display: none;">Answer 1</p>
</li>
<li class="question">
<p><span class="plus"></span>Question 2</p>
<p class="answer" style="display: none;">Answer 2</p>
</li>
</ul>
</div>
I removed having 2 click handlers for the same item and placed them into one call.
I also corrected your .plus elements to be span tags, as it's invalid for a block level element like div to be within p tags.
Updated Fiddle
You should replace <p><div class="plus"></div>Question 1</p> by <p><span class="plus"></span>Question 1</p> since <p><div></div></p> is not a valid HTML code, check the following post Putting <div> inside <p> is adding an extra <p>.
You should toggle the related answer with clicked .plus, so you could use closest('li') to get the parent question then .find(".answer") to target the related answer :
$(".plus").click(function(){
$(this).closest('li').find(".answer").toggle();
});
Instead of :
$(".plus").click(function(){
$(".answer").toggle();
});
Hope this helps.
$(".plus").click(function(){
$(this).toggleClass("minus plus").closest('li').find(".answer").toggle();
});
.faq-block ul, .faq-block ul li {
list-style-type: none !important;
}
span.plus {
display: block;
width: 30px;
height: 30px;
background-color: red;
float:left;
margin-right: 20px;
cursor:pointer;
}
span.minus {
display: block;
width: 30px;
height: 30px;
background-color: blue !important;
float:left;
margin-right: 20px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq-block">
<ul>
<li class="question">
<p><span class="plus"></span>Question 1</p>
<p class="answer" style="display: none;">Answer 1</p>
</li>
<li class="question">
<p><span class="plus"></span>Question 1</p>
<p class="answer" style="display: none;">Answer 1</p>
</li>
</ul>
</div>
The fact that you're already using $(this) to get the currently clicked-on element, and yet still fail to use that to get the right target, makes me sad...
First things first. It is not valid to have <div> inside a <p> tag, causing JSFiddle to highlight these errors. It can be fixed by using <span> instead of <div>.
Now, as for doing the toggle, just navigate your way through the DOM:
$(this).closest(".question").find(".answer").toggle();
Navigates up the tree to the .question, then back down to the .answer, and toggles it.
https://jsfiddle.net/ocm81sv8/3/
https://jsfiddle.net/ocm81sv8/8/
$(".plus").on('click', function() {
$(this).toggleClass("minus plus")
.closest('li').find(".answer").toggle();
});
This will make sure if you click on a plus element, it will only toggle its own item, and then find the answer to show.
You need to use a more specific selector. Currently, you are using the class selector ".plus", which is going to be something common to all your questions. It is not a unique identifier. Your code will match all elements that fit your selector scope. To see what I mean, just enter $(".plus") in the chrome console on that page. It will return an array consisting of all the elements that match.
My suggestion is add a unique id to each question, so perhaps something like "question-0", "question-1" ... and so on, then use the selector "#question-X" to toggle it.
Hopefully that helps,
Good luck
Related
How to link to a <div> on another page? was showing how to Link text to a div id, but what I am looking to do is write one web page that is linked from other pages but hides all content but what the link id says to show. o page1 link to infopage.html with content A visible and page2 link to infopage.html with content B visible, page3 link to infopage.html with content C visible and so on. using plain HTML, CSS and vanilla JavaScript. no jQuery please; trying to learn how this would tie together. hope I explained this well enough
One option is to use the :target selector.
You hide all the content in CSS with the use of display: none;. Then you can show the content when the link is clicked by using *:target { display: block; }
If you want to load content from other websites, you can either use PHP include or iframe. However you cant show only specific parts of the website that easily. You would need to overwrite its default styling with the same emthod mentioned above.
main > div {
display: none;
}
main > div:target {
display: block;
}
/* For Styling Pupose only */
nav ul {
display: flex;
list-style: none;
}
nav li {
margin: 0 10px;
}
<nav>
<ul>
<li>Content A</li>
<li>Content B</li>
<li>Content C</li>
</ul>
</nav>
<main>
<div id="A">This is Content A</div>
<div id="B">This is Content B</div>
<div id="C">This is Content C</div>
</main>
Here's a quick and dirty way to make that happen:
all the articles are hidden by default
window.location.href.split('#')[1] will get you the anchor name
classList.remove('hidden') removes the hidden class from the selected article
page1.html
<style> .hidden { display: none; }</style>
<div id="article1" class="hidden"><h2>Article 1</h2></div>
<div id="article2" class="hidden"><h2>Article 2</h2></div>
<p>Go to Article 3</p>
<p>Go to Article 4</p>
<script>
document.querySelector(`#${window.location.href.split('#')[1]}`).classList.remove('hidden');
</script>
page2.html
<style>.hidden { display: none; } </style>
<div id="article3" class="hidden"><h2>Article 3</h2></div>
<div id="article4" class="hidden"><h2>Article 4</h2></div>
<p>Go to Article 1</p>
<p>Go to Article 2</p>
<script>
document.querySelector(`#${window.location.href.split('#')[1]}`).classList.remove('hidden');
</script>
<div id="box1"> <img src="images/pskeksmall.jpg" alt="" />
<h2 class="subtitle">Student Makes our new website</h2>
<p>We are very proud to announce that our new website was designed and created by Charlie Johnson</p>
<ul class="contact">
<li><span></span></li>
<li><span>Pinterest</span></li>
<li><span>Google+</span></li>
</ul>
</div>
What I want this to do is open in a small window, and have more information on the topic. I've only looked briefly at JavaScript, so if there's an easy way to do this without JScript it would be preferable. I need to do this for 3 other boxes too.
EDIT: Maybe I wasn't very clear, I don't want to user to leave the page, at all, using Chrome I know that popups open in the small dialogue box, this is what I want the information to be provided by. If this isn't possible, is there a way that I could change the information in the main text area, without changing the page?
EDIT 2: OK so I found this on W3Schools.com:
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
document.getElementById("demo").innerHTML = "Paragraph changed.";
}
</script>
</head>
<body>
<h1>JavaScript in Head</h1>
<p id="demo">A Paragraph.</p>
<button type="button" onclick="myFunction()">Try it</button>
</body>
</html>
So I'm now wondering if it would be possible to use my image in substitute to the button, and change my instead of the paragraph used above.
The easy HTML way to do this is to use a tags with the target attribute:
Try it
A tag documentation: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
Here is a CSS-only example of how you can click-to-reveal a (usually hidden) element which can then display more information.
No javascript needed!
.more-info {
display: none;
background-color: rgba(255,255,127,1);
padding: 6px;
border: 2px solid rgba(127, 0, 0, 1);
}
#item1:target, #item2:target {
display: inline-block;
}
<ul>
<li>Click me for more info about Item 1</li>
<li>Click me for more info about Item 2</li>
</ul>
<p id="item1" class="more-info">Now you can read more information about Item 1</p>
<p id="item2" class="more-info">Now you can read more information about Item 2</p>
I'm trying to wrap text to fit inside it's parent element however I'm having issues with the text as seen in the below image.
On the left side, the word 'Against' is broken up and is harder to read though on the right side, the single word is too long and so is correctly broken up to fit within it's parent. Here is the code to support this:
HTML:
<li>
<div class="icon">
<h5>D</h5>
</div>
<p class="label">Defending Ourselves Against Infectious Diseases</p>
</li>
<li>
<div class="icon">
<h5>D</h5>
</div>
<p class="label">DefendingOurselvesAgainstInfectiousDiseases</p>
</li>
CSS:
.label {
word-break: break-all;
}
I would preferably like the left side to display the text without breaks and the right side to display with breaks (and a hyphen to show that it is broken) as the word is too long.
A CSS solution would be better though I think the only way to solve this is with Javascript. How would I fix this text issue?
EDIT
Also, I cannot just use a <br> tag because I would like this to apply to many other elements like this.
Replace the word-break rule with word-wrap: break-word.
li {
max-width: 200px;
word-wrap: break-word;
}
<ul>
<li>
<div class="icon">
<h5>D</h5>
</div>
<p class="label">Defending Ourselves Against Infectious Diseases</p>
</li>
<li>
<div class="icon">
<h5>D</h5>
</div>
<p class="label">DefendingOurselvesAgainstInfectiousDiseases</p>
</li>
</ul>
Use word-wrap instead of word-break.
If you have to cut some extra texts then there is
text-overflow:ellipsis;
word-wrap: break-word; (Only in IE7)
I found a good Article:
http://kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/
http://www.impressivewebs.com/word-wrap-css3/
JS
<div id="myDIV">GIVE YOUR TEXT</div>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
document.getElementById("myDIV").style.wordWrap = "break-word";
}
</script>
<div>
<a target="_blank" href="/ShowDetails.php">
<ul>
<li>Code1:123456</li>
<li>Code2:654321</li>
</ul>
... somethings ....
</a>
</div>
I want when the user clicks on Code1:123456 that they go to ShowDetails.php and when the user clicks on Code2:654321 nothing happens, so that they can copy the code. Right now when an user clicks Code2:... the user goes to ShowDetails.php too.
and i want whole div linked to ShowDetails.php expect Code2:654321
You could maybe do this:
$(function() {
$("a").on('click', function(e) {
if (e.target.innerHTML.indexOf('654321')>-1) e.preventDefault();
});
});
Of course give your 'a tag' an ID or class for the selector.
This solution works if you know the content you're looking for
WORKING EXAMPLE
If you have any questions let me know.. good luck!
If you surround all the list with the <a> tag, all the list will be considered as a link.
You want to move the link to surround only the text in the first item :
<div>
<ul>
<li><a target="_blank" href="/ShowDetails.php">Code1:123456</a></li>
<li>Code2:654321</li>
</ul>
</div>
By the way, target="_blank" is to be avoided in order to keep accessibility for people who need it. They may be troubled if they can't go on the previous page by clicking the appropriate button.
The best solution is to generate the correct html code in the first place. You can move the link inside the first li-element.
div {
border: 1px blue dotted;
}
.spacer {
background-color: #DDDDDD;
height: 100px;
border: none;
}
<div>
<ul>
<li>
<a target="_blank" href="/ShowDetails.php">Code1:123456</a>
</li>
<li>Code2:654321</li>
</ul>
<a target="_blank" href="/ShowDetails.php">
<div class="spacer"></div>
</a>
</div>
Edit: Added extra links in places where they are needed.
This is my pen: http://codepen.io/anon/pen/IszKj
What I want to do is how it so when I click on either any status or any date I open up a hidden div which gives a list of options.
My question is, how do I approach this in the best way?
Do I have two different divs and then open the one which is relevant to the list item which was clicked:
<div id="status" style="display: hidden">Option 1 Option 2</div>
<div id="date" style="display: hidden">Option 1 Option 2</div>
Do I have one div and only show the content inside it which is relevant to that button?
<div style="hidden">
<span id="status">...</span>
<span id="date">...</span>
</div>
In addition to this, should I be using toggle or the traditional open / close function.
It would be nice for it to be degradable if JS is disabled.
Created a Fiddle for you:
http://jsfiddle.net/e4mQD/1/
HTML:
<div style="display: block;
height: 40px;">
<ul id="filter">
<li>
<span>Any status▾</span>
<ul class="options">
<li>Option1</li>
<li>Option2</li>
</ul>
</li>
<li>
<span>Any date▾</span>
<ul class="options">
<li>OptionA</li>
<li>OptionB</li>
</ul>
</li>
</ul>
CSS:
#filter, .options {
list-style-type: none;
}
.options {
display:none;
}
.options li {
cursor: pointer;
}
JavaScript:
$('#filter li').click(function(){
$(this).find('.options').toggle();
});
display:hidden
is not valid css rule. You need to use display:none
My question is, how do I approach this in the best way?
In your particular use-case, it is better that you use different blocks for each of those options.
In fact, as #mh-itc pointed out, it is better if you use nested list i.e. ul instead of div inside those lis.
Also, you may use a instead of span.
It would be nice for it to be degradable if JS is disabled.
This can be achieved by deferring the display:none; until the JavaScript is loaded and run.
Demo: http://jsfiddle.net/abhitalks/928Dj/
Markup:
<div>
<ul id="filter">
<li>
Any status ▾
<ul class="opt">
<li><label><input type="checkbox" />Status 1</label></li>
<li><label><input type="checkbox" />Status 2</label></li>
</ul>
</li>
<li>
Any date ▾
<ul class="opt">
<li><label><input type="checkbox" />Date 1</label></li>
<li><label><input type="checkbox" />Date 2</label></li>
</ul>
</li>
</ul>
</div>
CSS:
ul {
margin: 0; padding: 0;
list-style: none;
}
#filter {
display: inline-block;
}
#filter > li {
display: inline-block;
margin-bottom: 12px;
padding-right: 12px;
vertical-align: top;
}
ul.opt.hidden {
display: none;
}
jQuery Code:
// comment out to see how it degrades without javascript
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
$(this).next('ul').toggle();
});
Note: In the demo, un-comment the JavaScript code to see how it will behave when JavaScript is available. And comment out to see how it degrades when JavaScript isn't available.
If you want to keep accessibility in mind change the hidden status when loading the site with javascript, if you do that user that have add-ons like NoScript active get to see every option without loosing functionality.
People who use NoScript tend to dislike sites that force them to deactivate NS to use it properly.
For your solution I suggest to use two separate divs, with this you have the option to show both boxes at the same time and have a styled version that makes clear, that these are separate.
Add a class like "optionbox" to these and throw your css rules in there instead of making a rule with #date, #status