Unexpected jQuery ajax json response - c#

I am having some strange issues with jQuery (1.7.2) ajax and asp.net.
When using the code below locally this all appears to work fine. The ajax fires fine, the modal pops up as expected, the div slides down, and I'm very happy with the result.
However, on our development server, we run into some strange issues. We start hitting the error function. In the error function, the return text isn't our JSON'd time stamp, but rather the HTML from a different page in our page flow. We've tried playing with the params to .ajax, we've tried fiddling with the modal, we've tried just returning the timestamp in our code behind method, we tried changing our dataType to text. That allowed it to fire the modal, however, Inf.innerHTML just ended up displaying the rendering of that other page in our page flow.
We've spent a bunch of time trying to debug this, but we're still stuck. Any ideas would be much appreciated.
jQuery:
$("#<%= Btn.ClientID %>").click(function() {
$.ajax({
async: true,
type: "POST",
url: "Page.aspx/Method",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$("#Modal").modal({
closeClass: "Modal-Close",
escClose: false,
opacity: 35,
overlayCss: { backgroundColor: "#000" }
}); //end Modal
//timeStamp = data.d; //Timestamp elsewhere in the js
}, //end success
error: function(xhr, status, error) { alert("xhr: " + xhr.responseText + "\n\nstatus: " + status + "\n\nerror: " + error); }
}); //end ajax
return false;
}); //end Btn.click
$(".Modal-Close").click(function() {
ModalClose();
});
var timeStamp;
function ModalClose() {
var img = document.getElementById("imgP");
var Inf = document.getElementById("Info");
var Name = document.getElementById("<%=divName.ClientID %>").value;
img.src = "difImg.png";
Inf.innerHTML = "Sometext" + Name + ", MoreText.<br />" + timeStamp;
var divO = document.getElementById("<%=divOut.ClientID %>");
$(divO).slideDown();
}
C# Page Code-behind
[WebMethod(EnableSession = true)]
public static string Method()
{
// Various magic
return "{\"d\":\"" + DateTime.Now.ToString("MMMM dd, yyyy h:mm tt") + "\"}";
}

Related

JavaScript dialog using AJAX call is out of sync

I'm having a problem with some JavaScript which is intended to display a JQUERY dialog box based on a C# ViewModel.
I have an ASP drop down within a repeater which displays 'Registration Date' information. The idea is when the user selects a date from the list, the JavaScript dialog box will appear displaying a more rounded summary of information relating to that registration using specific View Model properties. The function CustomerSummary is called on a standard $(document).ready for the page in question.
JS Code
function CustomerSummary() {
var registrationId;
var data;
$("select[id$='ddlRegistration']").change(function () {
registrationId = $(this).val();
if (registrationId !== 'default')
{
data = MakeAJAXCall(registrationId);
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
"Permit From: " + data.PermitFrom + "<br />" +
"Permit To: " + data.PermitTo + "<br />" +
"Registration Status: " + data.RegistrationStatus
);
$("#dialog").dialog({
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
}
});
}
});
function MakeAJAXCall(regId)
{
$.ajax({
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "text json",
url: "/Secure/CustomerSummary.aspx/GetRegistration",
data: "{ regId: \"" + regId + "\" }",
success: function (msg) {
data = msg.d;
},
error: function (xOptions, textStatus)
{
console.log(textStatus);
console.log(xOptions);
}
});
}
}
C# Code
[WebMethod(), ScriptMethod(UseHttpGet=false)]
public static RegistrationViewModel GetRegistration(int regId)
{
RegistrationRepository repo = new RegistrationRepository();
RegistrationViewModel reg = new RegistrationViewModel();
RegistrationFactory regFac = new RegistrationFactory();
reg = regFac.ConvertToRegistrationViewModel(repo.GetRegistration(regId));
return reg;
}
What is happening during debug
What is happening here is on this line :
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
I'm getting the error:
Uncaught TypeError: Cannot read property 'RegistrationId' of undefined
The first time I select a date from the menu and the change function is invoked, I get the above error message, and no dialog box appears, if I inspect data I can indeed see that it is undefined. Then, once I select a different data from the drop down menu, and I hit my breakpoint (change.(function) data is set to the data retrieved from the previous AJAX call, the dialog box then pops up but with the previous requests data, the results then stay in this cycle, every time I select a data I am presented with the previous selections information.
Can anyone point out why im constantly one selection out of sync, I believe its due to the first change request but I don't understand why the AJAX call isn't setting data to the desired result until I select the next drop down item.
This will not work
data = MakeAJAXCall(registrationId);
Because MakeAJAXCall is performing an Ajax call and it is asynchronous so the return will not execute in the same order as your return in the function. So, you need to use a callback.
Try this to change your code to something like:
MakeAJAXCall(registrationId, function(data){
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
"Permit From: " + data.PermitFrom + "<br />" +
"Permit To: " + data.PermitTo + "<br />" +
"Registration Status: " + data.RegistrationStatus
);
});
Then on your Ajax Call you need to make this change as well:
function MakeAJAXCall(regId, callback)
{
$.ajax({
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "text json",
url: "/Secure/CustomerSummary.aspx/GetRegistration",
data: "{ regId: \"" + regId + "\" }",
success: function (msg) {
data = msg.d;
callback(data); //<--- You callback function is called here
},
error: function (xOptions, textStatus)
{
console.log(textStatus);
console.log(xOptions);
}
});
}
First A in Ajax is for asynchronous. It means your call will run in the background and that is why you use callbacks. When your call completed with success/error, say 10 seconds later, correct function is called. In the meanwhile, you other code that sets up and creates a result also runs, most likely before any answers received from ajax query. As #Dalorzo suggested, wrap your result dialog code in a callback, so your code will run after results received.

