Script doesn't take effect on element recently created [duplicate] - javascript

This question already has answers here:
jQuery how to bind onclick event to dynamically added HTML element [duplicate]
(9 answers)
Closed 10 years ago.
I have created two scripts for managing a list. One for adding a li element in the page and saving it to the database, and the other one, for removing it. The fact is, when I create a li element, the second script (remove one), doesn't take effect on it (I must update the page to remove it). How can I make it work?
I leave you both scripts:
Adding:
function afegir() {
var fnom=document.getElementById('compranom').value;
var fnum=document.getElementById('quantitat').value;
$.ajax({
data: {
"nom": fnom,
"num":fnum
},
url: 'afegir.php',
type: 'post',
beforeSend: function () {
},
success: function (response) {
if(response!="-1") {
$('.llista').append('<li value="'+fnum+'" id="'+response+'" >'+fnom+'</li>');
}
else{
alert('Error');
}
}
});
}
Removing:
$(document).ready(function(){
$(".list li").click(function() {
var fid=$(this).attr('id');
$.ajax({
data: {
"id": fid
},
url: 'treure.php',
type: 'post',
beforeSend: function () {
},
success: function (response) {
if(response=="si") {
$("#"+fid+"").remove();
}
else{
alert('Error');
}
}
});
});
});
Thank you for your help.

use on event delegation for this..
$(document).ready(function(){
$(".list").on('click','li',function() {
var fid=$(this).attr('id');
$.ajax({
data: {
"id": fid
},
url: 'treure.php',
type: 'post',
beforeSend: function () {
},
success: function (response) {
if(response=="si") {
$("#"+fid+"").remove();
}
else{
alert('Error');
}
}
});
});
});
link here to read more about on delegated event

Can use live() for getting to newly created elements: http://api.jquery.com/live/
Description: Attach an event handler for all elements which match the current selector, now and in the future.

Related

Multiple instance jquery function with bootstrap modal

I am trying to run jquery function once modal is shown, but I close modal by clicking on the side or one close button and then open I find multiple instances of the inner function running.
<script type="text/javascript">
$(document).ready(function () {
$(".test").click(function () {
var cid = $(this).attr('cid');
$("#post-form").one('submit',function (event){
event.preventDefault();
$.ajax({
url: '{% url 'create_request' %}',
type: 'POST',
data: {
'cid': cid,
'req_num' : $('#request_number').val(),
},
success: function (data) {
console.log("success")
if (data['request']=='0')
{
alert("Request is already there");
}
else if(data['request']=='1')
{
alert("Not enough components:(");
}
$("#exampleModal").modal('hide');
}
})
})
})
})
</script>
test is the class given to button which opens bootstrap modal
post-form is the id given to my form
Attach the submit event listener outside the click function, otherwise you will create one listener per click.
$(document).ready(function () {
$("#post-form").one('submit',function (event){
event.preventDefault();
$.ajax({
url: '{% url 'create_request' %}',
type: 'POST',
data: {
'cid': cid,
'req_num' : $('#request_number').val(),
},
success: function (data) {
if (data['request']=='0')
{
alert("Request is already there");
}
else if(data['request']=='1')
{
alert("Not enough components:(");
}
$("#exampleModal").modal('hide');
}
})
})
})
This will of course break the context for this in $(this).attr('cid');, so you will have to update that to reflect the changes. I'd suggest placing it inside a hidden field in your form, or as an attribute to your modal, whatever is more convenient.

Append option to multi-select using ajax

I have the following HTML multi-select code:
<select class="multi-select" multiple="multiple" id="multiSelectId">
And am trying to dynamically add elements into it using ajax:
function TestFunction(value) {
const selectMembers = $("#multiSelectId");
selectMembers.empty();
selectMembers.append('<option value="val">test1</option>');
$.ajax({
url: '#Url.Action("GetMemberById", "SystemAdmin")',
data: {
'memberId': value
},
success: function(data) {
selectMembers.append('<option value="val">test2</option>');
alert("test3");
}
});
selectMembers.multiSelect('refresh');
}
So the weird thing is, that test1 and test3 are working fine, whereas test2 doesn't work at all and I can't find why it doesn't work. Does anybody has an idea?
You need to refresh in the success callback handler. Remember ajax() is asynchronous.
function TestFunction(value) {
const selectMembers = $("#multiSelectId");
selectMembers.empty();
selectMembers.append('<option value="val">test1</option>');
$.ajax({
url: '#Url.Action("GetMemberById", "SystemAdmin")',
data: {
'memberId': value
},
success: function(data) {
selectMembers.append('<option value="val">test2</option>');
selectMembers.multiSelect('refresh');
alert("test3");
}
});
}

