Select an element's contents without certain descendants - javascript

I am trying to select the parent element .search-result-item and skip the h3 tag in it and btn-grey class from selection. my code is here
$('div.search-result-item:not(h3 .btn-grey)').click(function(e){
console.log('1');
});
but it selects h3 and btn-grey also what i doing wrong?
my HTML is here
<div data-id="52c53ccfaea0837f318b470c" class="search-result-item ">
<div>
<div class="search_result">
<div class="picture"><img width="195" height="130" src="/images/not_available.png" alt=""></div>
<div class="info">
<h3>
<a href="/course-detail/masters/management-with-human-resource-management/full-time/university-of-chester-faculty-of-business-enterprise-and-lifelong-learning/uk/52c53ccfaea0837f318b470c" title="Management with Human Resource Management">
Management with Human Resource Management </a>
</h3>
<p>
<strong>Entry Requirements: </strong>IELTS : 6.5
</p>
<a data-id="52c53ccfaea0837f318b470c" class="request-info" title="Request Info">
<button class="btn btn-yellow">Request Info</button>
</a>
<a class="btn btn-grey" href="/course-detail/masters/management-with-human-resource-management/full-time/university-of-chester-faculty-of-business-enterprise-and-lifelong-learning/uk/52c53ccfaea0837f318b470c" title="Course Details">
Course Details
</a>
</div>
</div><!-- .search_result -->
</div>
</div>

Try this instead. Do the filtering after the event has fired by checking what element fired the event:
$('div.search-result-item').click(function(e){
if (!$(e.target).is('h3,.btn-grey')) {
console.log('1');
}
});

You're misinterpreting what is going on. When you bind an even to a parent element, all events that happen on child elements will bubble to the parent and trigger the event on the parent. Using :not() will not change that fact. You instead need to test the event.target inside the event handler to ensure that the target element was not one of the elements that you didn't want to trigger the event.
$('div.search-result-item').click(function(e){
if ( !$(e.target).is("h3,.btn-grey") ) {
console.log('1');
}
});

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>

Correct selector specification for element.closest() DOM method

I'm trying to get hold of the outer div's id from the innermost button element in the following HTML:
<div id="menu_level_0" class="menu_level">
<div class="editor">
<div class="ui_details">
<div class="dialog_buttons">
<button class="ui_btn" type="button">OK</button>
</div>
</div>
</div>
</div>
Dumping e.target from the button's event handler callback fn to the console returns the correct button element.
But why does calling
e.target.closest(".menu_level");
from the same callback give me null?
Try to console.log your e.target. It's probably another element, not your button.
// proof that, button.closest() works:
console.log(document.querySelector("button").closest('.menu_level'))
<div id="menu_level_0" class="menu_level">
<div class="editor">
<div class="ui_details">
<div class="dialog_buttons">
<!-- this in onclick="" is the button element -->
<button class="ui_btn" type="button" onclick="console.log(this.closest('.menu_level'))">OK</button>
</div>
</div>
</div>
</div>

How to add to onclick function inside a list i.e<li onclick=""><button onclick=""></button></li>

