Ajax success function and find parent class - javascript

On click I run a function that will do an ajax submission for each form that has the .red_active class. After the ajax submission or after the complete function I want to remove the parent's .red_active class. This is what I tried, can you help me spot my mistake?
$('.edit_old').click(function(){
$('.slider_edit').each(function(){
if($(this).hasClass('red_active')){
$(this).find('.edit_form_slide').each(function(){
$(this).on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
console.log('submitted '+ url);
//$(this).parent().removeClass('.red_active');
},
error: function () {
console.log('fail');
}
});
});
$(this).submit();
//$(this).submit().parent().removeClass('.red_active');
});
}
});
});

The issue is because within the success handler the this keyword does not reference the .edit_form_slide as it does in the each() handler. You need to store the reference of this in a variable:
$('.edit_old').click(function () {
$('.slider_edit').each(function () {
var $sliderEdit = $(this);
if ($sliderEdit.hasClass('red_active')) {
$sliderEdit.find('.edit_form_slide').each(function () {
var $editFormSlide = $(this); // store 'this' in a variable
$editFormSlide.on('submit', function (e) {
e.preventDefault();
var data = $editFormSlide.serialize();
var url = $editFormSlide.attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
console.log('submitted ' + url);
$editFormSlide.parent().removeClass('.red_active'); // to use here, within the other scope
},
error: function () {
console.log('fail');
}
});
});
$editFormSlide.submit();
});
}
});
});
Note that I did the same for the .slider_edit selector too, just to keep things consistent. If you have nested this references it can get confusing to keep track of what is referencing what, without a named variable.