Issues with jquery html()

Having some issues properly getting the manipulated data from an element.
Everywhere on the internet doesn't seem to cover such a simple question with a simple answer. Please help.
I have manipulated an element with a returning ajax request:
$("#last_comment_added").html("1457856458")
now my function on the page:
jQuery(document).ready(function($) {
var post_slug = $("#post_slug").html();
var last_comment_added = $("#last_comment_added").text();
if (post_slug && last_comment_added) {
setInterval(function() {
$.ajax({
type: "POST",
url: "ajax_comments.php",
data: {
"task": "updates",
"post_slug": post_slug,
"last_comment_added": last_comment_added
},
cache: false,
success: function(html) {
eval(html)
}
});
}, 10000);
}
});
I get the old data from the element, not the new ajax "1457856458" data.
Please help.
If I understand your problem right it's just that you create this variable called last_comment_added and expect it to be continually updated, you set it once to be the text of the last_comment_added, it's never updated in your interval function. Here's a change that should make it work better for you.
jQuery(document).ready(function($) {
var post_slug = $("#post_slug").html();
if (post_slug && last_comment_added) {
setInterval(function() {
$.ajax({
type: "POST",
url: "ajax_comments.php",
data: {
"task": "updates",
"post_slug": post_slug,
"last_comment_added": $("#last_comment_added").text()
},
cache: false,
success: function(html) {
eval(html)
}
});
}, 10000);
}
});
Don't use eval.
Try
$(document).ready(function() {
var post_slug = $("#post_slug").html();
var last_comment_added = $("#last_comment_added").html();
if (post_slug && last_comment_added) {
setInterval(_update, 10000);
}
});
function _update() {
$.ajax({
type: "POST",
url: "ajax_comments.php",
data: {
"task": "updates",
"post_slug": post_slug,
"last_comment_added": last_comment_added
},
cache: false,
success: function(data) {
$("#last_comment_added").html(data)
}
});
}
and you return from PHP only NEW data. (something like: echo '1457856458';)

Ajax, prevent multiple request on click

I'm trying to prevent multiple requests when user click on login or register button. This is my code, but it doesn't work. Just the first time works fine, then return false..
$('#do-login').click(function(e) {
e.preventDefault();
if ( $(this).data('requestRunning') ) {
return;
}
$(this).data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
$(this).data('requestRunning', false);
}
});
});
Any ideas? Thanks!
The problem is here:
complete: function() {
$(this).data('requestRunning', false);
}
this no longer points to the button.
$('#do-login').click(function(e) {
var me = $(this);
e.preventDefault();
if ( me.data('requestRunning') ) {
return;
}
me.data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
me.data('requestRunning', false);
}
});
});
Use on() and off(), that's what they are there for :
$('#do-login').on('click', login);
function login(e) {
e.preventDefault();
var that = $(this);
that.off('click'); // remove handler
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize()
}).done(function(msg) {
// do stuff
}).always(function() {
that.on('click', login); // add handler back after ajax
});
});
In your ajax callbacks the context (this) changes from the outer function, you can set it to be the same by using the context property in $.ajax
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
context: this, //<-----
success: function(msg) {
//stuffs
},
complete: function() {
$(this).data('requestRunning', false);
}
});
You can disable the button.
$(this).prop('disabled', true);
I have also faced a similar problem.
Just adding $('#do-login').attr("disabled", true); gives me the solution.
$('#do-login').click(function(e) {
e.preventDefault();
$('#do-login').attr("disabled", true);
.........
.........
Here do-login is button id.
I've tried this and worked very fine for me, I was having trouble that $.ajax send more request until results return,
var settings = {
"url": "/php/auth/login.php",
"method": "POST",
"timeout": 0,
"async": false,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"data": jsondata, //data pass here is in JSON format
};
$.ajax(settings).done(function (ress) {
try{
console.log(ress, "Result from Ajax here");
}
catch(error){
alert(error);
console.log(ress);
}
});
async : false worked for me.
Thanks.
Or you can do it by $(this).addClass("disabled"); to you button or link and after click is performed, you can $(this).removeClass("disabled");.
// CSS
.disabled{
cursor: not-allowed;
}
// JQUERY
$('#do-login').click(function(e) {
e.preventDefault();
$(this).addClass("disabled");
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
context: this,
success: function(msg) {
//do more here
$(this).removeClass("disabled");
},
});
});
P.S. If you use bootstrap css, you do not need the css part.
I found the approach useful. I've implemented it as a general purpose function for jQuery with ES6.
export default function (button, promise) {
const $button = $(button);
const semaphore = 'requestRunning';
if ($button.data(semaphore)) return null;
$button.data(semaphore, true);
return promise().always(() => {
$button.data(semaphore, false);
});
}
Because $.ajax() returns a promise, you simply pass in the promise and the function takes care of the rest.
Roughly speaking, here's the usage.
import preventDoubleClick from './preventdoubleclick';
...
button.click(() => {
preventDoubleClick(this, () => $.ajax()
.done(() => { console.log("success") }));
});
This function can help you with control multi Ajax requests and it's has timeout function which can return flag status to 0 after ex. 10sec (In case the server took more than 10 seconds to respond)
var Request_Controller = function(Request_Name = '', Reactivate_Timeout = 10000)
{
var a = this;
a.Start_Request = function(){
if(window.Requests == undefined){
window.Requests = {};
}
window.Requests[Request_Name] = {'Status' : 1, 'Time': + new Date()};
}
a.End_Request = function(){
if(window.Requests == undefined){
window.Requests = [];
}
window.Requests[Request_Name] = undefined;
}
a.Is_Request_Running = function(){
if(window.Requests == undefined || window.Requests[Request_Name] == undefined){
return 0;
}else{
var Time = + new Date();
// Reactivate the request flag if server take more than 10 sec to respond
if(window.Requests[Request_Name]['Time'] < (Time - Reactivate_Timeout))
{
return 0;
}else{
return 1
}
}
}
}
To use it:
var Request_Flag = new Request_Controller('Your_Request_Name');
if(!Request_Flag.Is_Request_Running()){
Request_Flag.Start_Request();
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
Request_Flag.End_Request();
}
});
}
for prevent multiple ajax request in whole site. For example: If use ajax request in other ajax page, Using ajax in php loop, etc, Give you multiple ajax request with one result. I have solution:
Use window.onload = function() { ... }
instead of
$(document).ready(function(){ ... });
on the main index.php page. Its will be prevent all multi request. :)

