Jquery ajax gives error when moved to a .js file - asp.net-mvc-3

in a asp.net MVC3 application I have this jquery ajax function
function CheckValue() {
var Returnvalue ="";
$.ajax({
type: 'POST',
url: '#Url.Action("CheckValue", "Home")',
async: false,
success: function (Value) {
Returnvalue= Value;
},
complete: function (IsValid) {
},
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown);
}
})
return Returnvalue;
}
What it does is call an action from the HomeController called CheckValue() that returns a value.
When I had it in my view page it worked correctly. But then, I moved it to a .js file MyFunctions.js and included the file in my view
<script src="#Url.Content("~/Scripts/MyFunctions.js")" type="text/javascript"></script>
and the ajax does not work anymore.
I get an alert "Not Found"
any idea on the problem?
Thanks a lot

The problem is due to the fact that your code is now in .js file, yet it contains C# code, specifically #Url.Action("CheckValue", "Home"). .js files are not compiled or interpreted, hence the error you get. Also, the way your code was structured is incorrect. You need to return the value in the success handler due to the AJAX call being asynchronous.
The fix is to pass the url as a parameter of your function:
function CheckValue(url) {
var Returnvalue ="";
$.ajax({
type: 'POST',
url: url,
async: false,
success: function (Value) {
return Value;
},
complete: function (IsValid) {
},
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown);
}
})
}
Then in your page you can pass the C# variable to the javascript function:
<script src="#Url.Content("~/Scripts/MyFunctions.js")" type="text/javascript"></script>
<script type="text/javascript">
CheckValue('#Url.Action("CheckValue", "Home")');
</script>

A better way of injecting MVC controller url's is through a server side rendered settings JS
#{
Layout = null;
Response.Expires = 120;
Response.CacheControl = "public";
Response.ContentType = "text/javascript";
}
MyApp = {};
MyApp.settings = {
checkValueUrl: "#Url.Action("CheckValue", "Home")"
};

Related

Generating File with Ajax Fileupload

My app is an MVC .NET 4.0 application.
My application is fairly straightforward. I open an text file and uploaded it to be processed and returned as an excel file. This works as expected.
The excel file is returned via an actionresult controller. There are no errors. It works the way I want it to.
The problem is that when I call ajaxStart with blockUI it works. However, upon returning the file, the ajaxStop or ajaxSuccess is never fired to turn off the spinner after the file result is displayed with a message - do you want to open the file or save it or cancel.
I'm using jquery fileupload, blockUI and jquery 1.9.1.
$('#fileupload').fileupload({
dataType: 'json',
type: 'POST',
url: fileuploadpath,
autoUpload: true,
beforeSend: function () {
$.blockUI({
timeout: 0,
message: '<h1><img src="../images/ajax-loader.gif" /> Processing...</h1>'
});
},
complete: function() {
//$.unblockUI();
},
done: function (e, data) {
//$('.file_name').html(data.result.message.Name);
//$('.file_type').html(data.result.message.Type);
//$('.file_size').html(data.result.message.Length);
$('.file_msg').html(data.result.message.Error);
},
success: function (data) {
$.unblockUI();
$('.file_msg').html(data.result.message.Error);
}
});
and here is the basics of the file return in the action controller:
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
return File(fileoutput, "application/vnd.ms-excel");
Everything works just great. The area I'm scratching over my head is - why isn't the spinner being turned off after the file return? Am I missing something? I've tried binding ajaxStop and ajaxStart to the document but that does not work. ajaxStart gets fired but upon the file return, ajaxStop is being ignored.
Remove the 'done' and 'complete' event and use this format for your ajax call:
$(document).ready(function() {
$('#fileupload').fileupload({
dataType: 'json',
type: 'POST',
url: fileuploadpath,
autoUpload: true,
timeout:60000,
beforeSend: function () {
$('#loader').show()
},
success: function (data) {
$('#loader').hide()
//$('.file_name').html(data.result.message.Name);
//$('.file_type').html(data.result.message.Type);
//$('.file_size').html(data.result.message.Length);
$('.file_msg').html(data.result.message.Error); //??? you are passing the error here
},
error: function(jqXHR, textStatus, errorThrown) {
$('#loader').hide()
if(textStatus==="timeout") {
alert("A timeout occurred");
} else {
alert("This is an other error");
}
}
});
});
NOTE: seen you have trouble with the blockUi, I have here used a other approach.
TIMEOUT:
I have set an extra parameter 'timeout' and set this to 60 sec. You coul set this to '0' which will be unlimited but it will be better practice to give it a limited value.
Place this in your HTML and give it a style of 'display:none' and an id.
<h1><img id="loader" src="../images/ajax-loader.gif" style="display:none"/> Processing...</h1>'

What is callback function in AJAX? How to implement a callback function in PreSaveAction function of SP2013 list NewForm?

