I have a page where I return users posts, these posts can be commented on the fly using some jquery code, after a new comment is posted I insert the new comment under the post along with a Delete button. The problem is the Delete button doesn't work on the newly inserted element unless I reload the page. I read that the solution is using the .on() method however I am a little confused re how to implement this.
I have one function that updates the post part with the newly inserted comment and this is the function that deletes the comment:
$(document).ready(function () {
$("button[id*='deletecmnt_']").click(function () {
var id = this.id.replace('deletecmnt_', '');
var comment_card_id = ('#comment_' + id);
var token = $(this).data('token');
$.ajax({
url: '../comment/' + id,
type: 'post',
data: {_method: 'delete', _token: token},
success: function () {
// Checks for display of comment card and removes it
if ($(comment_card_id).is(":visible")) {
$(comment_card_id).fadeOut("fast");
}
}
})
})
});
I don't understand what needs to be changed here and how.
You need to use event delegation for elements added dynamically. In your .on() method, you need to add the selector that you want the handler attached to after it's created.
$(document).ready(function(){
$("body").on("click", "button[id*='deletecmnt_']", function () {
// codes
}
});
This will listen for clicks on elements not yet created that match your selector. Here's the JQuery API doc page for more info: http://api.jquery.com/on/
Related
I have a problem with my script.
In my table, every row has a url link which open modal window with email input to change this email without refresh page.
Script is ok if you change only one row. If I change second, third, etc row, every values changed by last one.
If I refresh page (F5) - script works perfectly.
Any helps ? Thanks a lot.
$(document).ready(function() {
var table = $('#example').DataTable();
$('#example tbody').on('click', 'a', function () {
var row = $(this).closest('tr[role="row"]');
var data = table.row(row).data();
$("#myModal").modal("show");
$("#email").val(data[0]);
$("#ulozit").click(function(){
var novy_email = $("#email").val();
$.ajax
({
method: "POST",
url: "action_admin.php?action=uprava_emailu",
data: { novy_email:novy_email, id:data[3] },
success: function(data)
{
table.ajax.reload();
$("#myModal").modal("hide");
}
})
});
});
});
You have nested onClick handlers.
The second handler is added every time the first handler is called. The jQuery event model allows multiple handlers on one element, therefore a later handler does not override an older handler. The handlers will execute in the order in which they were bound.
In short: Do not nest your handlers.
I have a message box. When I click on submit it only works for the first time. Are the onclick events removed?
The code is like this :-
$("#message-box #send-message-btn").click(function(){
var messageText=$("#message-box #textarea").val();
$.get("getUserName",function(username,status){
$.get("getUserByUserName?username="+username,function(user,status){
var sentFrom=user.userId;
var today=new Date();
var today=getDateInFormat(today);
today=today+"Z";
var time=today;
var ajaxData= {
messageTypeId,
messageText,
messageReference : referenceId,
context,
sentFrom,
time
}
$.ajax({
url:"/addMessages",
data: JSON.stringify(ajaxData),
type: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
success : function(data) {
console.log("inside sucess of add messages");
$.get("/getMessagesByTypeContextReference?referenceId="+referenceId+"&&context="+context+"&&messageTypeId="+messageTypeId,function(messages,status){
var gets=[];
$.each(messages,function(i,message){
message.timestamp=getDateInFormat(new Date(message.time).addHours(-8));
gets.push($.get("getUserByUserId?userId="+message.sentFrom,function(user,status){
message.sentFromName=user.firstName+' '+user.lastName;
}));
})
$.when.apply($,gets).then(function(){
rowData.messages=messages;
$("#message-box").html('');
callHandlebars("#message-box","message-form-template",[],rowData);
})
})
},
error : function (exception) {
console.log("exception :"+exception);
}
});
})
})
})
After submitting the message in my database I am reloading the message box html. Is that removing the event handler? What is the solution?
You attach the click with this selector $("#message-box #send-message-btn") but in your success callback it looks like you reload everything in message-box so the button send-message-btn would be replaced and any attached events lost. You can use event delegation to keep those events attached or simply reattach them after replacing the HTML of message-box.
To leave them attached with delegation try replacing:
$("#message-box #send-message-btn").click(function(){
with:
$("#message-box").on('click', '#send-message-btn', function () {
This attaches the event to message-box and because of event bubbling allows message-box to pass the event back to send-message-btn even after he has been replaced in the DOM.
You are reloading the whole div on success. This makes you lose the click event, so it will not trigger again.
You can fix it by:
Re-adding the event after the div is reloaded (tested, but not really beautiful code)
Use on http://api.jquery.com/on/ instead of click (not tested, last time I used something like this was called "live", but it seems now is deprecated)
I have function:
function delMeh() {
console.log('prolazi klik');
var did = $(this).attr('data-value');
$.ajax({
url: "delTmeh.php",
type: "POST",
async: true,
data: { vrednostid:did}, //your form data to post goes here as a json object
dataType: "html",
success: function(data) {
$('#tablemeh').dataTable().fnDestroy();
drawMeh();
},
error: function(data) {
console.log(data);
}
});
}
and HTML:
<i data-value="32" onclick="delMeh();" class="fa fa-times delMeh"></i>
SO, on click I need to delete row 32 from database, but how I can get data-value of clicked element...
I try with:var did = $(this).attr('data-value'); inside delMeh() function but dont work.
How to get attr data-value of clicked element when call function like I need to do?
Why do u need the data value, when using a inline function click?
You could directly pass the value as a parameter to the function.
function delMeh(value) {
// do your stuff
}
<i onclick="delMeh(32);" class="fa fa-times delMeh"></i>
This would work good, but I seriously doubt the usage of this in a inline function call, as it could be used when a element's event is binded using jquery event listener.
Then you can use $(this).data('value')
I hope this helps.
function delMeh() {
console.log('prolazi klik');
var did = $(this).attr('data-value');
alert(did);
}
$(".delMeh.fa.fa-times").click(delMeh);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<i data-value="32" class="fa fa-times delMeh">test</i>
This uses the more standard addEventListener. AddEventListener allows for multiple events of the same type and passes the this argument to the function. It also prevents the overwriting of the inline events.
Send the element on the onclick method
onclick="delMeh(this);"
and receive the element on your function
function delMeh(element) {
// than you can get the value with
var did = $(element).attr('data-value');
// or
var did = $(element).data('value');
}
Or you could do it the jQuery way, by binding the on click handler on your html elements like this:
$(".delMeh").click(function() {
// here you could use this
var did = $(this).attr('data-value');
});
where you won't need to set the inline onclick attribute on each element.
Check this question to understand the difference between .attr vs. .data.
You really should avoid using inline event handlers with jQuery as others mention. The reason include getting new jQuery bubbling functionality and not separating the event registration code from the event handling code.
It sounds like your elements are created dynamically, which is probably why your previous attempt at using .on failed (mentioned in your comments). That also means none of the other suggestions will work as-is.
Instead use a single delegated event handler, attached to a non-changing ancestor element. document is the default if nothing else is closer/convenient. In your case the better element might be $('#tablemeh').on(..., but I would need to see a sample of your page's HTML.
A delegated event handler listens for the event (in this case click) to bubble up to the element, then it applies the jQuery selector. Then it calls your function only on the matching elements that caused the event. That means the elements only have to exist/match at event time.
Also, use data as a short-cut to fetch attributes with a data- prefix.
So instead of your existing code, just use something like this:
$(document).on('click', '.delMeh', function(){
var did = $(this).data('value');
$.ajax({
url: "delTmeh.php",
type: "POST",
async: true,
data: { vrednostid: did },
dataType: "html",
success: function(data) {
$('#tablemeh').dataTable().fnDestroy();
drawMeh();
},
error: function(data) {
console.log(data);
}
});
});
So I have a page that loads the data into the page through the following ajax function.
$(document).ready(function(){
function loadData(page){
$.ajax
({
type: "POST",
url: "inc/load_data.php",
data: "p="+page+"XXXXXXXXXXX",
success: function(msg)
{
//alert(msg);
$("#container").ajaxComplete(function(event, request, settings)
{
$("#container").html(msg);
//**MODIFIED CODE
$(document).delegate('a.vote_up','click', f_vote_up);
});
}
});
}
});
//Loaded Message
$msg.='<span class="vote_buttons" id="vote_buttons'.$row['id'].'">
</span>';
The message that is loaded has some links that need to work with a another Ajax function(given below), which is apparently not working. The second function(below) is loaded before the data is loaded into the page. I suspect, may be since this function is loaded way before the data is loaded, the second function is not recognizing the click on vote_up. Is there any way to fix it??? I'm not too familiar with AJAX, I would really appreciate some help.. Thank you
$(function(){
$("a.vote_up").click(function(){
//get the id
alert("Hi");
//REST OF THE CODE
}
//***NEW FUNCTION
function f_vote_up(){
//get the id
the_id = $(this).attr('id');
//REST OF THE CODE
$("span#vote_buttons"+the_id).html("Hello, Testing Response!");
alert("End of Func!"); // <
}
When you call that second function, it's only grabbing all the a.vote_up elements that currently exist on the page. When you add more links to the page later on, they don't know to listen for the click.
You can do one of two things to fix this:
Add the click listener to each new link when you add it to the DOM. But this is a bit of work, because you'd have to change how your AJAX function builds the links, and you'd have to turn that click-listener-assigning function into something standalone that you could use at any time.
Instead of doing using the click method, use the delegate method instead:
$(document).delegate('a.vote_up', 'click', function () { ... });
More info on event delegation with jQuery.
you should bind your click event after you load the html
$.ajax
({
type: "POST",
url: "inc/load_data.php",
data: "p="+page+"XXXXXXXXXXX",
success: function(msg)
{
//alert(msg);
$("#container").ajaxComplete(function(event, request, settings)
{
$("#container").html(msg);
$("a.vote_up").click(function(){
//get the id
alert("Hi");
//REST OF THE CODE
});
});
}
});
You can use the live function to bind an event to dynamically created elements, i.e.:
$("a.vote_up").live('click', function(){
//get the id
alert("Hi");
});
http://api.jquery.com/live/
This will effectively bind this click event to all elements which match the a.vote_up selector, now and in the future.
I working with some ajax at the moment, the result of a successful ajax result is that some more content is add to the page on the fly. My problem is that is added on the fly it looks like I cannot attach any events to the elements that are added.
The flow of what happens is that the user selects an option from a drop-down list, the value of that selection is sent to a PHP function which then returns some more HTML to the page which is appended to a div on the page.
I know there is a problem with the elements not existing on domReady as I run a length() check and it confirms they don't 'exist' on the page.
Is there away around this so that I can run click event on the HTML that gets added after the first ajax request has returned successfully?
$(document).ready(function() {
//customise the select menus
$('#customselector').SelectCustomizer();;
$('.career_select .selectitems').click(function(){
var selectedCareer = $(this).attr('title');
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
}
});
});
$('#grade_choice_options .selectitems').click(function(){
var selectedGrade = $('#grade_choice_customselect').val();
alert(selectedGrade);
})
});
Use live() instead of click() directly:
$('.career_select .selectitems').live('click', function() { ....
live() essentially wires up any new elements that match that are added subsequently.
Try using this plugin :
http://brandonaaron.net/code/livequery/docs : Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.