jquery $(this) object missing issue - javascript

I have a problem with jQuery's $(this) object and make me miss the this element
in code :
$('.star').click(function (){
var id = $(this).parent().attr('id').split('rating')[1];
var vote = $(this).index() + 1;
var ThisStar = $(this);
alert(ThisStar.parent().html())
$.ajax({
type: 'POST',
url: EXECUTION_URL + 'ajax/rate.php',
data: {'article' :id ,'rate': vote},
success:function(data,tt,ff){
alert(ThisStar.parent().html())
}
});
the first alert fire : the true contents of the parents of the clicked node
the second alert fire : null !!!!
why it have been changed into the ajax ? or from another reason ? please tell me a good solution for this issue
ok actually i checked my code that there is two lines after the ajax function that delete the stored node in the this object and because of the ajax function is asynchronous function the two lines executed before the code inside the success function >> thanks for all

Your code should work fine, check the proof. The only difference would be this:
success:function(data,tt,ff){
alert(ThisStar.parent().html())
}
vs.
success:function(data,tt,ff){
alert(ThisStar.parent().html())
}});

Related

"i" value in JavaScript for loop is not being recognized in a jquery function

I'm using jQuery and ajax to open a bootstrap modal window. My code works perfectly when not in a loop, and my content is displayed appropriately in the modal window. But I have five modals on the page, and naturally I'd like to use a for loop so I don't repeat my code five times.
It seems like a no-brainer to write a for loop to execute the code five times, but somehow, there is a problem, and when I put the code into a for loop, the modal content will not show in the opened window.
Here is code that works how I need it, so the modal content from my modal1.php file shows in a modal popup window. Notice that the i variable is used three times; once in the jQuery selector, and twice in the $.ajax(...) area:
var i = 1;
$('#modal' + i).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
This code below uses the variable i the exact same way as the code above. However, with the code below, the modal1.php content does not show (nor do any of the other files named 'modal[i].php'). Instead, only a blank dark background appears when they are opened.
for (i = 1; i < 6; i++) {
$('#modal' + i).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
}
So I don't understand why the $.ajax() area of the code won't recognize the i variable in the for condition, but it will recognize it in the initial jQuery selector $('#modal' + i), which I've tested and found to be true. Is there a way I can write this loop so that the ajax area will recognize the i variable? Or is there a mistake in my code that I'm overlooking?
Incidentally, I've noticed that similar questions have been asked, but they have been downvoted for not being clearly written. I've read them all, and they don't answer the question that I have today.
The problem here is that you are (unintentionally) referencing a variable (i) via a closure.
Since scope is dictated by function in JavaScript, wrap your on usage with another (immediately invoked) function so a unique i is saved:
for (i = 1; i < 6; i++) {
(function() {
var iModalNumber = i;
$('#modal' + iModalNumber).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + iModalNumber + '.php',
data:{id:id},
success:function(data){
$('#modal' + iModalNumber).html(data);
}
});
});
}());
}
The reason that these questions get down-voted so much is because issues/misunderstanding of closures is so common. It is admittedly a difficult concept to grasp, and your question was well written.
More information: How do JavaScript closures work?
You could probably do this without using loop but using jQuery .each() and adding value attributes to your html elements. Warning... untested code ahead.
jQuery('.modal').each(function(){ // use a class instead of an id
$(this).on('show.bs.modal', function(e) { //use $(this) to target
var i = $(this).val(); // get the value id
var id = e.relatedTarget.dataset.id; // do your code
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
});

jQuery function .val() does not work

I'm trying to update the value of the div block
<div id="likeVal">Likes: #Model.Likes</div>
after making an Ajax call as below:
$.ajax({
type: "POST",
async: false,
url: "/Media/VideoLike?likes=" + likes + "&id=" + id
}).done(function(data) {
$("#likeVal").innerHTML = data.likes
});
but the value in the block does not get updated. However when I use document.getElementById("#likeVal").innerHTML = data.likes; the value gets changed. I know that document.getElementById returns a DOM object. I have used the jQuery function in another Ajax call that I made here:
}).done(function(notice) {
if (notice.error || notice.isLastBlock) {
displayStatusMessage(notice.message);
if (notice.isLastBlock) {
$("#assetId").val(notice.assetId);
$("#detailsPanel").show();
}
return;
}
It works fine and the value get's updated in the div block. What am I doing wrong in the first Ajax call?
You are using wrong method for that.
jQuery.val() gets/sets you value of form field. You should use jQuery.html() to get/set content of element.

Why a JavaScript function with some specific name is not working while others are?

A very interesting problem I am facing these days is regarding one of my JavaScript function. My JavaScript function with some specific name is not working but if I change its name to anything else then it is working. Have a look -
// function to retain the jquery ui css for toolbar
function retain_css() {
alert('hi');
$( "#new_sort_options" ).buttonset();
}
// new sort
$(document).on("click", ".new_sort_button", function() {
var order = $(this).val();
var make_id = $('#new_make_id').val();
$.ajax({
beforeSend : start_loader(),
type : 'POST',
url : '/ajax/new-sort.php',
data : 'order='+order+'&make_id='+make_id,
dataType : 'json',
success : function(data) {
$("#new_results_toolbar").html(data.toolbar);
$("#new_results").html(data.models);
retain_css();
end_loader();
}
});
});
But retain_css() is not working at all. Even alert() is not firing. But if i change its name to anything such as my_fun() then the code works. I don't understand why it is happening so? Any idea? Don't worry about end_loader() function as it has nothing to deal with my problem. I also changed the order of code when retain_css() was being used but didn't work.
Try not to create global functions because it may collide with other frameworks or libraries.
//define private namespace
window.user3779493Functions = {};
//define method
user3779493Functions.retain_css = function() { ... }
//call method
user3779493Functions.retain_css();
Some functions are already programmed like 'alert('hi');', that is a function called alert:
function alert() {
/* do something */
}
That function also doesn't work.

$(document).Ready() loads Flexigrid, but not when called again by other function outside $(document).Ready()

I have a function called "loadTimeTrackersGrid()", which loads a flexigrid.
The setup looks like this :
$(document).ready(function () {
var editTrackerID = 0;
loadTimeTrackersGrid();
)};
The beginning of the function looks like this :
function loadTimeTrackersGrid(caseStatus) {
var url = 'Utilities/DataViewHandlers/ViewTimeTrackers.ashx?CaseFileID=' + $('#hidCaseFile').val();
if ($('#hidTaskID').val() !== "")
url += '&TaskID=' + $('#hidTaskID').val();
if (caseStatus == "NI") {
url += '&NonInvoiced=1';
}
$('#viewTimeTrackersGrid').flexigrid({
url: url,
dataType: 'json',
method: 'get',
As you can see it calls another page which contains a stored procedure which returns a set of rows and a jsonwriter then puts the returned columns into the flexigrid.
But the problem I am having is outside the (document).ready(), when I have a function that calls the "loadTimeTrackersGrid()", it never reloads the flexigrid or makes a call to the file that contains the stored procedure.
My function(that I am trying to get to work) looks like this :
function returnInvoicedItems() {
loadTimeTrackersGrid();
$('.menuBtn img').parent().children('ul').removeClass('menuShow');
}
And this is how I am calling "returnInvoicedItems" function:
<li>Non Invoiced Tracker</li>
I am not sure, but I think I can see the problem. Your second function returnInvoicedItems() that calls loadTimeTrackersGrid(), it does have a jQuery code (in the line $('.menuBtn img').parent().children('ul').removeClass('menuShow');. Now, if you have a jQuery call, don't you have to do make that call inside $(document).ready()?
Try to move returnInvoicedItems() inside $(document).ready() and see what happens.
This works like a gem:
$('#viewTimeTrackersGrid').flexOptions({ url: 'Utilities/DataViewHandlers/ViewTimeTrackers.ashx?' + invoicedUrl + '&NonInvoiced=1' }).flexReload();

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