Selectors not working on ajax response - ajax

I'm using ajax to submit pages and return content blocks based on user action for an onboarding sequence.
If have a page which loads and get 1 content element, the user then clicks Yes or No, which loads the next content element into the same space (via ajax).
For some reason my selectors don't seem to be working on that ajax loaded html.
Here is my ajax function which gets the form:
$.ajax({
beforeSend: function() {
$("#loader").toggleClass('progress');
},
type: 'POST',
dataType: 'json',
data: data,
url: baseUrl+'welcome/user_confirmation_form',
complete: function( response ) {
$("#loader").toggleClass('progress');
},
success: function( response ) {
console.log(response);
$("div.welcome-page > .col").html(response.response);
},
error: function( response ) {
$("#next-steps").html(response.response);
}
});
I'm then trying to access the submit button (have tried doing it as a ahref and button type=submit but nothing seems to be selecting the event.
$('div.welcome-page').on('submit', "user_complete", function(e) {
e.preventDefault();
console.log('FOund form');
var user = $(this).serializeArray();
console.log(user);
});
If I view source, the ajax returned HTML is not even in the dom, but it is when viewing the UI normally.
I'm guessing this has something to do with it?
How can I select all the form data?
Any time I click on the button or ahref it just fires the same page again.

If user_complete is a class you are assigning on your submit button in your loaded html, then you are missing a .
$('div.welcome-page').on('submit', ".user_complete", function(e) {
But this will only work if you're using a submit action as this is listening for a submit event. Maybe you want to listen for a click event?

You need to bind the events to your handlers for your newly added HTML elements. Your original call to
$('div.welcome-page').on('submit' ...
Only bound the event handler for the elements that were on the page at that point in time.
You can put your handler into a function ...
var myHandler = function(e) {
e.preventDefault();
var user = $(this).serializeArray();
}
And then after you load the new HTML you need to bind the handler to the event. So, on success with the AJAX you would ...
success: function( response ) {
$("div.welcome-page > .col").html(response.response);
$('div.welcome-page').on('submit', "user_complete", myHandler);
},

Related

Ajax function call not working second time

Need help to resolve ajax call issue
In my view page ( working on codeigniter), there is a dropdown and a div
section. Based on dropdown value, data will get change in div section. I am
using ajax call ( to call method in controller) to upload data in div tag on
dropdown change event. Ajax call working fine on first change event of
dropdown but when i select value for second time in dropdown, ajax function
call is not working ( second select and so on).
My code is:
VIEW PAGE =>
$(document).ready(function() {
$("body").on('change','#assettype_id',function(e){ // "assettype_id" is
dropdown id
//e.preventDefault();
var categoryval = $('#assettype_id :selected').val();
$.ajax({
type: 'POST',
cache: false,
url: 'http://my_path/index.php/assetcontroller/assignpc/'+ categoryval, // Based on "categoryval" data will change in div tag
dataType: 'html',
success: function(data) {
$( "#result" ).load( "http://my_path/index.php/assetcontroller/assignpc/"+ categoryval); // "result" is div tag id
$( "#result" ).html(categoryval);
},
});
return false;
});
});
Why ajax call is not working in dropdown 'second time' change event?
You need to wrap the .on('change') event into a function, so it can be called anytime later.
That's because once you have added new html output through Ajax, this html doesn't yet know about your change event!
So the function my_change_event() needs to be re-called, once your Ajax output has been added to DOM with your $( "#result" ).load()
something like this:
$(document).ready(function() {
my_change_event();
});
function my_change_event(){
$( "#assettype_id" ).on( "change", function() {
$.ajax({
type: 'POST',
cache: false,
url: your_url,
success: function(data) {
// do something with data
// html output
my_change_event();
}
});
}

load form using jquery ajax and resubmit that form without page refresh

i want to submit form which loaded via jquery without refreshing the whole page.
but this code first load form without refreshing whole page then the form loaded via jquery refreshes whole page on submission.
how to solve this problem??
$(document).ready(function() {
$("body").on("click",".down",function(e) {
e.preventDefault();
var name = $("#down").attr("name");
var vote = $("#down").val();
var voteString = 'votedown='+ vote;
$.ajax({
type: "POST",
url: 'vote.php',
data: voteString,
cache: false,
error: function() {
$('#btn-vote').html('<p>An error has occurred</p>');
},
beforeSend: function() {
$('#load').html("<img src='../images/LoaderIcon.gif' />");
},
success: function(html) {
$("#re").html(html);
}
});
The on function takes a selector as well, that way you can use it on elements loaded with ajax. You also have to bind it to an element that exists when the page loads.
$('body').on('click', 'selector of the element created', function(){
...
})
Obviously you should not use body probably but a closer parent of the loaded element.

Loading Content Via Ajax

Ok, so I'm pretty new to ajax and loading content externally and would appreciate any insight to my problem.
I currently have a hidden div that is empty where the ajax content should load in after a link is clicked.
<div id="#ajax-wrap"></div>
I currently have a list of links that all have the same class and I'd like to have, when clicked, the blank div do a slide toggle and then load in the content from the page that the link was to.
Link:
Current jQuery:
$("a.home-right").click(function () {
$('#ajax-wrap').slideToggle();
});
Being as I'm new to Ajax and loading the external content, I'd like to know how to load content from the linked page that's house in the #content tag. So essentially, I'd like a .home-right link, #ajax-wrap would slide toggle, and then Ajax would pull content from the linked page (which is always going to be a different random link) and it's #content div, placing that content in #ajax-wrap.
Thanks in advance for any help folks!
You want to set the ajax for the links. Requirements:
Writing a handler for links.
We must cancel the default behaviour of browser when somebody click on a link (that redirect to the page).
Removing old data ajax recieved from server and make the #ajax-wrap fresh.
Load the remote page via ajax and set it to #ajax-wrap.
Now slide it down.
// Document Ready
$(function () {
// attaching click handler to links
$("a.home-right").click(function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#ajax-wrap');
$wrap
// removing old data
.html('')
// slide it up
.slideUp()
// load the remote page
.load(href + ' #content', function () {
// now slide it down
$wrap.slideDown();
});
});
});
You can simply use the ajax like this:
$("a.home-right").click(function () {
$.ajax({
type: "get",
url: "YOUR URL HERE",
success: function(data){
$('#ajax-wrap').html(data);
$('#ajax-wrap').slideToggle();
},
error: function(){
alert("An error occured");
}
});
});
try this:
$(function(){
$("a.home-right").click(function () {
$('#ajax-wrap').slideUp();
var url = $(this).attr("href")
$.ajax({
type: "get",
url: url,
success: function(msg){
$('#ajax-wrap').html(msg)
$('#ajax-wrap').slideDown();
},
error: function(){
alert("An error occured");
}
});
})
})
Use get:
// Inside click handler
$.get('url_that_returns_data')
.done(function(response){
var $response = $(response);
$('#ajax-wrap').html($response.find('#content')).slideToggle();
});

Load Ajax Content to Hidden Tab - Instead of Current Tab

I have a dashboard UI that utilizes a jQuery tabs script. Each tab loads its content via separate Ajax requests.
Here's the issue I'm having:
A user will open multiple tabs, one right after the other
Each tab is created and an Ajax request is made for each
The last tab to be created is currently open and each tab's content is displayed on this tab once the requests are complete
Once a user clicks on any tab, the content is set as it should be.
Basically, if the user opens a new tab ahead of a recent tab's Ajax request completing, both Ajax requested contents display on the current open tab until the user clicks on any tab and then everything is displayed as it should be.
I've tried setting the Ajax calls to async: false which solves the issue as it forces the ajax requests to complete and load on the current tab before allowing the user to open another tab, however the user feedback has been negative in that users think that the dashboard froze (which it has).
I've also set a timeout function to load the tab with a loading .gif and then make the async: false Ajax request. The user feedback as been the same, even with the timeout function as the loading gif stops it's animation once the Ajax request is made.
The Ajax requests looks like this:
$.ajax ({
url: report,
cache: false,
success: function(html) {
$("#loading").hide();
$("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer">'+html+'</div>');
},
error: function(x, status, error) {
$.ajax ({
url: 'admin/error_notification.php',
type: "POST",
data:{
error: error
}
});
},
async:true
});
Keep track of the last request in some way and abort it when creating another request:
var jqxhr = {abort: function () {}};
/* various other code */
function loadTabOrWhatever() {
jqxhr.abort();
jqxhr = $.ajax({
/* ajax call in your question */
I would suggest having a separate tabcontent div that is paired with each tab (not just one #tabcontent div), and show/hide those when switching tabs. Then if a previous ajax call comes back later, and populates a tabcontent div that is now hidden, there's no harm done.
function loadTab(tabName) {
// Hide all tab content panes, then just show the one we want
$(".tab-pane").hide();
$("#tab-" + tabName).show();
$.ajax ({
...
success: function(html) {
$("#loading").hide();
$("#tab-" + tabName).append('<div id="c'+count+'" class="tabContentContainer">'+html+'</div>');
<snip>
Create your content panes like:
<div class="tab-pane" id="tab-firsttab"></div>
And trigger links would be something along the lines of:
First Tab
I believe it would make it harmless then for users to quickly click on multiple tabs, firing off multiple ajax calls, since each ajax call will only load the content into it's own content pane.
I figured out that if I create the tabContentContainer div prior to the Ajax request, then the tab selector has a object to then hide when another tab opens. Then, once the Ajax response is loaded, the visibility of it has already been set. See below:
$("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer"></div>');
$.ajax ({
url: report,
cache: false,
success: function(html) {
$("#loading").hide();
$("#c"+count+"").html(''+html+'');
},
error: function(x, status, error) {
$("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer"><div class="alert alert-error" style="margin-top:70px;"><button type="button" class="close" data-dismiss="alert">×</button><strong>Don\'t worry… It\'s not you, it\'s us.</strong> We were unable to connect to your data and deliver results. We are looking into this now.</div></div>');
$.ajax ({
url: 'admin/error_notification.php',
type: "POST",
data:{
error: error
}
});
},
async:true
});
I have such a setup. You call the function below indicating what tab you're loading into. I make sure each new tab has a unique ID (UUID) and that the function gets that ID to load the page.
There is a snag, however - I have found that if the sub pages loaded contain javascript code, that needs to initialize objects internally to the page,
they may be confused by the fact that the page is 'hidden'. Sometimes when
I get back to the tab with such elements, I would find they have a 'small' size.
This function also store the data submitted to the backend, so that you easily can create a 'reload' button.
function LoadView(ident, view, data) {
var img = $('<img>', {
src : '/images/ajax-loading.gif'
});
$('#' + ident).html(img);
data.view = view;
data.viewid = ident;
// console.log(data);
$.ajax({
url : '/cgi-bin/browser.cgi',
data : data,
type : 'GET',
dataType : 'html',
timeout : 30000000,
success : function(result) {
$("#" + ident).html(result);
// set data on view
$("#" + ident).data('data', data);
},
error : function(xhr, status, error) {
var img = $('<img>', {
src : '/images/exclamation_micro.png'
});
$('#' + ident).html(img.html() + error);
// alert("Error processing request " + error);
},
timeout : function() {
var img = $('<img>', {
src : '/images/exclamation_micro.png'
});
$('#' + ident).html(img.html() + ' Timeout');
// alert("Timeout processing request");
}
});
}
function ReloadView(view, ident) {
// Retrieve the data for the view
var data = $('#' + ident).data('data');
// Reload the view
LoadView(ident, data.view, data);
}

jquery live() appending click events causing multiple clicks

I have some strange behaviour going on with the jQuery ajax functionality in my asp.net MVC3 application.
I have several boxes of data each containing a link to open a popup and change the data in each box. To do this I've added a jquery live() click event to process the data via a jQuery ajax call. In the "success" method of the ajax call, i take the return data and open a UI Dialog popup (a partial view) which contains a list of radio buttons. I select a different radio button and press 'close' - the close button fires another live() click event, processes that new data via an ajax call which refreshes the data in the box on the main page.
This works perfectly first time. If you then click to change it again, the popup opens, allows you to select a new value, but this time pressing close on the popup triggers two click events which throws an null error in my MVC controller.
If you repeat this process it triggers 3 click events, so it's clear that live() is appending these events somewhere.
I've tried using on() and click(), but the page itself is made up of panels loaded in via ajax so I used live() to automatically bind the events.
Here is the code I'm using:
HTML
<p><!--Data to update goes here--></p>
Update Data
First Click event calling popup with Partial View
$('a.adjust').live('click', function (e) {
var jsonData = getJsonString(n[1]);
var url = '#Url.Action("ChangeOptions", "Search")';
var dialog = $('<div id="ModalDialog" style="display:none"></div>').appendTo('body');
// load the data via ajax
$.ajax({
url: url,
type: 'POST',
cache: false,
contentType: "application/json; charset=utf-8",
data: jsonData,
success: function (response) {
dialog.html(response);
dialog.dialog({
bgiframe: true,
modal: true
}
});
}
});
e.preventDefault();
});
Second click event the takes the new info to return updated partial view
$('a#close').live('click', function (event) {
var jsonData = getJsonString(n[1]);
var url = '#Url.Action("GetChangeInfo", "Search")';
$.ajax({
url: url,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: jsonData,
success: function (response) {
$('#box-' + #column).html(response); //this refreshes the box on the main page
},
error: function () {
}
});
$('#ModalDialog').dialog('close');
event.preventDefault();
});
Anybody know what might be happening here, and how I could resolve it?
Use namespaces to unbind previous click binds like this:
$('a.adjust').unbind('click.adjustclick');
Then bind the click action to a.adjust:
$('a.adjust').bind('click.adjustclick', function(){
//your code here
//note the return false, this prevents the browser from visiting the URL in the href attribute
return false;
});
If i understand you correctly, you try to run the second click action when the dialog is closed. Therefor I would use the build in close function for the dialog like this:
$('a.adjust').bind('click.adjustclick', function(){
var jsonData = getJsonString(n[1]);
var url = '#Url.Action("ChangeOptions", "Search")';
var dialog = $('<div id="ModalDialog" style="display:none"></div>').appendTo('body');
// load the data via ajax
$.ajax({
url: url,
type: 'POST',
cache: false,
contentType: "application/json; charset=utf-8",
data: jsonData,
success: function (response) {
dialog.html(response);
dialog.dialog({
bgiframe: true,
modal: true,
close: function(){
var jsonData2 = getJsonString(n[1]);
var url2 = '#Url.Action("GetChangeInfo", "Search")';
$.ajax({
url: url2,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: jsonData2,
success: function (response2) {
$('#box-' + #column).html(response2); //this refreshes the box on the main page
},
error: function () {
}
});
}
}
});
}
});
});
If you are using your own button a#close, bind a click event to it to close the dialog, it will automatically fire the close function for the dialog.
$('a#close').unbind('click.closedialog');
$('a#close').bind('click.closedialog', function () {
$('#ModalDialog').dialog('close');
return false;
}
Try this:
$('a#close').unbind('click').bind('click', function (event) {
//Your Code
});

Resources