Basically, I want to create a sidebar in which there will be many contacts.
Each contact will be there inside a list.
There will be two onclick functions inside a list.
In list two onclick functions are:
1st onclick- After clicking on the list<li onclick=""></li>It should open another sidebar(I have created it).
2nd onclick-This onclick is inside <button> i.e <li onclick=""><button onclick=""></button></li>After clicking on this onclick a new chatbox(almost done) should open.
But in my case whenever I click on any list inside the sidebar, it display's both sidebar and chatbox simultaneously.
I want both onclick functions to work separately.
html code:
<ul class="list mat-ripple">
<li ><img src="img1.png"><span class="name"> abc</span>
<button class="btn-link" style="margin-left:65px;color:green;font-size:15px;">
<b>
<i class="fa fa-comments" aria-hidden="true"> </i>
</b>
</button>
</li>
<li>
<img src="img1.png"><span class="name"> abc</span>
<button id="clickme" style="margin-left:65px;color:green;font-size:15px;">
<b>
<i class="fa fa-comments" aria-hidden="true"> </i>
</b>
</button>
</li>
<li onclick="toggle_div_fun('sectiontohide');">
<img src="img1.png"><span class="name"> abc</span>
<button onclick="showFrontLayer();" style="margin-left:65px;color:green;font-size:15px;">
<b>
<i class="fa fa-comments" aria-hidden="true"> </i>
</b>
</button>
</li>
</b>
</button>
</li>
<li onclick="toggle_div_fun('sectiontohide');">
<img src="img1.png"><span class="name"> abc</span>
<button onclick="showFrontLayer();" style="margin-left:65px;color:green;font-size:15px;">
<b>
<i class="fa fa-comments" aria-hidden="true"> </i>
</b>
</button>
</li>
</ul>
1st oclick function inside list needs to target below code( 2nd sidebar that needs to toggle using onclick function):
Contact List
Sachin Sir
Sachin Sir
Sachin Sir
Sachin Sir
After 2nd Onclick function inside the button is targeting the below code(toggle):
<div id="div1">
<div id="bg_mask">
<div id="frontlayer"><br/><br/><img src="https://png.icons8.com/go-back/androidL/24" title="Go Back" width="24" height="24" onclick="hideFrontLayer();" style="margin-top:-60px;position:absolute;margin-left:-20px;">
<div id='result'></div>
<div class='chatcontrols'>
<form method="post" onsubmit="return submitchat();">
<input type='text' name='chat' id='chatbox' autocomplete="off" placeholder="ENTER CHAT HERE" />
<input type='submit' name='send' id='send' class='btn btn-send' value='Send' />
<input type='button' name='clear' class='btn btn-clear' id='clear' value='X' title="Clear Chat" />
</form>
</div>
</div>
</div>
</div>
javascript functions:
<script>
function showFrontLayer() {
document.getElementById('bg_mask').style.visibility='visible';
document.getElementById('frontlayer').style.visibility='visible';
}
function hideFrontLayer() {
document.getElementById('bg_mask').style.visibility='hidden';
document.getElementById('frontlayer').style.visibility='hidden';
}
</script>
Is there any other code to toggle 2 targeted elements(sidebar and chatbox)?
Both should be done inside a list.
I'm guessing what you would need is:
event.stopPropagation();
This would prevent the event from button (which is inside) propagating to it's parent.
$('#inner').click(event=>{
event.stopPropagation();
$('#other').toggle();
});
$('#outer').click(event=>{
console.log("outer");
});
#outer {
background-color: blue;
width: 100px;
height: 100px;
padding-top: 50px;
}
#other {
background-color: red;
width: 100px;
height: 100px;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outer">
<button id="inner">Toggle Visibility</button>
</div>
<div id="other">
This div has to be toggled on click of the button
</div>
Given that you've tagged this with jQuery, I'm going to assume you have jQuery available.
You can attach click events with jQuery, $('button').click(function(){...}).
So what you'd probably want to do is attach a click event that checks the state for certain features and, depending on those features, does different things.
For example, you could have it check for the class 'clicked', and if it doesn't have the class 'clicked', expand your second sidebar and add the class 'clicked', and if it does have the class 'clicked' you do the second click function you want it to do.
Of course depending on the specifics of the desired behavior you may want to check for and change state in a different way than adding the class 'clicked', but that's just one approach.
you can simply use onclick event using jquery like this
$(document).ready(function(){
$('button').click(function(){
<!---Your Code-->
});
});
the problem is about understanding event handling in Javascript. You have a list element with an click event. This List Element contains a button, which has a click event too. This means, when you click on the list item you trigger 2 events (that's why you see the two divs). I think you can solve this by using event.stopPropagation() in your showFrontLayer and HideFrontLayer functions, in order to prevent the event target from bubbeling to the list item.
function showFrontLayer(evt) {
evt.stopPropagation();
document.getElementById('bg_mask').style.visibility='visible';
document.getElementById('frontlayer').style.visibility='visible';
}
function hideFrontLayer(evt) {
evt.stopPropagation();
document.getElementById('bg_mask').style.visibility='hidden';
document.getElementById('frontlayer').style.visibility='hidden';
}
For more infos about event capturing and bubbeling see: https://javascript.info/bubbling-and-capturing

Onclick needs to ignore parent href

I have a question, and I doubt it is possible. the question is as follows:
How can my onclick be executed without the anchor tag being activated?
The onclick will show the disclaimer message.
Sample code:
<a href="websiteurl.com">
<div id="container">
<div class="content-wrapper">
<div class="image">
<img src="...."/>
</div>
<div class="disclaimer-message">disclaimer text</div>
<div class="text-wrapper">
<p>Sample text</p><span onclick="this.parentNode.querySelector('div.disclaimer-message').classList.toggle('disclaimer-show');">?</span>
</div>
</div>
</div>
</a>
Thanks in advance :)
I would write a dedicated function to handle your click.
<span onclick="clickHandler">...</span>
See my click handler below. If you want to prevent the default behavior of a javascript event, which in the case of a click event, you could use e.preventDefault() and e.stopPropagation().
function clickHandler(e) {
e.preventDefault()
e.stopPropagation()
}
This will prevent the browser from following it's default behavior which is to follow that link redirect. e.stopPropagation() will stop the event from bubbling up to its parent, which in this case is the anchor element.
<a href="http://www.websiteurl.com">
<p>Sample text<p><span onclick="alert('hello');return false">try me</span>
</a>
Note that when using this approach you should always wrap your script in a try catch block because if your code throws an error the parent link will be clicked.
<a href="http://www.websiteurl.com">
<p>Sample text<p><span onclick="try {alert('hello'); } catch(e) {}; return false">try me</span>
</a>
To prevent the anchor link being invoked on click event :
Assign the click listener on the highest parent possible (right after anchor tag)
Prevent the event bubbling up to the anchor by invoking its preventDefault method
var container = document.querySelector('#container');
container.addEventListener('click', function(event) {
event.preventDefault();
var msgBlock = container.querySelector('.disclaimer-message');
msgBlock.classList.toggle('disclaimer-show');
msgBlock.classList.toggle('hide');
});
a {
text-decoration: none;
}
.disclaimer-show {
color: red;
font-weight: bold;
}
.hide {
display: none;
}
<a href="websiteurl.com">
<div id="container">
<div class="content-wrapper">
<div class="image">
<img src="...." />
</div>
<div class="disclaimer-message hide">disclaimer text</div>
<div class="text-wrapper">
<p>Sample text</p><span>?</span>
</div>
</div>
</div>
</a>
<a href="websiteurl.com">
<p>Sample text<p>
</a>
<span onclick="this.parentNode.querySelector('div.class-message').classList.toggle('class-show');">try me</span>
Thats the way you should do it as there is no point to hold span tag inside of anchor , "this.parentNode" targets anchor element ,so querySelector won't work unless u got ur div inside of anchor