Jquery Ajax - Not loading text

I am new to jquery and coding in general. This is what I am trying to do:
When a link is clicked, expand the #country_slide div
Show "loading" text
If ajax is successful, put the contents of an html file into the div
Otherwise alert an error and close the div
This is the code I now have:
http://jsfiddle.net/spadez/n9nVs/5/
window.onload = function () {
var a = document.getElementById("country_link");
a.onclick = function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
$("#country_slide").val('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
}
}
When the link is clicked, I never see the loading text in the box. Please can someone tell me where I have gone wrong here? Also if anyone can offer any words of advice about my first jquery script I would really appreciate it.
Your anchor's id is country, not country_link. So:
var a = document.getElementById("country");
or just use jQuery's id selector:
var a = $("#country");
or even better directly chain:
$(function() {
$('#country').click(function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
$("#country_slide").html('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
}
});
Notice that I have used the $(document).ready function instead of window.onload. Also I have replaced the onclick event subscription with jQuery's click function. If you are using jQuery it would be better to take full advantage of it.
Working jsFiddle Demo
You don't have any country_link element in your page.
Instead of using window.onload you can use DOM ready.
Attach click handler by jQuery with .on() method.
The .val() method is for <input />. For other elements, use .html() instead.
// DOM ready instead of window.onload
$(function () {
// attach click handler by jQuery instead of onclick
$('#country').on('click', function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
// val() method is for <input />
// use html() instead
$("#country_slide").html('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
});
});
References:
.html() - jQuery API Documentation
.on() - jQuery API Documentation
.val() - jQuery API Documentation
jQuery( callback ) - jQuery API Documentation
On the fiddle you have
<a href="#" id="country">
Where it should be:
<a href="#" id="country_link">
or change the JS to be
var a = document.getElementById("country");
Because there is no element with an ID country_link
document.getElementById() returns null if the element isn't found
document.getElementById('country').onclick = ...; //should work
In JavaScript, null is a special primitive and you cannot add properties to primitive types.
You have to add an element with id=country_link and the this code will work as NOX said. I have tried that in jsfiddle. try it using
$("#country").click(function(){
// your code goes here
})
that will works.
document.getElementById("country_link"); shall be replaced by document.getElementById("country"); as "country_link" is not the id of any <a> tag in the mark up.
If you are using jQuery library you may handle event like-
$(document).on("click","a",function(){
//ajax stuff
});
Updated Your jsfiddle Code. Just check. its going to failure method. In your workspace you should have the test.html returning the actual data. Thanks.
Don't use plain JS if you already have jQuery (it will be easier for you):
;$(document).ready(function(){
$(country_link).click(function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$(country_slide).show();
$(country_slide).val('<p>Loading</p>');
},
success: function (data, textStatus) {
$(country_slide).html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$(country_slide).hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
});
});

Categories