Json string not finding controller method - javascript

Using a third party plugin for javascript, fullcalendar. One of the options is a dayClick event, which is pretty obvious on what it does. As soon as a day is clicked it performs an action.
So I got ajax in this dayClick function and I'm trying to pass a value to the controller.
$(document).ready(function () {
$('#calendar').fullCalendar({
height: 170,
selectable: true,
editable: true,
defaultView: 'basicWeek',
dayClick: function (date, jsEvent, view) {
$.ajax(
{
url: '#Url.Action("Calendar","Home")',
type: "GET",
data: JSON.stringify({ date: date }),
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
success: function (response) {
$("calendarLoad").append($(response));
$('#myModal').modal();
},
error: function (request, status, error) {
alert(error);
alert(status);
alert(request.responseText);
}
});
}
});
});
If it successfully passes its supposed to write out my partial view. But it doesn't get to this point. I've debugged my controller and the date parameter is null.
[HttpGet]
public ActionResult Calendar(string date)
{
string[] dateSplit = date.Split(new char[] { 'T' });
DateTime objDate = Convert.ToDateTime(dateSplit[0]);
var content = db.Calendars.Where(x => x.startDate == objDate).ToList();
return PartialView(content);
}
I'm using fiddler to monitor the results after using the dayClick function and I see it trying to pass the JSON data but the result is always
No results.

It should just be:
data: { date: date },
without any call to JSON.stringify(). jQuery will convert that object into the appropriate form for the HTTP request. When you pass it a string, it assumes that you've already done the conversion so it just uses the string directly (as you can see in that URL you highlighted in the screenshot).

Related

Data passing error from javascript to controller