jQuery Range Slider not working after Ajax call after updating jQuery to 1.10.2

I am working on a asp.net C# MVC web application and offers a jquery UI price range filter to filter the products based on selected price range. The resulted products are loaded via Ajax and everything seems to work fine upto now. However, after upgrading to the jQuery version 1.10.2 and jQuery UI 1.10.3, the same slider works on first load, but fails to load after Ajax requests. The following code is on the page where filter is being impelemented.
The same code is working fine with jQuery 1.7.1 and jQuery UI 1.10.0.
It appears that the slider is not initialized after content is loaded via Ajax, but not sure why! What could be wrong here?
$("#slider-range").slider({
range: true,
min: minValue,
max: maxValue,
values: [selectedMinValue, selectedMaxValue],
values: [selectedMinValue, selectedMaxValue],
slide: function (event, ui) {
//Note: Currency Custom formatting is not supported.
$(".currentMinPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + ui.values[0]);
$(".currentMaxPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + ui.values[1]);
},
change: function (event, ui) {
var url = removeParameter('#(currentURL)', "price");
var newUrl = url.replace(/&amp/g, '');
if (isAjaxRequest) {
callAjax(UpdateQueryString("price", ui.values[0] + "-" + ui.values[1], newUrl));
}
}
});
isAjaxRequest = true;
$(".currentMinPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + $("#slider-range").slider("values", 0));
$(".currentMaxPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + $("#slider-range").slider("values", 1));
}
Ajax function
$.ajax(
{
url: url,
type: 'POST',
success: function (result)
{
// Result is in html
$('#catalog').replaceWith(result);
$('#ajax-loading').hide();
DisplayFilter();
//Lazy Loading
$("img.lazy").show().lazyload(
{
effect: "fadeIn"
});
$(window).trigger("scroll");
}
});
I think you need to initialize your slider AFTER it is rendered. None of the DOM elements you create after your initial render will be intialized or bound by javascript you have already run.
So, 1st Encapsulate your initialization in a function:
function initSlider(passedMin, passedMax)
{
$("#slider-range").slider({
range: true,
min: passedMin,
max: passedMax,
values: [selectedMinValue, selectedMaxValue],
values: [selectedMinValue, selectedMaxValue],
slide: function (event, ui) {
//Note: Currency Custom formatting is not supported.
$(".currentMinPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + ui.values[0]);
$(".currentMaxPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + ui.values[1]);
},
change: function (event, ui) {
var url = removeParameter('#(currentURL)', "price");
var newUrl = url.replace(/&amp/g, '');
if (isAjaxRequest) {
callAjax(UpdateQueryString("price", ui.values[0] + "-" + ui.values[1], newUrl));
}
}
});
isAjaxRequest = true;
$(".currentMinPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + $("#slider-range").slider("values", 0));
$(".currentMaxPrice").html('#(Model.PriceRangeFilterContext.CurrencySymbol) ' + $("#slider-range").slider("values", 1));
}
}
Then in your AJAX, call your init function on success
$.ajax(
{
url: url,
type: 'POST',
success: function (result)
{
// Result is in html
$('#catalog').replaceWith(result);
$('#ajax-loading').hide();
DisplayFilter();
//Lazy Loading
$("img.lazy").show().lazyload(
{
effect: "fadeIn"
});
$(window).trigger("scroll");
initSlider(newMin, newMax)
}
});

Multiple File Upload using JQuery and C#

I am trying to perform a file upload using JQuery and c#, but I am having a lot of problems. I can't figure out how to get the file to upload. It works fine if I use FileUpload, but I am allowing the user to dynamically add files, and so I am using Jquery (ajax post to another file) in order to process the file. First I was getting a POST and enctype error, but now it just isn't doing anything. Firebug is showing me that the ajax code is failing, but doesn't tell me anything else.
Here is my jquery:
function AddDocumentsDatabase() {
$('input:file').each(function (index) {
var fileName = $(this).val();
$.ajax(
{
type: "POST",
url: "../ajaxURLs/InsertDocument.aspx?requestNumber=" + reqNum + "&fileName=" + fileName,
contentType: 'multipart/form-data',
cache: false,
success: function (html) {
alert("File Inserted!")
}
}
);
});
}
And here is the InsertDocument.aspx code:
RequestDB db = new RequestDB();
ApplicationFunctions app = new ApplicationFunctions();
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Hello");
foreach (string key in Request.Form)
{
if (!key.StartsWith("fleBrowse")) continue;
{
Response.Write(Request.Form[key].GetType());
}
}
}
If it is something really easy, I apologize, my mind isn't running at full speed, right now. Any suggestions are greatly appreciated.
I agree with shawleigh17; it's a big job, and others have done it well. I've used jQuery FileUpload (http://blueimp.github.com/jQuery-File-Upload/) with great success. However, if you do want to try to debug your code, try adding an error function to your ajax call to debug:
$.ajax(
{
type: "POST",
url: "../ajaxURLs/InsertDocument.aspx?requestNumber=" + reqNum + "&fileName=" + fileName,
contentType: 'multipart/form-data',
cache: false,
success: function (html) {
alert("File Inserted!")
},
error(jqXHR, textStatus, errorThrown) {
alert( "Error: " + textStatus + ": " + errorThrown );
}
});
try this one which given blow link :
http://www.dotnetcurry.com/ShowArticle.aspx?ID=317

How to get the OSX Style SimpleModal to work with dynamic linkbutton

First, i have quickly become a huge fan of jQuery. The simplicity has really caught my attention. I am learning something new everyday working with jQuery as i have not been working with it for that long. I have working with the SimpleModal and love its look and feel. I have come across and issue though and was wondering if there was anyone who could help me with it. I have a page that was originally making a call to the database retrieving data and populating a gridview with the data. I had the OSX Style SimpleModal attached to a linkbutton in the gridview and that worked GREAT!! However, ive decided to instead of having server-side code call the database, i will have an .ajax call which will retrieve the data. Obviously i cannot populate the gridview with the data from the .ajax call so i decided to dynamically create a table with a link inside the table hoping it would have the ability to launch the OSX Style SimpleModal the same way the gridview link did. But to my dismay, it did not. I was wondering if anyone had any ideas on how to get it to work or perhaps suggest a different technique for showing the data coming back from the .ajax call.
Here is my jQuery code:
$('#cmdSubmit_Create').click(function () {
var allowCodes;
if ($('#chkAllowValueCodes').is(':checked')) {
allowCodes = 1;
}
else {
allowCodes = 0;
}
$.ajax({
type: "POST",
url: "Test.aspx/createSource",
data: '{"schoolId":"' + $('#ddSchools').val() + '","vendor":"' + $('#txtVendor').val() + '","tsource":"' + $('#txtTSource').val() + '","allowCodes":"' + allowCodes + '"}',
contentType: "application/json",
dataType: "json",
success: function (msg) {
// Replace the div's content with the page method's return.
document.getElementById('divResults').innerHTML = msg.d;
},
error: function (xhr, status, error) {
alert('error' + error)
}
});
return false;
});
This is my code-behind:
[WebMethod]
public static string createSource(string schoolId, string vendor, string tsource, int allowCodes)
{
try
{
dsResults = Common.CreateHandPSource(tsource, schoolId, vendor, allowCodes);
return BuildTable(dsResults.Tables[0]);
}
catch
{
throw new Exception("Could not create source code!");
}
}
public static string BuildTable(DataTable dt)
{
StringBuilder sb = new StringBuilder();
int x = 0;
int y = 1;
int colCount = dt.Columns.Count;
sb.Append("<table><thead>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<th>" + column.ColumnName + "</th>");
}
sb.Append("</thead><tbody>");
foreach (DataRow row in dt.Rows)
{
sb.Append("<tr>");
do
{
sb.Append("<td>");
if (y == 0)
{
sb.Append("<a href='#' class='osx' OnClientClick='showFields(this)' >" + row["SchoolId"] + "-" + row["title"] + "</a>");
}
else
{
sb.Append(row[y]);
}
sb.Append("</td>");
y++;
}
while (y < colCount);
sb.Append("<tr>");
y = 0;
}
sb.Append("</tbody></table>");
return sb.ToString();
}
SOLUTION:
I initialize the OSX modal on the live.hover of the link and that allows the link to launch the click function for the OSX SimpleModal. Here is the code:
$('.osx').live('hover', function () {
OSX.init();
});
I see two potential problems...
You are telling the .ajax method that you expect a Json return but you are actually returning HTML.
Your data looks like a Json obect inside a string for some reason.
Try this:
$.ajax({
type: "POST",
url: "Test.aspx/createSource",
data: { schoolId: $('#ddSchools').val(), vendor: $('#txtVendor').val(), tsource: $('#txtTSource').val(), allowCodes: allowCodes},
dataType: "html",
success: function (msg) {
// Replace the div's content with the page method's return.
$('#divResults').clear().html(msg);
},
error: function (xhr, status, error) {
alert('error' + error)
}
});

Update Events Dynamically

i have a couple of queries regarding the fullcalendar by arshaw..
when i select a particular stretch of dates and give an appropriate title as shown here
i get the event rendered in the calendar.. but when i want to save the event (I'm using asp.net) ie say after the user clicks on a save button,the title,startdate,end date has to be written into the events[{}] of the script..for this im using
response.write("script /script(with the tags of course)") after the button click which doesnt work.. would anyone suggest a better or a simpler working way?
also how to disable the selectable property? eg only an admin can set the event and a user can only see the event and not edit it..
I don't think that you can update fullcalendar event JavaScript object with Response.Write() method.
You should use ajax to save event on server side and update calendar on client side.
Do something like this
function saveEvent() {
var event = { startDate: $('#txtDate').val(), description: $('#txtDescription').val(), id: id }
$.ajax({
type: "POST",
async: false,
url: "../UserCalendarService.asmx/SaveEvent",
data: "{'startDate': '" + event.startDate + "','description':'" + event.description + "','id':'" + event.id + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
result = result.d;
eventFound = $('#calendar').fullCalendar('clientEvents', result.id).length;
if (eventFound == 1) {
existingEvent = $('#calendar').fullCalendar('clientEvents', result.id);
existingEvent[0].title = result.title;
existingEvent[0].start = result.start;
existingEvent[0].editable = result.editable;
existingEvent[0].allday = true;
$('#calendar').fullCalendar('updateEvent', existingEvent[0]);
}
else {
$('#calendar').fullCalendar('renderEvent', {
title: result.title,
start: result.start,
id: result.id,
editable: result.editable,
allday: true
},
false // make the event "stick"
);
}
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
if (err.Message == 'SomeErrorMessage') {
//handleError, redirect or popup message
}
}
});
}
As for your second question, event object has editable property. It is true or false.
You can found more about it in proper documentation.

Categories

Resources