jQuery Click event not attaching to Knockout template - javascript

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/

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>

jQuery not working when I load dynamic component in Angular

I have implemented dynamic components in Angular and whenever a dynamic component is loaded its corresponding jQuery is not working. Same jQuery script is working elsewhere.
This is where my dynamic component loads:
<div class="listing-table-outer" [#myAwesomeAnimation]='state'>
<app-dynamic-question [componentData]="componentData"></app-dynamic-question>
</div>
Below html will be loaded dynamically.
<div class="panel panel-default " >
<div class="panel-body" >
<h1>{{textLabel}}</h1>
<p>{{textHeader}}</p>
<div class="form-inline display-one" role="form">
<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput" placeholder="">
</div>
<div class="learn-more magtop10">
<a> <i class=" glyphicon glyphicon-play"></i> Learn More</a>
</div>
<div class="display_advance">
<div class="well">
<p>{{textFooter}}</p>
</div>
</div>
<div class="bs-component">
Clear
Skip
Continue
</div>
</div>
</div>
I have written this script
$(document).ready(function(){
$('.learn-more').click(function() {
$('.display_advance').slideToggle('1000');
$("i", this).toggleClass(" glyphicon-play glyphicon-triangle-bottom");
});
});
I have checked this script and it is working perfectly elsewhere.
Please let me know why this is happening.
As you already stated yourself, the html is loaded dynamically. That means that this html is not yet there when $(document).ready(function() { ... }) is executed. So you're trying to add a click event to an element that doesn't exist at that moment.For this exact situation there's a thing called event delegation.
Instead of doing
$('.learn-more').on('click', function() { ... });
you would do
$(document).on('click', '.learn-more', function() { ... });
This way any elements below document with class learn-more, now or in the future, will get this click event.

Delegated event doesn't work for elements after sort

I have this HTML element:
<div class="row preview-pictogram">
<div class="column3 col-xs-3" data-index="3">
<span class="index">Spalte <span>3</span></span>
<span class="dec p-2">-</span>
<span class="width">3</span>
<span class="inc p-2">+</span>
</div>
<div class="column1 col-xs-4" data-index="1">
<span class="index">Spalte <span>1</span></span>
<span class="dec p-2">-</span>
<span class="width">4</span>
<span class="inc p-2">+</span>
</div>
<div class="column4 col-xs-3" data-index="4">
<span class="index">Spalte <span>4</span></span>
<span class="dec p-2">-</span>
<span class="width">3</span>
<span class="inc p-2">+</span>
</div>
<div class="column2 col-xs-3" data-index="2">
<span class="index">Spalte <span>2</span></span>
<span class="dec p-2">-</span>
<span class="width">3</span>
<span class="inc p-2">+</span>
</div>
</div>
The is a (delegated) event that listens on the click event of the .dec and .inc classes:
$(".dec, .inc").on("click", this.overlay, function () {
_this.updateWidth(this);
});
This works fine. But at one point I'm sorting the columns by its class name with this code:
ColumnConfigurator.prototype.sortColumns = function (columns) {
var items = $("div", columns).get();
items.sort(sort_by_class);
$(columns).html(items);
};
var sort_by_class = function(a, b) {
return $(a).attr("class").localeCompare($(b).attr("class"));
};
After that happened that delegated event from above doesn't work anymore. I wonder why that happens. I thought the point of delegated events is that they work also for new elements. this.overlay is an element that contains the HTML above and it doesn't change at all.
.on() should be used on the parent.
In your case if this.overlay is a jQuery element that contains the posted HTML then
this.overlay.on("click", ".dec, .inc", function () {
_this.updateWidth(this);
});
EDIT:
After checking #noriMonsta answer I realized that I wrote a wrong code.
I update my answer but I give him all the credit.
I thought the point of delegated events is that they work also for new elements.
Yes, but you are not delegating the events, but attaching them directly to the target elements.
$("div span").on("click", ".dev, .inc", function () {
_this.updateWidth(this);
});
In the code above you are delegating the event to the div elements. As long as the divs exist all the time, your events will trigger even if you alter their inner HTML.
Cleaner, as noriMonsta wrote:
this.overlay.on("click", ".dec, .inc", function () {
_this.updateWidth(this);
});
Because, as you said, this.overlay is an element whose content doens't change never.
In the following snippet you can check how undelegated (or direct) events stop to work after the DOM manipulation:
$(".dec, .inc").on("click", function() {
$("#results").append("not delegated<br>");
});
$(".column").on("click", ".dec, .inc", function() {
$("#results").append("delegated<br>");
});
$("#alterDOM").on("click", function() {
$(".column").html( $(".column").html() );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="column">
<span class="dec">dec</span>
<span class="inc">inc</span>
</div>
<div class="column">
<span class="dec">dec</span>
<span class="inc">inc</span>
</div>
</div>
<button id="alterDOM">Alter DOM</button>
<div id="results"></div>

Show hide separate divs with jQuery

With my inexperience in jQuery, I'm finding the simplest tasks difficult.
What I attempt to do is show/hide certain messages when a certain icon is clicked. This is my HTML:
<div class="container">
<div class="row">
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small" value="measure">
<i class="fa fa-clock-o"></i>
</div>
<div class="pov_title_small">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_large" value="locate">
<i class="fa fa-map-marker"></i>
</div>
<div class="pov_title_large">
LOCATE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small" value="inform">
<i class="fa fa-commenting"></i>
</div>
<div class="pov_title_small">
INFORM
</div>
</div>
<div id="measure" style="display:none" class="pov_description">
<p> Message MESSAGE</p>
</div>
<div id="locate" class="pov_description">
<p> Message LOCATE</p>
</div>
<div id="inform" style="display:none" class="pov_description">
<p> Message INFORM</p>
</div>
</div>
</div>
My JavaScript code that changes the pov icon/title classes works and is currently here:
$('.pov_icon_small , .pov_icon_large').on('click', function () {
$('.pov_icon_large').not($(this)).removeClass('pov_icon_large').addClass('pov_icon_small');
$('.pov_title_large').not($(this).next('div[class^="pov_title_"]')).removeClass('pov_title_large').addClass('pov_title_small');
$(this).toggleClass("pov_icon_small").toggleClass("pov_icon_large");
$(this).next('div[class^="pov_title_"]').toggleClass("pov_title_small").toggleClass("pov_title_large");
});
What I aim to do, is display a certain message (e.g. Message Measure) when the a certain icon pov_icon_small value="measure" is clicked while keeping the others hidden. When the user clicks another icon; that respective message will be displayed and the others will be hidden :
$(document).ready(function(){
$('input[.pov_icon_small]').click(function(){
if($(this).attr("value")=="measure"){
$(".pov_description").not("#measure").hide();
$("#measure").show();
}
if($(this).attr("value")=="locate"){
$(".pov_description").not("#locate").hide();
$("#locate").show();
}
if($(this).attr("value")=="inform"){
$(".pov_description").not("#inform").hide();
$("#inform").show();
}
});
The message-linking JS code doesn't seem to work. Am I doing a small error here? Or should I be preparing the code in a completely different way?
Theres two issues, first your CSS selector input[.pov_icon_small] is not valid. The second is that you are attaching the click function to pov_icon_small which do not have enough height or width for a user to click. I've adjusted the HTML so this binds to the pov_title_small class instead.
You'll want to attach your click function to items have a value, then pass that value as the selector. For pov_title_small I've changed the attribute value to data-value, then the click function uses that to select the ID you want to display. Here is the code:
HTML:
<div class="container">
<div class="row">
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-clock-o"></i>
</div>
<div class="pov_title_small" data-value="measure">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_large">
<i class="fa fa-map-marker"></i>
</div>
<div class="pov_title_large" data-value="locate">
LOCATE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-commenting"></i>
</div>
<div class="pov_title_small" data-value="inform">
INFORM
</div>
</div>
<div id="measure" style="display:none" class="pov_description">
<p> Message MESSAGE</p>
</div>
<div id="locate" style="display: none;" class="pov_description">
<p> Message LOCATE</p>
</div>
<div id="inform" style="display:none" class="pov_description">
<p> Message INFORM</p>
</div>
Javascript:
$(document).ready(function(){
$('[data-value]').bind('click', function(){
$('.pov_description').hide();
$('#'+$(this).attr('data-value')).show();
});
});
You can see it working in this JS Fiddle: http://jsfiddle.net/h97fg75s/
1st : you just need to get a value and convert it to id ..
2nd: like #juvian mentioned $('input[.pov_icon_small]') is not a valid selector
3rd .pov_icon_small its a div not an input so you can use $('div.pov_icon_small') instead
4th: .pov_icon_small doesn't have any value attribute .. .pov_title_small and .pov_title_large those has the value attribute
$(document).ready(function(){
$('div.pov_title_small , div.pov_title_large').click(function(){
var ThisValue = $.trim($(this).attr('value'));
$(".pov_description").not("#"+ThisValue).hide();
$("#"+ThisValue).slideToggle()
});
});
Working Demo
if you need to control it from .pov_icon you have 2 ways
1st: put a value attribute in .pov_icon_small/large
2nd: you can use
$('div.pov_icon_small , div.pov_icon_large').click
and
var ThisValue = $.trim($(this).next('div[class^="pov_title_"]').attr('value'));

how to hide skill div on close class click

how to hide div on object of div click
I am adding jquery path than my html code is here as it is and than after I am apply script to delete label class="main" with span and div class close1
but it's not perform
<label class="main ">
<span class="tag-value">mysql </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">codeigniter </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">ajax </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">jquery </span>
<div class="close1">X</div>
</label>
<script>
$(function(){
$(".close1").click(function(){
$(this).parent(".main").hide();
});
});
</script>
Check that JQ lib. is in the head of you r document, also, you can probably just use .parent()
http://jsfiddle.net/Yx4EU/
<script>
$(function(){
$(".close1").click(function(){
$(this).parent().hide();
});
});
</script>
If this does not work, I suggest adding a fiddle for someone to look at.
Check this out: http://jsfiddle.net/8436y/1/
In this fiddle you will notice I haven't defined the parent, since it is not necessary (in this case).
http://jsfiddle.net/8436y/5/
here I have used the .closest() to define the closest class="main" , which also works ;)

Categories

Resources