jQuery: Updating global var and re-running function - javascript

I have a function that has another function nested that binds a click event to re-run that function with a different ajax URL:
function getInternal() {
var callUrl = 'https://url.com'; // URL ON LOAD
$.ajax({
dataType: "json",
url: callUrl,
success: function(data) {
var obj = data;
$( document ).ready(function(callUrl) {
$( "a.dept" ).click(function() {
var filterDept = $(this).attr('id');
callUrl = 'https://url.com/' + filterDept; // URL TO UPDATE
getInternal(callUrl); // RUN THIS FUNCTION AGAIN
});
});
Unfortunately the click event continues to return the same data. It doesn't look like callUrl is updating.
How do I update a global variable from within a function to re-run itself?

The first line of your function sets your variable to a specific value: var callUrl = 'https://url.com'; Thus, every single time you run this function, the variable will be set to 'https://url.com'.
By moving your variable outside of the function it will become a global variable, and the portion of your code that updates callUrl will persist.
That being said, your code is all sorts of mixed up. You have $( document ).ready() within an AJAX callback, a click event that gets redefined within that with each call, nothing seems to be closed, and you've supplied a parameter for getInternal(); despite the fact that it takes none.
Is something like this what you're after?
$(document).ready(function() {
//On click of link, run AJAX call to changing URL (based on clicked link's ID)
$( "a.dept" ).click(function() {
var filterDept = $(this).attr('id');
var callUrl = 'https://url.com/' + filterDept;
getInternal(callUrl);
});
});
function getInternal(callUrl) {
$.ajax({
dataType: "json",
url: callUrl,
success: function(data) {
alert("Call made to " + callUrl);
}
});
}

Related

How to make jquery find the row and fire an action on success (using "this")

This is a jquery code that performs a database update when the user modifies a cell:
$( document ).ready(function() {
$('tr').on('blur', 'td[contenteditable]', function() {
$.post("ajax/modQtyModels", {
modelId: $(this).closest('tr').children('td.idmodel').text(),
qty: $(this).closest('tr').children('td.editQty').text(),
ajax: true,
success: function(data) {
$(this).closest('tr').children('td.editQty').addClass("success");
}
});
});
});
In the "success" part I want it to just change the class (to change its color as it uses bootstrap) of that cell to show the user that their data changed successfully but it doesn't seem to notice that it has to change the color. I've tried everything on that line but I guess the line is not the problem. Other actions like an alert work well so I suspect of the $(this).
In the success callback you are dealing with another function, so the scope is no longer the one of your blur event callback, so this keyword will point out to another object and not your jQuery element.
So you need to save the this value in another variable and refer to your element with this neww variable, inside the success callback.
(document).ready(function() {
$('tr').on('blur', 'td[contenteditable]', function() {
var tr = $(this);
$.post("ajax/modQtyModels", {
modelId: $(this).closest('tr').children('td.idmodel').text(),
qty: $(this).closest('tr').children('td.editQty').text(),
ajax: true,
success: function(data) {
tr.closest('tr').children('td.editQty').addClass("success");
}
});
});
});
this inside of success: function(data) { does not refer to this inside of $('tr').on('blur'
You can save the value of this (typically in a variable called that), so that when you are in that new function, you can do:
$( document ).ready(function() {
$('tr').on('blur', 'td[contenteditable]', function() {
var that = this;
$.post("ajax/modQtyModels", {
modelId: $(this).closest('tr').children('td.idmodel').text(),
qty: $(this).closest('tr').children('td.editQty').text(),
ajax: true,
success: function(data) {
$(that).closest('tr').children('td.editQty').addClass("success");
}
});
});
});

how to get value outside jquery click function

I have a on click function to get the id of a,and I want to alert it.
The following code is not working showing null, why? thanks
var projectId=null;
$('body').on('click', '#list a', function(){
projectId=this.id; //id should = 30
alert(projectId); //here display 30
});
alert(projectId); //here display null
what i really want to do is :
a.js I have sth like, when I click "a" it redirect to another page which need to render by my projectId:href='/projectDetail' this page call b.js
$.ajax({
type: "GET",
url: 'http://xxx',
dataType:'json',
contentType:"application/json",
success:function(data){
console.log(data);
var projectList="<ul style='list-style:none;'>"
for (var i = 0; i < data.data.length; i++) {
projectList += "<li><div id='listall'><a
id='"+data.data[i].projectId+"'
href='/projectDetail'>"+
"<img class='back' src='/img/Homepage_ProjectFrame.png'></li>"
}
var projectList="<ul>"
});
var projectId=null;
$(document).on('click', '#listall a', function (){
event.preventDefault();
projectId=this.id;
alert(projectId);
});
alert(projectId);
b.js I have:
$.ajax({
type: "GET",
url: 'http://xxx?projectId='+projectId
dataType:'json',
contentType:"application/json",
success:function(data){
console.log(data.data);
$(".photoprojectD").attr("src",data.data.projectPhotoUrl);
$(".dlocation p").html(data.data.countryName);
$(".dcategory p").html(data.data.categoryName);
});
So i need projectId from a.js to render dynamic information
Do you have any good ideas?
Thanks a lot for your guys helping
the second alert(projectId); outside the "click" event handler runs as soon as the page loads. Inevitably this is before your "click" handler can possibly be executed, because the user has likely not had time to click on it, and even if they had time, there's no guarantee that they will. Therefore the variable projectId is not populated when that code executes.
You can certainly use projectId outside your "click" event, but you have to wait until after at least one "click" event has happened before you can expect it to have a value.
There's also danger that your hyperlinks are causing the page to postback before any of this ever happens. Since you're using jQuery you can prevent this very easily:
$('body').on('click', '#list a', function(event) {
event.preventDefault(); //prevent default hyperlink redirect/reload behaviour
projectId=this.id; //id should = 30
alert(projectId); //here display 30
});
Lastly, ensure that this other place you want to use the value is not doing anything silly like declaring another "projectId" variable with narrower scope and then trying to use that. For example, this will not work as you wish:
var projectId = null;
$('body').on('click', '#list a', function(event) {
event.preventDefault(); //prevent default hyperlink redirect/reload behaviour
projectId=this.id; //id should = 30
alert(projectId); //here display 30
exampleFunc(); //call the function below
});
function exampleFunc() {
var projectId = null; //oops, another "projectId" with narrower scope (within this function) will take precedence here
alert(projectId); //will be null
});
Whereas this will:
var projectId = null;
$('body').on('click', '#list a', function(event) {
event.preventDefault(); //prevent default hyperlink redirect/reload behaviour
projectId=this.id; //id should = 30
alert(projectId); //here display 30
exampleFunc(); //call the function below
});
function exampleFunc() {
alert(projectId); //will be 30
}

Run JS function on .load() content

I have a function called timepicker which is usually called by using
$(document).ready(function() {
$('#timepicker').timepicker();
});
But I have been unable to make it work on content that is displayed using jQuery .load().
I have tried several methods including using the below but nothing happens?
$(document).ready(function() {
var $parent = $('#small_container');
var time = $parent.find('#timepicker');
time.timepicker();
});
The #small_container is the ID of the DIV that the content is loaded into and the #timepicker is the id of the input that should call the function when it is clicked on.
Have I added it to the correct place in the callback?
$('.edit_job').on("click", function(){
var week_start = $('input[name=week_start]').val();
var job_id_del= $('input[name=job_id]').val();
var user_id = $('input[name=user_id]').val();
$('#small_container').load('ajax/edit_weekly_job_load.php?job_id='+job_id_del+'&week_start='+week_start+"&user="+user_id);
$('#timepicker').timepicker();
$('#small_container').on("click", '#edit_job_submit', function(){
jQuery.ajax({
type: "POST",
url: "ajax/edit_weekly_job_ajax.php",
dataType: "json",
data: $('#edit_job_form').serialize(),
success: function(response){
if(response.success === 'success'){
window.opener.$("#diary").load("ajax/diary_weekly_load.php?week_start="+week_start+"&user="+user_id);
window.close();
}
},
});//end ajax
});//save_job_edit_submit
});//end edit job
The content is loaded asynchronously to the element #small_container. The timepicker function is gets called before the content is actually loaded. Try to call the function in the callback of load() method:
$('#small_container').load('ajax/edit_weekly_job_load.php?job_id='+job_id_del+'&week_start='+week_start+"&user="+user_id ,function(){
$('#timepicker').timepicker();
} );
Also validate that element #timepicker is actually appended to the element #small_container.

AJAX jQuery on click dynamically created only works first time

I am trying to create a dropdown menu that I dynamically insert into using jQuery. The objects I'm inserting are notifications, so I want to be able to mark them as read when I click them.
I have an AJAX call that refreshes the notifications every second from the Django backend.
Once it's been refreshed, I insert the notifications into the menu.
I keep an array of the notifications so that I don't create duplicate elements. I insert the elements by using .append(), then I use the .on() method to add a click event to the <li> element.
Once the click event is initiated, I call a function to .remove() the element and make an AJAX call to Django to mark the notification as read.
Now my problem:
The first AJAX call to mark a notification as read always works. But any call after that does not until I refresh the page. I keep a slug value to identify the different notifications.
Every call I make before the refresh uses the first slug value. I can't figure out why the slug value is tied to the first element I mark as read.
Also, if anyone has a better idea on how to approach this, please share.
Here's my code:
var seen = [];
function removeNotification(elem, urlDelete) {
elem.remove();
console.log("element removed");
$.ajax({
url: urlDelete,
type: 'get',
success: function(data) {
console.log("marked as read");
},
failure: function(data) {
console.log('failure to mark as read');
}
});
}
function insertNotifications(data) {
for (var i = 0; i < data.unread_list.length; i++) {
var slug = data.unread_list[i].slug
var urlDelete = data.unread_list[i].url_delete;
if (seen.indexOf(slug) === -1) {
var elem = $('#live-notify-list').append("<li id='notification" +
i + "' > " + data.unread_list[i].description + " </li>");
var parent = $('#notification' + i).wrap("<a href='#'></a>").parent();
seen.push(slug);
$( document ).ready(function() {
$( document ).on("click", "#notification" + i, function() {
console.log("onclick " + slug);
removeNotification(parent[0], urlDelete);
});
});
}
}
}
function refreshNotifications() {
$.ajax({
url: "{% url 'notifications:live_unread_notification_list' %}",
type: 'get',
success: function(data) {
console.log("success");
insertNotifications(data);
},
failure: function(data) {
console.log('failure');
}
});
}
setInterval(refreshNotifications, 1000);
I really don't know what do you mean with parent[0] in
removeNotification(parent[0], urlDelete);
I think you can simply try $(this)
removeNotification($(this), urlDelete);
but to be honest I find to put
$( document ).ready(function() {
$( document ).on("click", "#notification" + i, function() {
console.log("onclick " + slug);
removeNotification(parent[0], urlDelete);
});
});
inside a loop .. its bad thing try to put it outside a function and use it like
$( document ).ready(function() {
setInterval(refreshNotifications, 1000);
$( document ).on("click", "[id^='notification']", function() {
console.log("onclick " + slug);
removeNotification($(this), urlDelete);
});
});
and try to find a way to pass a urlDelete which I think it will be just one url

jQuery: Referencing the calling object(this) when the bind/click event is for a class

Thanks for reading this.
I am dynamically generating some data which includes a select drop-down with a text box next to it. If the user clicks the select, I am dynamically populating it (code below). I have a class on the select and I was hoping the following code would work. I tested it with an ID on the select and putting the ONE on the ID I got it to work. However, in changing the code to reference a class (since there will be multiple data groups that include a select with a text box next to it) and $(this), I could not get it to work. Any ideas would be helpful. Thanks
The relevance of the text box next to the select is the second part of the code...to update the text box when an option is selected in the select
.one is so the select is updated only once, then the .bind allows any options selected to be placed in the adjacent text box.
$('.classSelect').one("click",
function() {
$.ajax({
type: "post",
url: myURL ,
dataType: "text",
data: {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
},
success:
function(request) {
$(this).html(request); // populate select box
} // End success
}); // End ajax method
$(this).bind("click",
function() {
$(this).next().val($(this).val());
}); // End BIND
}); // End One
<select id="mySelect" class="classSelect"></select>
<input type="text">
$(this) is only relevant within the scope of the function. outside of the function though, it loses that reference:
$('.classSelect').one("click", function() {
$(this); // refers to $('.classSelect')
$.ajax({
// content
$(this); // does not refer to $('.classSelect')
});
});
a better way to handle this may be:
$('.classSelect').one("click", function() {
var e = $(this);
$.ajax({
...
success : function(request) {
e.html(request);
}
}); // end ajax
$(this).bind('click', function() {
// bind stuff
}); // end bind
}); // end one
by the way, are you familiar with the load() method? i find it easier for basic ajax (as it acts on the wrapped set, instead of it being a standalone function like $.ajax(). here's how i would rewrite this using load():
$('.classSelect').one('click', function() {
var options = {
type : 'post',
dataType : 'text',
data : {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
}
} // end options
// load() will automatically load your .classSelect with the results
$(this).load(myUrl, options);
$(this).click(function() {
// etc...
}); // end click
}); // end one
I believe that this is because the function attached to the success event doesn't know what 'this' is as it is run independently of the object you're calling it within. (I'm not explaining it very well, but I think it's to do with closures.)
I think if you added the following line before the $.ajax call:
var _this = this;
and then in the success function used that variable:
success:
function(request) {
_this.html(request); // populate select box
}
it may well work
That is matching one select. You need to match multiple elements so you want
$("select[class='classSelect']") ...
The success() function does not know about this, as any other event callback (they are run outside the object scope).
You need to close the variable in the scope of the success function, but what you really need is not "this", but $(this)
So:
var that = $(this);
... some code ...
success: function(request) {
that.html(request)
}
Thanks Owen. Although there may be a better to write the code (with chaining)....my problem with this code was $(this) was not available in the .ajax and .bind calls..so storing it in a var and using that var was the solution.
Thanks again.
$('.classSelect').one("click",
function() {
var e = $(this) ;
$.ajax({
type: "post",
url: myURL ,
dataType: "text",
data: {
'_service' : myService,
'_program' : myProgram ,
'param' : myParams
},
success:
function(request) {
$(e).html(request); // populate select box
} // End success
}); // End ajax method
$(e).one("click",
function() {
$(e).next().val($(e).val());
}); // End BIND
}); // End One

Categories