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.
Related
I am trying to add the record to DB using Ajax and get the data back from JsonResult if success, in order to call the function further, but somehow always land in the error: parseerror. However, the record is inserted in DB.
Here is my post method:
$("body").on("click", "#btnAdd", function () {
var txtTermName = $("#txtTermsName");
var txtAlternativeTerms = $("#txtAlternativeTerms");
$.ajax({
type: "POST",
url: "/Administration/AddTerm",
data: '{name: "' + txtTermName.val() + '", alternatives: "' + txtAlternativeTerms.val() + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
var row = $("#tblTerms tr:last-child");
if ($("#tblTerms tr:last-child span").eq(0).html() != " ") {
row = row.clone();
}
AppendRow(row, r.Name, r.Alternatives);
txtTermName.val("");
txtAlternativeTerms.val("");
},
error: function(textStatus, errorThrown) {
alert("Error: " + errorThrown);
}
});
});
And my controller JsonResult:
[HttpPost]
public JsonResult AddTerm(Term term)
{
this.SaveTerm(term);
return Json(term);
}
Any comment or suggestion is appreciated
UPDATE
Json(term).Data contents:
- Json(term).Data {Models.Term} object {Models.Term}
+ ChangedBy
Description null string
ID 27 int
Inactive false bool
Name "sdfgdsgf" string
SynonymsList "sdfgdsgfdsgsdgf" string
+ Updated {09.08.2018 10:00:50} System.DateTime
Looks like an exception is being called somewhere after your database save call (I take it the SaveTerm method does more than just save the item?) resulting in an error page being returned instead of JSON - hence the parse error.
Try adding a Try { } Catch { } to the action and I reckon there will be an exception caught from the SaveTerm method.
I am trying to create Multilevel Dropdown.
I have default dropdown with values
Ex. Parent Dropdown with Id='ddl1'
If we select value from it then load data from server with selected and Create new dropdown name as child dropdown, and again select value from child and load data from server, if data present then create child dropdown.
we have to create drowpdown, till n level.
'Ex. i am creating like below'
function createdropdown(id) {
var labelHtml = "<tr id='trFormType" + id + "' class='trFormType'><td><label class='tdLabel'>" + labelFormType + " * </label></td>";
labelHtml += "<td><select class='ddlFormType' id='ddlFormType" + id + "' name='ddlFormType" + id + "' >";
labelHtml += "<option value=''";
labelHtml += ">" + labelSelect + "</option>";
labelHtml += "</select></td></tr>";
return labelHtml;
}
var selectedId=''; $(".ddlFormType").live("click", function () { selectedId= "#" + $(this).prop('id'); });
$(selectedId).live("change", function () { $.ajax({ url: Url + 'Method/' + (selectedId).val(), type: 'GET', dataType: 'json', cache: false, timeout: 9000, success: function (data) { $("#detailTable tbody").append(createdropdown(currentId)); }
});
'But .change event not get fired, for dyncamically created dropdown'
'Hope you can understand?'
For creating n level dropdowns you need to create a dropdown in ajax callback like this:
$.ajax({
url: "Your URL",
method: "GET",
dataType: 'json',
success: function (data) {
$("Your Dropdown Conatiner").append("<select><option name="option1" value="1"></option>...</select>");
},
error: function (data) {
}
});
It think your problem is that you are creating the select after the DOM has been fully loaded and jQuery has already registered all events.
If you want to add dinamically N selects you should include a call to register it inside the code you are adding to the DOM, check this sample:
<div id="select-container"></div>
<script>
function CreateSelect(id){
return `<select id="ddl` + id + `">
<option value="Opcion">Opcion<\/option>
<option value="Opcion2">Opcion 2<\/option>
<\/select>
<script>
RegisterSelectChangeEvent(` + id + `);
<\/script>`;
}
function RegisterSelectChangeEvent(id){
console.log("Event Raised");
$("#ddl" + id).on("change", function (e) {
jQuery("#select-container").append(CreateSelect(id+1));
});
}
(function(){
jQuery("#select-container").append(CreateSelect(1));
})();
</script>
You can see it working here:
https://codepen.io/anon/pen/LQRqYY
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") + "\"}";
}
I used a Jquery truncator solution which is neatly written by Henrik Nyh to have a read more/less functionality. The script here
I wanted to modify this code to be able to keep track of read/unread status by updating database. I worote the code that does the database update in a webservice as follows.
[WebMethod]
public void updateReadStatus(int ID)
{
//code to update the database
}
I added the following to consume the webservice in the Jquery
function updateStatus(){
$.ajax({
type: "POST",
url: "WebServices/myWebService/updateReadStatus",
data: "{'ID': " + $("#lblID").Text + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
error: OnError
});
function OnSuccess(reuslt) {
alert(result.d);
}
function OnError(result) {
alert(result.status + ' ' + result.status);
}
}
//and i called this function on this line
full_node.find('a:last').click(function() {
truncated_node.show(); updateStatus(); full_node.hide(); return false;
//The user control that im using this scrip on has a repeater that contains a div that contains the paragraph to be truncated.
<div class="readmore">
<%# Eval("Message_Text")%>
<asp:Label ID="lblID" runat="server" visible="false"
</div>
The truncate script works fine and it gave me the functionality i want, read more/less. But i am not able to get the added functionality i wanted. I am getting "12030 unknown" error, i believe the problem is in the line data:
"{'ID': " + $("#lblID").Text + "}",
how can I bring the value of the parameter ID from the text value of the lable to pass it to the webservice?
text is a function, not a property, so you need to call it with ():
"{'ID': " + $("#lblID").text() + "}",
Also, if you want to call a given WebMethod via Ajax, you'll need to decorate it with the [ScriptMethod] attribute.
You don't say what lblID identifies, but you should either be doing:
$("#lblID").text()
or
$("#lblID").val()
See http://api.jquery.com/text/ and http://api.jquery.com/val/
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.