on event don't trigger after replaceWith() - javascript

When i click on a <span>, the span changes to an input field
$('table td').on('click', 'span', function() {
var $el = $(this);
var $input = $('<input/>').val($el.text()).attr('class', 'form-control');
$el.replaceWith($input);
var save = function() {
var $p = $ ('<span>').text( $input.val() );
$input.replaceWith($p);
};
$input.one('blur', save).focus();
});
$('input').on('change', function() {
var target = $(this);
$.ajax({
url: 'url',
data: {
value: target.val(),
ruleId: target.data('rule'),
date: target.data('date')
},
type: 'POST',
success: function(data) {
console.log('updated');
}
});
});
After it, i need to catch when the input changes
But it does not trigger the $('input').on('change', function() { function anymore...

Can you try to use this instead
$(document).on('change','input',function(){
// your code here
}
Hope the helps

bind event to document and not to element will solve your problem.
$(document).on('change', '.item', function(event) {
refer jQuery doc

Related

how to bind event to element after generateing

I have this script :
$(window).load(function () {
$(document).on('click', '.btn-delete-confirm', function () {...});
});
and I have this element :
<div id="attachments"></div>
and I have this script to load some html :
$(document).on('click', '.nav-tabs li a[href="#attach"]', function () {
$.ajax({
url: loadAttachmentsURL,
data: { equipmentId: equipmentId },
success: function (data) {
$("#attachments").html(data);
}
});
});
in my result from ajax I have some button that have .btn-delete-confirm class but when clicked on them nothing happen .
the sample of result like this :
<td><a data-id="73b2db39-199c-845c-8807-6c6164d2d97d" data-url="/Admin/EquipmentAttachment/Delete" class="btn-delete-confirm btn">Delete</a></td>
how can I resolve this ?
one way will be by attaching click event after html is set:
$(document).on('click', '.nav-tabs li a[href="#attach"]', function() {
var equipmentId = "?";
var loadAttachmentsURL = "/url";
$.ajax({
url: loadAttachmentsURL,
data: {
equipmentId: equipmentId
},
success: function(data) {
$("#attachments").html(data);
$(".btn-delete-confirm").click(function() {
alert("click!");
});
}
});
});
another will be attaching the click event to the document context:
$(document).on('click', ".btn-delete-confirm", function() {
alert("click!");
});
$(document).on('click', '.nav-tabs li a[href="#attach"]', function() {
var equipmentId = "?";
var loadAttachmentsURL = "/url";
$.ajax({
url: loadAttachmentsURL,
data: {
equipmentId: equipmentId
},
success: function(data) {
$("#attachments").html(data);
}
});
});
You are trying to add an eventlistener to something that isnt there yet.
This will result in an error, and the event wont fire again.
So try to add the listener AFTER the ajax import.
$(document).on('click', '.nav-tabs li a[href="#attach"]', function () {
$.ajax({
url: loadAttachmentsURL,
data: { equipmentId: equipmentId },
success: function (data) {
$('#attachments').html(data);
$('.btn-delete-confirm').on('click', function () {...});
}
});
});
Though .delegate() method is deprecated in jquery-3.0, its description is still worth to have a look:
Attach a handler to one or more events for all elements that match the
selector, now or in the future, based on a specific set of root
elements.
Exmaple:
// jQuery 1.4.3+
$( elements ).delegate( selector, events, data, handler );
// jQuery 1.7+
$( elements ).on( events, selector, data, handler );
Using document as a root element is not a big problem, but have you tried #attachments ?
$(window).load(function () {
$("#attachments").on('click', '.btn-delete-confirm', function () {...});
});

jQuery get id of element that triggered event from nested function

How do I get the id of the ".item" element from inside the getJSON function?
jQuery(document).ready(function() {
$(".item").tooltip({
items: "div",
content: function(callback) {
$.getJSON('mydata.json', function(data) {
var country = event.target.id;
console.log(country);
});
}
});
});
I've seen an explanation here, but I'm not sure how to pass the event(s) in my case.
In your content callback, this refers to the element whose tooltip is being invoked, so you could use this.id to get the id of the current element
jQuery(function ($) {
$(".item").tooltip({
items: "div",
content: function (callback) {
var el = this;
$.getJSON('mydata.json', function (data) {
var country = el.id;
console.log(country);
});
}
});
});
This is how I would do it
jQuery(document).ready(function() {
$(".item").tooltip({
items: "div",
content: function(callback, this) {
var $obj = $(this);
$.getJSON('mydata.json', function(data, $obj) {
var country = event.target.id;
console.log(country);
console.log($obj.attr("id"));
});
}
});
});
Try to use the
$(this)
to access the current element, then you can access its ID by using
$(this).attr('id')
See http://jqueryui.com/tooltip/#custom-content

How do i prevent my .done handler from being called multiple times?

I have this JQuery expression where i push a button, get some HTML from the server and then append it to a DOM node in my document:
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").click(function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data); //find better way of doing this
});
});
});
</script>
I have multiple ".addButton" buttons on my web site. The problem im experiencing is that after multiple clicks on the buttons my .done handler is being called multiple times.
My guess is that i have a list of event handlers that are being executed, I cant understand where / why this is done or how I prevent it from happening.
The problem is not taht you do the request is done more then once rathern then it calls done after its done.. you can keep the state in data object::
$(document).ready(function () {
var posting = false;
$(".addbutton").data("done", false).click(function () {
var addbuttonNode = $(this);
if (!addbuttonNode.data("done")) {
addbuttonNode.data("done", true);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data);
});
}
});
});
I would do the following:
$(".addbutton").click(function () {
var addbuttonNode = $(this);
addbuttonNode.attr('disabled',true);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data); //find better way of doing this
addbuttonNode.attr('disabled',false);
});
});
You could check it for any request pending:
$(document).ready(function () {
$(".addbutton").click(function () {
// if any request pending, return {undefined}
if ($.active) return;
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", {
id: '#guid'
}).done(function (data) {
// instead of .next().next()
$(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this
// or .parent().find('selector')
});
});
});
If you wish instead each button to be clickable only once, then use jQuery .one() method:
$(document).ready(function () {
$(".addbutton").one('click', function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", {
id: '#guid'
}).done(function (data) {
// instead of .next().next()
$(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this
// or .parent().find('selector')
});
});
});
Try to use bind, and unbind functions for the event handling. Then You can unbind the click function after it was executed once.
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").bind('click',function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' }).done(function (data) {
addbuttonNode.next().next().append(data);
});
addbuttonNode.unbind('click');
});
});
</script>
Another way of doing nearly the same, I think this should be better:
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").each(function(){
$(this).bind('click',function () {
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' }).done(function (data) {
addbuttonNode.next().next().append(data);
});
$(this).unbind('click');
});
});
});
</script>
I haven't tried it yet, but it should work, try it! :)
You can also set up a class or data attribute to check if the button was already clicked. You can then exit from the script like if($(this).hasClass('clicked')) { return; } or something...