I'm working on ASP.NET MVC project , I want to get location dropdown selected value and according to that i need to load values to City dropdown , i implemented following code and location dropdown onselect event call the javascript function and javascript function call the controller method but when executing controller method locationId is null ,and i debug javascript and locationID is there till the this line data: JSON.stringify({ locationId: +locationId }), after that javascript returns error.but controller method get hit but locationId null
code for dropddowns
<div class="row">
<div class="col-sm-4">
#Localizer["Locations"]
<select id="locationDropDown" class="selectpicker form-control" asp-for="selectedLocation" onchange="getCityList()">
<option value="0"><None></option>
#foreach (var item in Model.LocationList)
{
<option value="#item.Id">#item.Name</option>
}
</select>
</div>
</div>
<div class="row">
<div class="col-sm-4">
#Localizer["KioskGroup"]
<select id="cityDropDown" class="selectpicker form-control">
<option>---Select City---</option>
</select>
</div>
</div>
Javascript code
function getCityList()
{
debugger;
var locationId = $("#locationDropDown").val();
console.log(locationId)
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
datatype: 'application/json',
contentType: 'application/json',
data: JSON.stringify({ locationId: +locationId }),
success: function (result) {
$("#cityDropDown").html("");
$("#cityDropDown").append
($('<option></option>').val(null).html("---Select City---"));
$.each($.parseJSON(result), function (i, zone)
{ $("#cityDropDown").append($('<option></option>').val(zone.Id).html(zone.Name)) })
},
error: function(){alert("Whooaaa! Something went wrong..")},
});
controller method
public ActionResult GetZoneListBYlocationID(string locationID)
{
List<Zone> lstZone = new List<Zone>();
long locationId = long.Parse(locationID);
var zones = _zoneRepository.GetZonesByLocationId(locationId);
return Json(JsonConvert.SerializeObject(zones));
}
Your current code is sending the json string {"locationId":101} in the request body because you specified the contentType as application/json. This is useful when you want to send an object with multiple properties and your action method parameter is a DTO/POCO class type. Model binder will be reading from the request body and map it to the parameter.
In your case, all you are sending is a single value. So do not send the JSON string. simply create a js object and use that as the data attribute value. Also remove the contentType: application/json as we are not sending a complex js object as json string.
Also application/json is not a valid option for the dataType property. You may use json. But jQuery is smart enough to guess the value needed here from the response headers coming back from server. So you may remove it.
function getCityList() {
var locationId = $("#locationDropDown").val();
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
data: { locationID: locationId },
success: function (result) {
console.log(result);
// populate dropdown
},
error: function () { alert("Whooaaa! Something went wrong..") },
});
}
Now this data will be send in Form Data as locationID=101 with Content-Type header value as application/x-www-form-urlencoded and will be properly mapped to your action method parameter.
You should use the correct types. In your action method, you are using string as your parameter and later trying to convert it to long. Why not use long as the parameter type ? Also if zones variable is a list of Zone object, you can pass that directly to the Json method. No need to create a string version in between.
public ActionResult GetZoneListBYlocationID(long locationId)
{
var zones = _zoneRepository.GetZonesByLocationId(locationId);
return Json(zones);
}
Why you are stringify the data.Below one should work without stringify
data: { locationId: +locationId },
I was facing the same problem. and after that, I have tried below solution.
Hope it will help you.
ajax call is as follows:
$.ajax({
type: 'POST',
url: "/Account/GetCities",
dataType: 'json',
data: { id: $("#StateID").val() },
success: function (states) {
$.each(states, function (i, state) {
$("#CityID").append('<option value="' + state.Value + '">' + state.Text + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve cities.' + ex);
}
});
The controller code is as follows:
public List<CityModel> GetCities(int id)
{
//your code
}
You can do in your application like this:
function getCityList()
{
var locationId = $("#locationDropDown").val();
console.log(locationId)
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
dataType: 'json',
data: { locationId: locationId },
success: function (result) {
$("#cityDropDown").html("");
$("#cityDropDown").append
($('<option></option>').val(null).html("---Select City---"));
$.each($.parseJSON(result), function (i, zone)
{ $("#cityDropDown").append($('<option></option>').val(zone.Id).html(zone.Name)) })
},
error: function(){alert("Whooaaa! Something went wrong..")},
});
}
And your controller will be same as you have done.

Updating HTML after Ajax or jQuery call

I've created two calls, one is ajax call to my controller, and other one is jquery call. I've did both just to check if my HTML would update once I trigger the event... But none of these methods update my HTML (it stays the same way). Here are the methods:
Method #1:
$("#btnSearch").click(function(){
var startDate = $.trim($("#startDate").val());
var endDate = $.trim($("#endDate").val());
$.post("/history/list",{'startDate':startDate,"endDate":endDate},function(data){
var result = $('<div />').append(data).find('#historyList').html();
$('#historyList').append(result);
console.log(result);
// the result is displayed correctly in the console...
});
});
// This is supposed to update my HTML in the browser now, but it's not showing anything new...
Method #2:
$('#btnSearch').click(function () {
console.clear();
$.ajax({
url: "/history/list",
data: {
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
type: "GET",
dataType: "html",
success: function (data) {
var result = $('<div />').append(data).find('#historyList').html();
$('#historyList').append(result);
console.log(result);
// the result is displayed correctly in the console...
},
error: function (xhr, status) {
alert("Sorry, there was a problem!");
},
complete: function (xhr, status) {
//$('#showresults').slideDown('slow')
}
});
});
None of these methods update my HTML once the call is finished and data is returned... The data object holds the HTML as the result, and I'd like that HTML in the data object replaces everything what is in div tag under id #historyList.. What am I doing wrong here?
P.S. I'm using chrome browser (if this is a useful information)
I don't get the result. Could you use .html, like so:
$('#historyList').html(data);
Or the whole code like this.
$('#btnSearch').click(function () {
console.clear();
$.ajax({
url: "/history/list",
data: {
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
type: "GET",
dataType: "html",
success: function (data) {
$('#historyList').html(data);
console.log(result);
// the result is displayed correctly in the console...
},
error: function (xhr, status) {
alert("Sorry, there was a problem!");
},
complete: function (xhr, status) {
//$('#showresults').slideDown('slow')
}
});
});
Make sure $('#historyList') is not an empty array and exists in the DOM. If it exists,
$('#historyList').html(data);
should solve the problem.
Correct me, if my understanding of the question is wrong.

ajax request not sending any data ASP.NET MVC project with jQuery

I'm fairly new to asp.net MVC but am baffled as to why my request isn't working.
I'm trying to send an ajax request with jquery as per:
jQuery(function ($) {
var total = 0,
share = $('div.share'),
googlePlusUrl = "https://plusone.google.com/_/+1/fastbutton?url=http://bookboon.com" + $(location).attr('pathname');
setTimeout(function() {
$.ajax({
type: 'GET',
data: "smelly",
traditional: true,
url: share.data('proxy'),
success: function(junk) {
//var $junk = junk.match(regex);
console.log(junk);
},
error: function (xhr, errorText) {
console.log('Error ' + xhr.responseType);
},
});
}, 4000);
And set a line in my RouteConfig as:
routes.MapRoute(null, "services/{site}/proxy", new { controller = "Recommendations", action = "Proxy" });
The markup has a data-attribute value as:
<div class="share" data-proxy="#Url.Action("Proxy", "Recommendations")">
And my Proxy action method starts with:
public ActionResult Proxy(string junk)
The problem is that the junk parameter is always null. I can see in the debug output that the route seems to correctly redirect to this method when the page loads (as per jQuery's document ready function), but I cannot seem to send any data.
I tried sending simple data ("smelly") but I don't receive that neither.
Any suggestions appreciated!
The model binder will be looking for a parameter in the request called junk, however you're sending only a plain string. Try this:
$.ajax({
type: 'GET',
data: { junk: "smelly" }, // <- note the object here
traditional: true,
url: share.data('proxy'),
success: function(junk) {
//var $junk = junk.match(regex);
console.log(junk);
},
error: function (xhr, errorText) {
console.log('Error ' + xhr.responseType);
},
});

Using fullcalendar.io with JSONP

I'm trying to add public holidays to full calendar. http://fullcalendar.io/
var actionUrl = #Html.Raw(Json.Encode(#Url.Action("Calendar", "Lecture")));
$('#fullcalendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
eventTextColor : "Black",
eventSources: [
{
url: actionUrl,
data: function() {
return {
campusIds: getCampusIds(),
lectureRoomIds: getLectureRoomsIds(),
lecturerIds: getLecturerIds(),
eventTypeIds: getEventTypeIds(),
}
},
error: function() {
alert('there was an error while fetching events!');
},
traditional: true
},
{
url: "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=zaf?callback=?",
error: function() {
alert('there was an error while fetching events!');
},
}
],
The first event source works and that fetches json from my mvc controller. The second source however doesn't. I understand I need to use jsonp and I think I need to map the returning data over to something that full calendar understands but I can't get this right. Please assist!
Thanks
Revised answer
I've found a solution. The service you are using for your dates has the API documentation here. The relevant portion:
JSONP
In each operation you can use JSONP like this: Sample URL returning
public holidays in Austria for January 2013:
JSON_URL?action=getPublicHolidaysForMonth&month=1&year=2013&country=aut&jsonp=myfunction
So change callback to jsonp and it should work. Also, it works best with FC if you give a range instead of a month. Your ajax call should look like:
events: function (start, end, timezone, callback) {
console.log(start.format('YYYY-MMM'));
$.ajax({
type: "get",
url: 'http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForDateRange&jsonp=?',
data: {
country: "zaf",
fromDate: start.format('DD-MM-YYYY'),
toDate: end.format('DD-MM-YYYY')
},
dataType: 'jsonp',
contentType: 'application/json',
success: function (data) {
var events = [];
$.each(data, function (i, holiday) {
events.push({
start: moment({
year: holiday.date.year,
month: holiday.date.month - 1, //momentjs uses base 0 months
day: holiday.date.day
}),
title: holiday.englishName,
allDay: true
});
});
callback(events);
}
}).fail(function (jqXHR) {
alert("failed to get holidays");
});
Here is a working JSFiddle.
Old answer: (still applicable for non-jsonp servers)
If you are trying to do a cross domain json request (jsonp), the server needs to support it.
JSONP requests are wrapped in script tags and must therefore be valid JS. A literal object is not valid JS (like {a:'b'}).
jQuery handles this by sending a callback function name parameter to the server. It looks like:
callback=jQuery21003313164389692247_1423682275577
The server must wrap the response data in this function like:
jQuery21003313164389692247_1423682275577( {id:"2",name:"me"} );
which is now valid and executable JS.
So, unless that server's API allows for JSONP requests, you cannot do cross domain requests to it. This is a security limitation of web browsers.
As an alternative, you could proxy the data through your server. Have fullcalendar make requests to your server which in turn loads data from the external source and sends it back to the client.
To begin with you need to make a call with valid parameters to the url i.e.
http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=eng
This would return data in the following format:
[{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}]
It is then a case of translating that data into the format that expects i.e. EventData.
This is done by iterating over the date objects returned via the json as follows but setting the properties you need (in the below demo I set the title and start):
var items = [];
$.each( json, function( key, val ) {
items.push({ title : val.localName, start : val.date } );
});
This all needs to be wrapped up in a getJson call i.e.
$.getJSON( "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=3&year=2013&country=eng", function( data ) {
$.each( data, function( key, val ) {
items.push({ title : val.localName, start : val.date } );
});
});
You can the set your calendar items as follows (simplified for demo):
$('#calendar').fullCalendar({
events: items
});
jsFiddle
var items = [];
var json = [{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}]
$.each( json, function( key, val ) {
items.push({ title : val.localName, start : val.date } );
});
$('#calendar').fullCalendar({
events: items
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.css" rel="stylesheet"/>
<div id='calendar'></div>

JQuery popup not working after continuous call

I'm using MVC 4 for my project and im trying to edit or display my data on popup.
When I call my open popup code 6 or 7 times I take javascript errors.
my controller is
public ActionResult OpenEditForm(string objectParam, string formStatus)
{
BranchNotesDetailViewModel viewModel = new BranchNotesDetailViewModel();
//..................
return PartialView("Edit", viewModel);
}
and my javascript code is
myDialog = $("<div> </div>");
function CreateDialog(name) {
myDialog.dialog({
autoOpen: false,
title: name,
resizable: false,
position: 'center',
stack: true,
height: 'auto',
width: 'auto',
modal: true,
close: function (event, ui) {
// remove div with all data and events
myDialog.remove();
//myDialog.dialog('close')
}
});
}
$('#brancNotesList .grid-row').click(function () {
var json = $(this).children('td:eq(1)').text().trim();
$.ajax({
contentType: 'application/html',
url: '#Url.Action("OpenEditForm", "BranchNotes")',
dataType: 'html',
type: 'GET',
data: {
objectParam: json,
formStatus: "1"
}
}).done(function (result) {
CreateDialog('Detail');
myDialog.html(result).dialog('open');
});
});
$(function () {
$(document).ajaxComplete(function (event, request, settings) {
//re-parse the DOM after Ajax to enable client validation for any new form fields that have it enabled
$.validator.unobtrusive.parse(document);
});
});
function openFormCreate() {
$.ajax({
contentType: 'application/html',
url: '#Url.Action("OpenEditForm", "BranchNotes")',
dataType: 'html',
type: 'GET',
data: {
formStatus: '2'
}
}).done(function (result) {
CreateDialog('Detail');
myDialog.html(result).dialog().dialog('open');
});
}
When i open dialogs one or two times it works but after fifth or sixth time it crashes with exception
JavaScript runtime error: Could not complete the operation due to error 80020101
I tried to find a memory problem or something after ajax call but i cant find where or what. Is there any way to handle that? I read about that problem some forums they say comments fields cause that but it not works for me.
I found my error. I have two layouts, one for main page one for edit page and i noticed some Jquery script files rendered in both pages. I cleaned the edit layout from jquery scripts then everything works fine.

Categories

Resources