Targeting a specific class with jQuery - javascript

I am trying to display a hidden class in jQuery but it is no applying to the class I am targeting. It displays the whole class:
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
</div>
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
</div>
The class comment_data is display: none by default and should only be displayed whenever the More button is clicked. Working but it is displaying all the comments for 3 div.
This is my jQuery code:
$( ".mmore" ).click(function() {
$('.comment_data').slideToggle("slow");
});

$('.mmore').click(function() {
$(this).parents('.feeds').find('.comment_data').slideToggle('slow')
});

You can use .closest() to find .feeds div and then use .find() for *.comment_data* div
$('.mmore').click(function() {
$(this).closest('.feeds').find('.comment_data').slideToggle('slow')
});

You're selecting all objects matching the selector .comment_data.
You'll need to limit it to the same container that the clicked button is in. There's a number of ways you could do this. One easy one would be:
$( ".mmore" ).click(function() {
$(this).parent().find('.comment_data').slideToggle("slow");
});

Related

show only one div hide multiple div

I have multiple div which has the same class and I want to display only one div per click which belongs to the parent div. I want to hide and show div "post-reply-box".
HTML
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i></a>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p> </div>
<div class="comnt comnt-reply">
<div class="post-reply-box" style="padding:10px; display: none;">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton">cancel</button>
</form>
</div>
</div>
jQuery
$(document).ready(function(){
$(".fa-reply").on("click",function(){
$(".post-reply-box").css("display","block");
});
});
$(document).ready(function(){
$(".cancelButton").on("click",function(){
$(".post-reply-box").css("display","none");
});
});
The issue in your code is because you're using a class selector which retrieves all the .post-reply-box elements in the DOM, not just the one relevant to the button which was clicked.
To fix this use DOM traversal to relate the elements to each other. In this specific example use closest() to get the .we-comment related to the button, then next() to get the .comnt-reply container, then find().
In addition there some other issues which need to be addressed:
There's no need to duplicate document.ready handlers. Put all the logic in a single one.
Use show() and hide() instead of css() to set the display state of the element.
Use a CSS file instead of inline style elements to set style rules.
Attach the event handler to the a element, not the child i, and call preventDefault() on the event that's raised.
Add the type="button" attribute to the Cancel button so that clicking it does not submit the form.
With all that said, try this:
jQuery($ => { // updated document.ready handler
$(".we-reply").on("click", e => {
e.preventDefault()
$('.post-reply-box').hide(); // hide all
$(e.target).closest('.we-comment').next('.comnt-reply').find(".post-reply-box").show(); // show relevant
});
$(".cancelButton").on("click", function() {
$(".post-reply-box").hide();
});
});
.post-reply-box {
padding: 10px;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i> Reply</a>
<span class="like-comment" data-toggle="tooltip" title="like">
<i class="ti-heart"></i>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p>
</div>
<div class="comnt comnt-reply">
<div class="post-reply-box">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton" type="button">cancel</button>
</form>
</div>
</div>
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i> Reply</a>
<span class="like-comment" data-toggle="tooltip" title="like">
<i class="ti-heart"></i>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p>
</div>
<div class="comnt comnt-reply">
<div class="post-reply-box">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton" type="button">cancel</button>
</form>
</div>
</div>

How to filter image gallery by tags using Javascript?

I've been struggling to understand how to overcome this problem. I've been tasked to retrieve user input, and on keystroke see if user input matches any amount of .tags If not, hide the .thumb-display.
So far, I've been able to gather that I'll need to add/remove the classlist "hidden" as well use the event handler "input", however I don't quite understand how to use event handler "input" in this context as well as change event.
This is for homework so I'd much rather have an explanation for an answer, rather than just an answer so I can understand what I currently can't. Even a hint could be vital and set me on the right track! Rules are: no changing HTML and must use JavaScript.
Here is the HTML:
<form class="frm-filter">
<div class="frm-group">
<a class="reset hidden" href="#">Reset</a>
<input class="frm-control" type="text" id="filter" name="filter" placeholder="tag filter" />
</div>
</form>
</nav>
<section class="gallery">
<div class="row">
<h1>Gallery</h1>
</div>
<div class="row">
<div class="thumb-display">
<img src="img/thumbs/african_road_to_the_mountain.jpg" alt="african road to the mountain" />
<p class="tags">#africa #mountain #road</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_and_palms.jpg" alt="beach and palms" />
<p class="tags">#palmbeach #distantpeaks</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_road.jpg" alt="beach road" />
<p class="tags">#oceanbeach #mountainroad</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/calm_lake.jpg" alt="calm lake" />
<p class="tags">#lake #clearskies #onthewater</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/fall_bridge.jpg" alt="fall bridge" />
<p class="tags">#fallcolors #bridgecrossing #river</p>
</div>
</div>
</section>
You need to listen on input keyup event and retrieve value from input then check if that value matches any tags and show/hide `parentNode
document.addEventListener('DOMContentLoaded', () => {
const inputEl = document.getElementById('filter');
const tags = Array.from(document.querySelectorAll('.tags'));
inputEl.addEventListener('keyup', () => {
const value = inputEl.value;
tags.forEach(tag => {
if (tag.textContent.includes(value)) {
tag.parentNode.style.display = 'block'
} else {
tag.parentNode.style.display = 'none'
}
})
})
})
<form class="frm-filter">
<div class="frm-group">
<a class="reset hidden" href="#">Reset</a>
<input class="frm-control" type="text" id="filter" name="filter" placeholder="tag filter" />
</div>
</form>
<section class="gallery">
<div class="row">
<h1>Gallery</h1>
</div>
<div class="row">
<div class="thumb-display">
<img src="img/thumbs/african_road_to_the_mountain.jpg" alt="african road to the mountain" />
<p class="tags">#africa #mountain #road</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_and_palms.jpg" alt="beach and palms" />
<p class="tags">#palmbeach #distantpeaks</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_road.jpg" alt="beach road" />
<p class="tags">#oceanbeach #mountainroad</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/calm_lake.jpg" alt="calm lake" />
<p class="tags">#lake #clearskies #onthewater</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/fall_bridge.jpg" alt="fall bridge" />
<p class="tags">#fallcolors #bridgecrossing #river</p>
</div>
</div>
</section>
You need to get user input. So you need to listen for an event. Add Event Listener to the rescue. Which event, though? How about "change".
Ok, so you can get what they typed, good. Now you need to compare it to the tags. So it's time to find all of those. You can get all of the ".tags" with a querySelector. That will get you a list of nodes that you can loop through to collect the innerText. You can check if the innerText includes the input that the user typed. If it doesn't, then you find the closest ".thumb-display" and set a style attribute to hide it. If the input IS in the innerText, then you need to remove any style attribute that is hiding the closest parent.
Boom, done. Maybe, I didn't try it an I almost never get it right the first time. But it would be something along those lines.

Add remove with numbering indicated dynamically

So currently I can easily add and remove multiple textarea
But what I'm trying to do is to put numbering per specific textarea
Here's my textarea
as you notice my default text area is Step 1
But I wanted to do is when I clicked add it will show another textarea that says
Step 2
<div class="optionBox">
<div class="block">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step 1</label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>
<div class="block"> <span class="add">Add Option</span>
</div>
</div>
My Javascript
$('.add').click(function () {
$('.block:last').before(' <div class="block"><div class="form-group"><label for="exampleFormControlTextarea1">Step</label><textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea></div><span class="remove">Remove</span></div>');
});
Here's the current output
To make this work you can add a span element with no content to the label within each .block. Then you can create a function which updates the number within that span based on the index of the element every time you add or remove a .block.
I would also strongly suggest that you clone elements instead of adding lots of HTML in to your JS logic, as this violates the Separation of Concerns principle due to tying the JS too closely with the HTML. In your case this can be done by simply adding one extra class on to the .block which holds the textarea elements. Try this:
$('.add').click(function() {
let $lastBlock = $('.block.step:last');
let $clone = $lastBlock.clone().insertAfter($lastBlock);
$clone.find('textarea').val('');
updateStepCounts();
});
$('.optionBox').on('click', '.remove', function() {
if ($('.block.step').length > 1) {
$(this).closest('.block').remove();
updateStepCounts();
}
});
let updateStepCounts = () => $('.block label span').text(i => i + 1);
updateStepCounts();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="optionBox">
<div class="block step">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step <span></span></label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>
<div class="block">
<span class="add">Add Option</span>
</div>
</div>
I removed the div.block surrounding the "add option" span and used .append on the newly added div.block-container element instead of .before to add the next textarea to the bottom of the options container. i think this reads a little better symantically.
Also using string interpolation i am able to insert the total number of div.block + 1 to track the number of textareas visible on the page.
Hope this helps.
$('.add').click(function () {
const numberOfBlocks = $(".block").length;
$(".block-container")
.append(`
<div class="block">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step ${numberOfBlocks + 1}</label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>`
);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="optionBox">
<div class="block-container">
</div>
<span class="add">Add Option</span>
</div>

How hide div if another div is open use javascript

i have div like this use javascript :
<script>
$(document).ready(function(){
$("#btnmsg-1").click(function(){
$(".msgid-1").show();
});
$("#btnmsg-2").click(function(){
$(".msgid-2").show();
});
$("#btnmsg-3").click(function(){
$(".msgid-3").show();
});
$("#btnmsg-4").click(function(){
$(".msgid-4").show();
});
});
</script>
<div>NAME : ABCDEF <button id="btnmsg-1">message</button></div>
<div class="msgid-1" style="display:none;"><textarea></textarea><input type="submit" name="btnsend" value="Send"></div>
<div>NAME : GHIJKL <button id="btnmsg-2">message</button></div>
<div class="msgid-2" style="display:none;"><textarea></textarea><input type="submit" name="btnsend" value="Send"></div>
<div>NAME : MNOPQR <button id="btnmsg-3">message</button></div>
<div class="msgid-3" style="display:none;"><textarea></textarea><input type="submit" name="btnsend" value="Send"></div>
<div>NAME : STUVWX <button id="btnmsg-4">message</button></div>
<div class="msgid-4" style="display:none;"><textarea></textarea><input type="submit" name="btnsend" value="Send"></div>
if i click button id="btnmsg-1" then div class="msgid-1" show, and then i click button id="btnmsg-3" then div class="msgid-3" show but div class="msgid-1" not hide or close,my question how hide the div if another div is open?
Instead of using separate handlers for each, you can use the related positioning of the elements along with classes to group them to show/hide
ie, Add a class like btnmsg to all the buttons and msgedit to all the div's that have to be shown/hidden. Now register a click handler to .btnmsg elements, from your markup the .msgedit element to be shown is the next sibling of the clicked button so show that then hide all other .msgedit elements.
$(document).ready(function() {
var $edits = $('.msgedit')
$(".btnmsg").click(function() {
var $this = $(this).parent().next().show();
$edits.not($this).hide()
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>NAME : ABCDEF
<button class="btnmsg" id="btnmsg-1">message</button>
</div>
<div class="msgid-1 msgedit" style="display:none;">
<textarea></textarea>
<input type="submit" name="btnsend" value="Send" />
</div>
<div>NAME : GHIJKL
<button class="btnmsg" id="btnmsg-2">message</button>
</div>
<div class="msgid-2 msgedit" style="display:none;">
<textarea></textarea>
<input type="submit" name="btnsend" value="Send" />
</div>
<div>NAME : MNOPQR
<button class="btnmsg" id="btnmsg-3">message</button>
</div>
<div class="msgid-3 msgedit" style="display:none;">
<textarea></textarea>
<input type="submit" name="btnsend" value="Send" />
</div>
<div>NAME : STUVWX
<button class="btnmsg" id="btnmsg-4">message</button>
</div>
<div class="msgid-4 msgedit" style="display:none;">
<textarea></textarea>
<input type="submit" name="btnsend" value="Send" />
</div>
Please add same classes to similar elements, and then use this jQuery code instead:
$(document).ready(function(){
$(".btnmsg").click(function(){
$(".msgid").hide();
$(this).parent().next(".msgid").show();
});
});
See the complete DEMO working: https://jsfiddle.net/lmgonzalves/n5f78kqs/
jsBin demo
don't use msgid-1, msgid-2 etc... cause it defeats the purpose of classNames. Use only msg
Same goes for your buttons. Remove the buttons IDs. use Class class="btn"
Don't use inline styles. Use <style> instead or call-to an external stylesheet.
HTML
<div class="btn">
NAME : ABCDEF <button>message</button>
</div>
<div class="msg">
<textarea></textarea>
<input type="submit" name="btnsend" value="Send">
</div>
CSS:
.msg{
display:none;
}
See how more readable is now your code?
jQuery:
var $msg = $(".msg"); // Get all .msg DIVs
$(".btn").on("click", "button", function( e ){
$msg.hide(); // Hide all
$(e.delegateTarget).next().show(); // Show next
});
You can do this by calling hide() on the elements you would like to hide.
For example, you would make the following change:
// Old
$("#btnmsg-1").click(function(){
$(".msgid-1").show();
});
//New
$("#btnmsg-1").click(function(){
$(".msgid-1").show();
$(".msgid-2").hide();
$(".msgid-3").hide();
$(".msgid-4").hide();
});
A cleaner way to do this would be to give all of your messages a "message" class, then your onClick handlers would look like this:
$("#btnmsg-1").click(function(){
$("#message").hide();
$(".msgid-1").show();
});
Hope that helps!

Find closest div with specified class

I have the DOM structure as
<div id="content">
<div id="wrapper">
<input type="text" id="search" />
</div>
</div>
<div class="subContent">
</div>
<div class="subContent">
</div>
I want to select <div class="subContent"> on enter event of input box which is closest to the input box.
$('#search').on('keypress', function(){
$(this).parent().parent().next();
});
Is there a better way to do this ?
$(this).closest('#wrapper').nextAll('.subContent').first()
That way you can change it to use classes
I guess this can help you
$("#search").click(function () {
$(this).closest("div.module").hide();
});
Possible duplicate of
Hiding the closest div with the specified class
Use This:-
<html>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<div id="content">
<div id="wrapper">
<input type="text" id="search" />
<div class="subContent" style = 'background-color:red;'>div1</div>
<div class="subContent" style = 'background-color:red;'>div2</div>
<div class="subContent" style = 'background-color:red;'>div3</div>
</div>
</div>
</html>
<script>
$('#search').on('keypress', function(){
$(this).next().css( "background-color", "blue" );
});
</script>

Categories

Resources