First you can optimize and remove the if and .find lines
$('.slider_edit. red_active . edit_form_slide').each(function(){
has the same effect than :
$('.slider_edit').each(function(){
if($(this).hasClass('red_active')){
$(this).find('.edit_form_slide').each(function(){
And next to find a parents with a class, the best way is to use .parents() and all beware of the this in your function, the this in the success function is not the this you are looking to. You should save the $(this) before the ajax call in a var and reuse it into success callback.
Full correction :
$('.edit_old').click(function() {
$('.slider_edit.red_active .edit_form_slide').each(function() {
var $formSlide = $(this);
$formSlide.on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function(data) {
$formSlide.parents('.red_active:first').removeClass('.red_active');
},
error: function() {
console.log('fail');
}
});
}).submit();
});
});

Related

How to display a random quote as soon as page loads?

I am working on a random quote app. Quote is display when click a new quote button but I want quote already display when page loads. I invoked a function but it still does not work. Thank you!
Here is my code:
$(document).ready(function() {
function randomQuote() {
$('#get-quote').on('click', function(e){
e.preventDefault();
// Using jQuery
$.ajax( {
url: "http://quotes.stormconsultancy.co.uk/random.json",
dataType: "jsonp",
type: 'GET',
success: function(json) {
// do something with data
console.log(json);
data = json[0];
$('#quotation').html('"'+json.quote+'"');
$('#author').html('-- '+json.author+' --');
$('a.twitter-share-button').attr('data-text',json.quote);
},
});
});
$('#share-quote').on('click', function() {
var tweetQuote=$('#quotation').html();
var tweetAuthor=$('#author').html();
var url='https://twitter.com/intent/tweet?text=' + encodeURIComponent(tweetQuote+"\n"+tweetAuthor);
window.open(url)
});
}
randomQuote();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try removing click listener. inside randomeQuote() remove click listener.
keep your click listener out side of document.ready
$(document).ready(function() {
randomQuote(); // call initially and get random quote
});
function randomQuote() {
$.ajax( {
url: "https://quotes.stormconsultancy.co.uk/random.json",
dataType: "jsonp",
type: 'GET',
success: function(json) {
// do something with data
data = json[0];
$('#quotation').html('"'+json.quote+'"');
$('#author').html('-- '+json.author+' --');
$('a.twitter-share-button').attr('data-text',json.quote);
},
});
$('#share-quote').on('click', function() {
var tweetQuote=$('#quotation').html();
var tweetAuthor=$('#author').html();
var url='https://twitter.com/intent/tweet?text=' + encodeURIComponent(tweetQuote+"\n"+tweetAuthor);
window.open(url)
});
}
$('#get-quote').on('click', function(e){
e.preventDefault();
randomQuote();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="get-quote">get quote</button>
<div id="quotation"></div>
Remove the onClick listeners so that when you call the function it will update directly.
function randomQuote() {
$.ajax( {
...
success: function(json) {
... //do updates
},
});
}

jQuery calculate hours function not working

I am trying to pass $(this) value to a jQuery function. The function is below but does not work. There are no errors in console.
The function is firing because when I place an alert at the top it works.
(function($){
$.fn.calculateHours = function() {
var tbody = $(this).closest('tbody'); // get closest tbody
var table = $(this).closest('table'); // get closest table
var params = table.find('.disguise').serialize(); // parameters
$.ajax({
type: 'post',
dataType: 'json',
url: '/calculateHours',
data: params,
success: function (response) {
// loop over object
$.each(response.rows, function(index, array) {
$.each(array, function(key, value) {
$('#row_' + index).find('.' + key).html(value);
});
});
if($.isPlainObject(response.columns)) {
$.each(response.columns, function(day, hour) {
$('.totalsRow').find('.total_' + day).html(hour);
});
}
$('.totalsRow').find('.grand_total').html(response.grand_total);
}
});
}
})(jQuery);
$(document).on('change', '.disguise', function(e) {
$.fn.calculateHours();
});
Adding functions to $.fn is meant to extend the jQuery object. In other words, you should be calling .calculateHours on your jQuery object:
$(document).on('change', '.disguise', function(e) {
$(this).calculateHours();
});
You want jquery to set the context automatically. To do that just pass a reference to the function as the handler.
$(document).on('change', '.disguise', $.fn.calculateHours);

Navigating a JSON object

total noob here:
I've got a JSON result coming to a .on('click') function which looks like this:
{"1411939719-8696.jpeg":true}
I want to remove a line in a table, based on where the call came from, but for some reason it's not working:
$('#fileupload').fileupload({
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
var del = $('<button/>')
.addClass('btn btn-danger')
.attr('data-type', 'DELETE')
.attr('data-url', file.deleteUrl)
.text('DELETE');
var thumb = $('<img />',
{ id: file.thumbnailUrl+'_ID',
src: file.thumbnailUrl,
alt:'MyAlt'});
$('#preview').find('tbody')
.append($('<tr>')
.append($('<td>').append(thumb))
.append($('<td>').append(del))
);
});
}
});
and the on click function is here:
$(document).on("click", ".btn-danger", function () {
$.ajax({
url: $(this).attr("data-url"),
type: $(this).attr("data-type")
}).done(function (result) {
$(this).closest("tr").remove(); // to remove the complete row after delete success
});
});
I need to remove the row that contains the delete button, along with the thumbnail image, but this code isn't working?
I think you are calling the wrong scope.
Maybe this could work:
$(document).on("click", ".btn-danger", function () {
//save scope-object to that
var that = this;
$.ajax({
url: $(this).attr("data-url"),
type: $(this).attr("data-type")
}).done(function (result) {
$(that).closest("tr").remove();
});
});

How to access the value of a select Box as variable onChange inside another function

I want to access the value of #schooSelect inside ajax so i can send some data to php onChange.
$.LoadBooks = function () {
$(document).on('change', '#SchoolSelect', (function (e) {
var SchoolVal = ($(this).val())
$.LoadBooks()
}))
var SchoolVal = ($('#SchoolSelect').val())
$.ajax({
type: "GET",
data: {
data: SchoolVal
},
url: "../php/booksads.php"
}).done(function (feedback) {
$('#booksads').html(feedback)
});
}
$.LoadBooks()
Your code is strangely structured. You are somehow "recursively" calling $.LoadBooks inside the event handler, which will cause a new event handler to be added to the element, which is certainly not what you want.
Just bind the event handler once, outside the function:
var loadBooks = function(schoolVal) {
$.ajax({
type: "GET",
data: {
data: schoolVal
},
url: "../php/booksads.php"
}).done(function (feedback) {
$('#booksads').html(feedback)
});
}
$(document).on('change', '#SchoolSelect', function(e) {
loadBooks($(this).val());
});
You can either pass the value of the select element to the function (as shown here) or call var schoolVal = $('#SchoolSelect').val() inside of it to get the value.
The convention is that only the name of constructor functions start with a capital letter. And if your function is related to jQuery in particular, you shouldn't add it to $.

.on("click", "img", function (e) not working after Postback

I have the following JQuery code :-
$('.rpItem').on("click", "img", function (e) {
alert('here');
var text = $(this).siblings('span.rpText').text();
e.preventDefault();
e.stopPropagation();
var args = {
reportName: text
};
$.ajax({
type: "POST",
url: "Dashboard.aspx/AddToFavourites",
data: JSON.stringify(args),
contentType: "application/json;charset=utf-8;",
success: function (data) {
__doPostBack('#MainMenuUP', text);
//__doPostBack('<%= MainMenuUP.ClientID %>', text);
},
error: function () {
}
});
});
$("#reports_textSearch").keyup(function () {
var textLength = $(this).val().length;
delay(function () {
if (textLength == 0) {
emptySearchString();
}
if (textLength > 2) {
var args = {
reportName: document.getElementById('reports_textSearch').value
};
doSearchString(args);
}
}, 1000);
});
function doSearchString(args) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Dashboard.aspx/FetchReports",
data: JSON.stringify(args),
dataType: "json",
success: function (data) {
//__doPostBack('#MainMenuUP', data.d);
__doPostBack('<%= MainMenuUP.ClientID %>', data.d);
},
error: function (data) {
}
});
}
and the first time its working fine. However after the postback, the doSearch keeps on working correctly, whilst the
$('.rpItem').on("click", "img", function (e) {
fails. It is not even going through that code.
I tried to replace the
__doPostBack('<%= MainMenuUP.ClientID %>', data.d);
with
__doPostBack('<%= MainMenuUP.UniqueID %>', data.d);
but that just does a page refresh which I do not want.
Any help will be very much appreciated!
Thanks
Change your selector to this one:
$('body').on("click", ".rpItem img", function (e) {
// your code
});
If the .rpItem is replaced during your ajax call read the following:
The first time your js executes, it binds the on event to the existing rpItems.
Any new added .rpItemwill skip this binding unless you re-execute the script that accomplishes the binding.
In order to avoid this, you may use the document for the binding as #Mojtaba suggests but keep in mind that you "add" the binding to the document leading to "checking" whether an .rpItem img has been clicked or not every time something is clicked on the document.
Otherwise, you can create a function that will take your .rpItem as an argument and will accomplish the binding explicitly. After each new .rpItem added to your page, you can call this function to bind the click event. Ex:
function foo(arg) {
$(arg).on("click", "img", function (e) {
...
}
}
$(document).ready(function(){
$('.rpItem').each(function(){
foo($(this));
};
});

Categories

Resources