So I am dealing with this weird service when returns a html page as the ajax response which has a form and the form is triggered automatically by some scripts in the page (so when you render the page a post request will be sent to you). What I am trying to do is to load this page I am getting from the response.
Say this is my Ajax call:
var ajax_call_test = function() {
var formData = new FormData($('#documentForm')[0]);
console.log("doc form: " + formData);
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
$.ajax("/documents/upload/", {
type: 'POST',
data: formData,
processData: false,
contentType: false,
cache: false,
async: false,
dataType: 'html',
success: function(html){
// ?
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("failed: " + errorThrown);
}
});
}
So I tried to use .html to set the response to a hidden <div>. It sets the html but never triggers the form. I am guessing the javascript in that page is not loaded when I use .html.
I also cannot use jQuery.parseHTML() since the version of library I am using does not support that functionality. Any idea what should I do with response?
When ever you load new html into the DOM. The javascript does not know about it.
I have to re invoke my javascript to work with the new DOM.
Lets say I have some click events
$(function(){invokeClicks()}) // onload call
function invokeSomeAction(){
$("selector").off(); // disable previous events from old html
$("selector").on("event", function(){
// handle event
})
}
function invokeClicks(){
invokeSomeAction();
// ... etc
}
So when this JS loads, the invokeClicks() method gets called.
Now, if I replace the HTML through a $.ajax() call, all I have to do is call invokeClicks() again to clear the old events and now the new HTML will work with the javascript
$.ajax({
url: "somepath",
data: {id: 1},
method: "GET",
success: function(html){
$("container_selector").html(html);
invokeClicks(); // reinit
},
})
Related
I have setup properties in my Ajax Request not to store cache. I have also added query string as a parameter in the URL to call new Ajax request. But whenever i refresh the page i see old content on the page. I always have to hard refresh a page to see the updated content.
The request headers are getting passed to the browser correctly which i have set in the properties of ajax. But why do i always have to hard refresh to get the updated content. How can i load the new content on just a page refresh. I have pasted my Ajax below
AJAX Methods to set the properties
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.type == 'POST') {
options.url += '?' + Date.now();
}
});
$.ajaxSetup({
cache: false,
headers: {
'Cache-Control':'max-age=0, public'
},
});
My JQuery
$.ajax({
url: "/Configuration/TestPlan/GetUserList",
type: 'POST',
cache: false,
dataType: 'json',
// async :false,
beforeSend: function () {
//call pageloader
showImageLoader();
},
data:jsonString,
contentType: "application/json; charset=utf-8",
success: function (data) {
From jquery - ajax - "If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests" -
So I don't think the cache option is doing what you think. Since it's a POST the only thing that will affect the cache-busting is that little snippet you have:
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.type == 'POST') {
options.url += '?' + Date.now();
}
});
Every time it makes a request - that page is actually being cached. It just does a new Date.now() - then that url is cahced until you do a new Date.now().
So when you comment it out - the last page/data called for is cached and now you've commented out the only thing updating the cachebuster.
Perhaps just apply the cache busting directly to the raw call:
$.ajax({
url: "/Configuration/TestPlan/GetUserList?" + Date.now(),
type: 'POST',
cache: false,
dataType: 'json',
// async :false,
beforeSend: function () {
//call pageloader
showImageLoader();
},
data:jsonString,
contentType: "application/json; charset=utf-8",
success: function (data) {
I am using angular datatables and I have some code that looks like this:
this.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
type: 'POST',
contentType: 'application/json',
processData: false,
beforeSend: function(xhr, settings) {
...
},
data: function(data) {
...
}
})
.withDataProp('data')
.withOption('processing', true)
.withOption('serverSide', true);
That all works properly and the table on the page is populated with data when the ajax call returns. All I want to do now is detect when that ajax call completes. I have tried to use this right below beforeSend:
success: function(data, textStatus, jqXHR, fnCallback) {
console.log(data);
}
That actually prints the returned data to the console, but when I add that success callback the table on the page never populates with the data. So how can I have a callback fire when the ajax is done and still have my table on the page populate with data like it normally does?
dataTables is using the ajax success callback internally, so you break things up if you override that. However, dataTables introduces its own dataSrc callback which is fired from within dataTables success handler to give you the upportunity to manipulate the response before any data is inserted :
this.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
dataSrc: function(json) {
//success!
console.log(json);
return json
},
type: 'POST',
contentType: 'application/json',
processData: false,
....
see demo -> http://plnkr.co/edit/94EWyDanIawCJJgyagiy?p=preview
As you may see in the demo, you also have an alternative in the ajax complete callback :
ajax : {
complete: function(jqXHR, textStatus) {
console.log(jqXHR.responseText)
}
..
}
I have tried to use AJAX call in an MVC5 project as many similar examples on the web, but every time there is an error i.e. antiforgerytoken, 500, etc. I am looking at a proper AJAX call method with Controller Action method that has all the necessary properties and sending model data from View to Controller Action. Here are the methods I used:
View:
#using (Html.BeginForm("Insert", "Account", FormMethod.Post, new { id = "frmRegister" }))
{
#Html.AntiForgeryToken()
//code omitted for brevity
}
<script>
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};
$('form').submit(function (event) {
event.preventDefault();
//var formdata = JSON.stringify(#Model); //NOT WORKING???
var formdata = new FormData($('#frmRegister').get(0));
//var token = $('[name=__RequestVerificationToken]').val(); //I also tried to use this instead of "AddAntiForgeryToken" method but I encounter another error
$.ajax({
type: "POST",
url: "/Account/Insert",
data: AddAntiForgeryToken({ model: formdata }),
//data: { data: formdata, __RequestVerificationToken: token },
//contentType: "application/json",
processData: false,
contentType: false,
datatype: "json",
success: function (data) {
$('#result').html(data);
}
});
});
</script>
Controller: Code cannot hit to this Action method due to antiforgerytoken or similar problem.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult Insert(RegisterViewModel model)
{
try
{
//...
//code omitted for brevity
}
}
I just need a proper AJAX and Action methods that can be used for CRUD operations in MVC5. Any help would be appreciated.
UPDATE: Here is some points about which I need to be clarified:
1) We did not use "__RequestVerificationToken" and I am not sure if we send it to the Controller properly (it seems to be as cookie in the Request Headers of Firebug, but I am not sure if it is OK or not). Any idea?
2) Should I use var formdata = new FormData($('#frmRegister').get(0)); when I upload files?
3) Why do I have to avoid using processData and contentType in this scenario?
4) Is the Controller method and error part of the AJAX method are OK? Or is there any missing or extra part there?
If the model in your view is RegisterViewModel and you have generated the form controls correctly using the strongly typed HtmlHelper methods, then using either new FormData($('#frmRegister').get(0)) or $('#frmRegister').serialize() will correctly send the values of all form controls within the <form> tags, including the token, and it is not necessary to add the token again.
If your form does not include a file input, then the code should be
$('form').submit(function (event) {
event.preventDefault();
var formData = $('#frmRegister').serialize();
$.ajax({
type: "POST",
url: '#Url.Action("Insert", "Account")', // do not hard code your url's
data: formData,
datatype: "json", // refer notes below
success: function (data) {
$('#result').html(data);
}
});
});
or more simply
$.post('#Url.Action("Insert", "Account")', $('#frmRegister').serialize(), function(data) {
$('#result').html(data);
});
If you are uploading files, then you need you need to use FormData and the code needs to be (refer also this answer and
$('form').submit(function (event) {
event.preventDefault();
var formData = new FormData($('#frmRegister').get(0));
$.ajax({
type: "POST",
url: '#Url.Action("Insert", "Account")',
data: formData,
processData: false,
contentType: false,
datatype: "json", // refer notes below
success: function (data) {
$('#result').html(data);
}
});
});
Note that you must set both processData and contentType to false when using jQuery with FormData.
If you getting a 500(Internal Server Error), it almost always means that your controller method is throwing an exception. In your case, I suspect this is because your method is returning a partial view (as suggested by the $('#result').html(data); line of code in you success callback) but you have specified that the return type should be json (your use of the datatype: "json", option). Note that it is not necessary to specify the dataType option (the .ajax() method will work it out if its not specified)
If that is not the cause of the 500(Internal Server Error), then you need to debug your code to determine what is causing the expection. You can use your browser developer tools to assist that process. Open the Network tab, run the function, (the name of the function will be highlighted), click on it, and then inspect the Response. It will include the details of the expection that was thrown.
contentType should be application/x-www-form-urlencoded
Try this code
<script>
$('form').submit(function (event) {
event.preventDefault();
$.ajax({
method: "POST",
url: "/Account/Insert",
data: $(this).serialize(),
contentType:"application/x-www-form-urlencoded",
success: function (data) {
$('#result').html(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
</script>
I am uploading a document to the server, using PHP and AJAX with JS on button click. I collect the form data make its object append the file data and pass it via AJAX to the function upload.php. The code works completely well in Chrome but fails to give the same effect in FF. Code is attached Further. What is the possible solution to the problem ?
$(document).on('click', '#uploadDocument', function()
{
var formData = new FormData();
formData.append('fileToUpload', $("#fileToUpload").prop("files")[0]);
$.ajax({
url: 'upload.php',
dataType: 'text',
cache: false,
contentType: false,
processData: false,
data: formData,
type: 'post',
success: function (status){
if(status == 'File Uploaded')
{
$('#listTable').load('showList.php');
}
else
{}
}
});
});
this is likely because of the default action of the form, you need to prevent that. pass in event to your onclick function and then use event.preventDefault(); on the first line in the function
I have page that displays data through AJAX, till the time the result is being fetched I wish to display a loader and as soon as the result is fetched I want that the loader should disappear. Below is part of the code where I am trying to display the loader
var onSubmit = function(e)
{
var txtbox = $('#txt').val();
var hiddenTxt = $('#hidden').val();
$("#walkaway").hide();
$("#submitamt").hide();
$("#xtrabutton").hide();
LodingAnimate();
$.ajax(
{
type: 'post',
url: 'test2.php',
dataType: 'json',
data: {txt: txtbox,hidden: hiddenTxt},
cache: false,
success: function(returndata)
{
$('#first').html(returndata[0]);
$('#second').html(returndata[0]);
$('#third').html(returndata[0]);
},
error: function()
{
console.error('Failed to process ajax !');
}
});
function LodingAnimate()
{
$("#maillist").html('<img src="img/ajax-loader.gif" /> Please Wait Loading...');
}
};
On click of a button the above AJAX is executed, after the click the loader runs but even after I get the reply(in console) the loader keeps on running, but in actual it should have disappeared.
You should hide/remove the loader manually after ajax call completes, add Jquery Complete call back and add the code to remove the loader in it.
Jquery Complete - This call back will execute after success and error call back executed.
$.ajax(
{
type: 'post',
url: 'test2.php',
dataType: 'json',
data: {txt: txtbox,hidden: hiddenTxt},
cache: false,
success: function(returndata)
{
//Success code
},
error: function()
{
//error code
},
complete:function()
{
//This block will execute after success/error executes.
//Make the loader div empty
$("#maillist").empty();
}
});