I want to store the value of a variable and use it outside the ajax call. But being an asynchronous call it is giving me initial value of that variable. I am implementing my custom code for some validations in PreSaveAction function since I have to do validations on Save button click of SharePoint NewForm,Following is my code,
<script type="text/javascript">
var titleItem;
var flg=0;
var dataFromServer;
function PreSaveAction()
{
titleItem = $("input[title='Title']").val();
$.ajax({
url:"http://sp13dev:4149/Appraisals/_api/web/lists/GetByTitle('SkillMaster')/items?$select=Id,Title&$filter=Title eq '"+titleItem+"'" ,
type: "GET",
async: false,
headers: { "Accept": "application/json; odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val() },
success: function (data) {
if(data.d.results.length>=1)
{
flg=1;
$("#labelTitle").html("Skill already exists. Please enter another name.");
}
else
{
flg=0;
$("#labelTitle").html("");
}
},
error: function (error) {
alert(JSON.stringify(error));
}
});
if(flg==1)
{
// $("#labelTitle").html("Skill already exists. Please enter another name.");
return false;
}
return true;
}
</script>
It seems like you have misplaced your return call. You should have your return placed inside your
if(data.d.results.length>=1)
statement inside the success callback function.

Rendering a simple ASP.NET MVC PartialView using JQuery Ajax Post call

I have the following code in my MVC controller:
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* drop down value */)
{
PartyInvites.Models.GuestResponse guestResponse = new PartyInvites.Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
}
Then this in my javascript at the top of my view:
$(document).ready(function () {
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});
function SetData(data)
{
$("#divPartialView").html( data ); // HTML DOM replace
}
});
Then finally my html:
<div id="divPartialView">
#Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
Essentially when a my dropdown tag (which has a class called SelectedCustomer) has an onchange fired it should fire the post call. Which it does and I can debug into my controller and it even goes back successfully passes back the PartialViewResult but then the success SetData() function doesnt get called and instead I get a 500 internal server error as below on Google CHromes console:
POST http:// localhost:45108/Home/GetPartialDiv/1 500 (Internal Server
Error) jquery-1.9.1.min.js:5 b.ajaxTransport.send
jquery-1.9.1.min.js:5 b.extend.ajax jquery-1.9.1.min.js:5 (anonymous
function) 5:25 b.event.dispatch jquery-1.9.1.min.js:3
b.event.add.v.handle jquery-1.9.1.min.js:3
Any ideas what I'm doing wrong? I've googled this one to death!
this line is not true: url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
$.ajax data attribute is already included route value. So just define url in url attribute. write route value in data attribute.
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: '#Url.Action("GetPartialDiv", "Home")',
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});

Pass Ajax POST variable to JQuery UI dialog

Below is an Ajax POST variable I use to return some information to an ASP MVC3 View. However, I cannot get the .dialg() pop-up function to work. Right now you click on the icon that calls GetProgramDetails(pgmname), and nothing happens. First time using Ajax, so any suggestions would be appreciated. Thx!
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js" type="text/javascript"></script>
<script type="text/javascript">
function GetProgramDetails(pgmname) {
var request = $.ajax({
type: 'POST',
url: '/BatchPrograms/PopDetails',
data: { programName: pgmname },
dataType: 'html'
});
request.done(function (data) {
$('#data').dialog();
});
</script>
EDIT
I've updated the request.done function to include a simple alert to see if the code was being called. After stepping through with Chrome's debugger, I saw that the code inside was completely skipped over.
request.done(function (data) {
alert("HERE!");
$('#programExplanation').html(data);
});
SECOND EDIT
Here is the controller code the ajax is returning a value from:
[HttpPost]
public string PopDetails(string programName)
{
BatchPrograms batchprograms = db.BatchPrograms.Find(programName);
if (batchprograms == null) return string.Empty;
StringBuilder s = new StringBuilder();
s.Append(batchprograms.ProgramName + " - " + batchprograms.ShortDescription);
s.Append("<br />Job Names: " + batchprograms.PrdJobName + ", " + batchprograms.QuaJobName );
s.Append("<br /> " + batchprograms.Description);
return s.ToString();
}
You need to use the success method to handle the callback, like so:
var request = $.ajax({
type: 'POST',
url: '/BatchPrograms/PopDetails',
data: { programName: pgmname },
dataType: 'html'
}).success(function(data){ $('#data').dialog()} );
This will launch the dialog for you, but if you want to get the response data to work with it, you can have GetProgramDetails take a second parameter which is a callback for after the data is loaded like so:
function GetProgramDetails(pgmname, callback) {
var request = $.ajax({
type: 'POST',
url: '/BatchPrograms/PopDetails',
data: { programName: pgmname },
dataType: 'html'
}).success(callback);
}
This way after the response is received you can handle what to do with the data in your implementation of the callback, in this case it seems like you will be setting data in the dialog and launching the dialog.

Is it possible to make multiple calls using Jsonp with deferred objects?

I'm trying to make two or more requests all at once if that's even possible? I'm concerned about speed since after the first request is made I want to display that info onto a web page and then do the same for each additional url.
I've been reading about deferred objects and trying some examples, and so far I've tried to do this,
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script >
$(document).ready(function($) {
// - 1st link in chain - var url = 'https://www.sciencebase.gov/
catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=60&offset=0&format=jsonp';
// - 2nd link in chain - var url = 'https://www.sciencebase.gov/
catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10';
// - 3rd (and last) link in chain - var url = 'https://www.sciencebase.gov/
catalog/item/4f4e4b19e4b07f02db6a7f04?format=jsonp';
// parentId url
function parentId() {
//var url = 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// itemLink url
function itemLink() {
//var url = 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log("parentId_data.items[0].title");
});
});
But it doesn't seem like the functions are functioning. I was expecting to be able to put some stuff after the .when() method inside the function to tell my program what to do, but I'm not getting anything displayed??
Thanks for the help!
Part of the problem is that in the done handler for $.when, the arguments that are passed to the callback are the array of arguments for each request, not simply the data that you want to use. You can get around this by using .pipe as in the example below.
Also, don't specify jsonpCallback unless you have a very good reason, most of the time you want to let jQuery manage that internally for you.
Here's a working example tested on JSFiddle
jQuery(function($) {
function parentId() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
// We'll use pipe here so that rather than the value being passed to our $.when handler
// is simply our data rather than an array in the form of [ data, statusText, jqXHR ]
}).pipe(function( data, statusText, jqXHR ) {
return data;
});
}
function itemLink() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
}).pipe(function(data) {
return data;
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log( parentId_data, itemLink_data );
});
});

Resources