jQuery Click event not attaching to Knockout template

I have a block of code that is attached to a jQuery click event. Here's the element:
<!-- Profiles -->
<div class="profiles">
<h1>Profiles</h1>
<div class="profile">
<div class="name">
<input type="text" maxlength="14" value="Default" />
<span class="rename">q</span>
</div>
<div class="controls">
<span class="edit">EDIT</span>
<span class="duplicate">COPY</span>
<span class="delete default">J</span>
<div class="alert-box">
<p>Are you sure you want to delete this profile?</p>
<div>Y</div>
<div>N</div>
</div>
</div>
<div class="saved">
<span class="cancel-button">Cancel</span><span class="save-button">Save</span>
</div>
</div>
</div>
When the item is selected, it becomes available for editing. Here's the event listener:
$('.rename').click(function () {
$('.selected .rename').fadeIn(80);
$(this).fadeOut(80);
$(this).parent().addClass('selected');
});
There's another event that listens for a click anywhere else on the page to deselect the item being edited:
$(document).click(function () {
$(".selected .rename").fadeIn(80);
$('.name').removeClass('selected');
});
When it is clicked on, it should be selected to allow for editing. When I move the code from the profile into a knockout template, it doesn't listen to the click event anymore. When I inspect the Event Listeners in Chrome's tools, the listener is nowhere to be found. Here is what my template looks like:
<div class="profiles">
<h1>Profiles</h1>
<div data-bind="template: { name: 'profilestempl', foreach: $root.profiles }"></div>
</div>
<script type="text/html" id="profilestempl">
<div class="profile">
<div class="name">
<input type="text" maxlength="14" data-bind="value: name" />
<span class="rename">q</span>
</div>
<div class="controls">
<span class="edit">EDIT</span>
<span class="duplicate">COPY</span>
<span class="delete">J</span>
<div class="alert-box">
<p>Are you sure you want to delete this profile?</p>
<div>N</div><div>Y</div>
</div>
</div>
<div class="saved">
<span class="cancel-button">Cancel</span><span class="save-button">Save</span>
</div>
</div>
</script>
Can someone explain to me why the event listener no longer works on the dynamically added elements? I would also like help in solving this problem. Thanks!
You have to add click event listener on the outer element which is always visible (since it doesn't work on hidden elements). And then add other selector for template code (which is hidden)
Sample code would be:
function addClickEventToCloseButton(){
$("#outerAlwaysVisible").on('click','#templateHiddenInitially',function(){
alert('works')
});
}
If you want the handler to work on elements that will be created in the future you should use on : http://api.jquery.com/on/

Categories

Resources