jQuery replace DIV to INPUT and vice versa

I am implementing an inline edit kind of functionality.
So initially a date label (say 05/01/1999) will be displayed and on click of it, it would be replaced with an input box with the same value (05/01/1999). Now user can select any date using the jQuery UI date picker and on select of any date (say 05/01/2005), I would again show a label (05/01/2005)
Currently I am using the below code;
$(document).on("click",".editableDateTxt", function () {
var currElmModelAttr = $(this).attr('data-model-attr');
var input = $('<input />', {'type': 'text','name':currElmModelAttr, 'style':'width:100px','class':'datePicker', 'value': $(this).html()});
var parent = $(this).parent();
parent.append(input);
$(this).remove();
input.datepicker().focus();
});
What is the best way to implement the same?
Now here is the crucial point: I am using jQuery UI datepicker, which uses the jQuery data() internally. So I do not want to loose it while jumping from div > input and vice versa.
How can I modify the above code to consider that the jQuery data() info stays?
Updated code
var MyView = BaseModalView.extend({
el: "#myModalContainer",
initialize: function() {
var self = this;
},
render: function() {
var self = this,
$el = $(self.el);
$el.find(".datePicker").datepicker();
self.initEventListeners();
},
initEventListeners: function() {
var self = this,
$el = $(self.el);
var $this;
$(document).on("click", ".editableDateTxt", function () {
var currElmModelId = $(this).attr('data-model-id');
var currElmModelAttr = $(this).attr('data-model-attr');
$this = $(this);
var input = $('<input />', {
'type': 'text',
'name': currElmModelAttr,
'data-model-id': currElmModelId,
'data-model-attr': currElmModelAttr,
'style': 'width:100px',
'class': 'datePicker',
'value': $(this).text()
});
$(this).replaceWith(input);
input.datepicker({
onSelect: function (date) {
$this.text(date);
input.replaceWith($this);
// input.blur();
}
}).focus();
$(document).on("blur change", "input", function () {
setTimeout(function () {
var value = input.val();
$this.text(value);
input.replaceWith($this);
}, 100);
});
});
}
You can do that better swapping with replaceWith()
$(document).on("click", ".editableDateTxt", function () {
var currElmModelAttr = $(this).attr('data-model-attr');
var $this = $(this);
var input = $('<input />', {
'type': 'text',
'name': currElmModelAttr,
'style': 'width:100px',
'class': 'datePicker',
'value': $(this).text()
});
$(this).replaceWith(input);
input.datepicker({
onSelect: function (date) {
$this.text(date);
input.replaceWith($this);
console.log(date);
}
})
});
Updated Demo
Also, I suggest, you hide/show the elements, which would be better in this case, instead of creating and swapping elements every time.
Here is a simpler version, as suggested by #Shaunak D, using the basic hide() and show().
^_^ jsfiddle sample
Html code:
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<div id="lbl"></div>
<input type='text' id="date-picker" />
Js codes:
$('#lbl').html('2014-01-01');
$('#date-picker').hide();
$('#date-picker').datepicker({
onSelect: function(date) {
$('#lbl').html(date);
$(this).hide();
$('#lbl').show();
}
});
$('#lbl').click(function(){
//alert();
$(this).hide();
$('#date-picker').show();
});
The best way to do this is to use a readonly input field with the date picker. Is there any reason behind using the div and replacing with input field?

Twitter bootstrap:Popop are not showing up on first click but show up on second click

Here is my code. Please help me
$(document).ready(function(){
$(document).delegate(".view","click",function(){
var id = $(this).attr("id");
alert(id);
$("#"+id).popover({
html : true,
content: function() {
return $("#"+id+"tt").html();
},
title: function() {
return $('#popoverTitle').html();
}
});
alert("thisa");
});
});
Try replacing the function .delegate() by .on(), this function has been superseded in the last versions of Jquery.
jQuery 1.4.3+
$( elements ).delegate( selector, events, data, handler );
jQuery 1.7+
$( elements ).on( events, selector, data, handler );
The code would be:
$(document).ready(function(){
$(document).on("click",".view",function(){
var id = $(this).attr("id");
alert(id);
$("#"+id).popover({
html : true,
content: function() {
return $("#"+id+"tt").html();
},
title: function() {
return $('#popoverTitle').html();
}
});
alert("thisa");
});
});
Try doing this way..
$('.view')
.popover({trigger: 'manual'})
.click(function() {
if($(this).hasClass('pop')) {
$(this)
.popover('hide')
.removeClass('pop');
} else {
var id = $(this).attr("id");
var title = $('#popoverTitle').html();
var response = $("#"+id+"tt").html();
$(this)
.attr({'title': title, 'data-content': response})
.popover('show')
.addClass('pop');
}
});

Categories

Resources