Fullcalendar - two Ajax callbacks - asp.net

I am struggling with situation of geting events from two different resources. I know that as ajax is asynchronous I cant get more than one callbacks and my code is proving that - By reloading the page I am getting random results from one or other query. But there must be some workaround, right? I just wanna get combined array of both events and vacations so I can pass it to fullcalendar as one instance. Thanks a lot!
var events = [];
var vaca = [];
var now = moment();
var nextMonth = now.clone().add(1, 'month');
$.ajax({
type: "GET",
url: "/home/GetEvents",
success: function (data) {
$.each(data, function (i, v) {
//alert(v.id);
events.push({
title: v.title,
description: "Project Type: " + v.projectType,
start: moment(v.onSite),
end: v.onSiteTill != null ? moment(v.onSiteTill).add('days', 1) : null,
color: v.color,
allDay: true
});
})
GenerateCalendar(events);
},
error: function (error) {
alert('failed');
}
})
$.ajax({
type: "GET",
url: "/home/GetVacations",
success: function (data2) {
$.each(data2, function (i, v) {
//alert(v.who);
vaca.push({
title: v.who,
description: ("Who or what: " + v.who + ". Vacation because " + v.why).link("Vacation/Edit/" + v.id),
start: moment(v.fromWhen),
// add one day due to excluding end date in callendar
end: v.tillWhen != null ? moment(v.tillWhen).add('days', 1) : null,
color: "#cc0000",
allDay: true
});
})
GenerateCalendar(vaca);
},
error: function (error) {
alert('failed');
}
})

You can call next Ajax call from first AJAX call.
Sample Code for Reference:
$.ajax({url: URL, data : {//data
}).done( function( data ) {
// Handles successful responses only
}).fail( function( error) {
console.log( error);
}).then( function( data ) { // Promise finished
$.ajax( { //2nd ajax
url : URL,
data : { DATA }
}).done( function( data ) {
// 2nd call finished
}).fail( function( reason ) {
console.log( error);
});
});

Generate your calendar first then make 2 calls to render the events. You can use the FullCalendar renderEvent or renderEvents to achieve this.
I have created a basic working example here.

Related

FullCalendar V4 How to set attribute of calendar event after drop

I'm using FullCalendar V4 callback function drop. I try to pass myID which are generated by server to be Calendar event.id, but I do not know how to do. The following is simple code
var calendar = new Calendar(calendarEl, {
drop: function( dropInfo ) {
$.getJSON( url, myParams, function( data ) {
// try to set data.myID to FullCalendar event id
calendarEvent = { id : data.myID };
});
},
eventClick: function( eventClickInfo ) {
var msg = "Are you sure to delete[" + event.title + "]?";
if ( confirm(msg) ) {
// It fails, because I can't get event.id
var params = { method: "deleteEvent", id: event.id };
$.get(url, params, function( data ){
eventClickInfo.event.remove();
});
}
}
});
I have tried to putcalendar.refetchEvents(); into the drop: $.getJSON(function(){}) response block, but FullCalendar makes 2 event in UI. One has balnk attribute, the other has right attribute. If I can eliminate the redundancy, it will be a good solution.
Thanks for ADyson's suggestion. Finally, I used callback function eventReceive solving the problem. The following is my simple code
var calendar = new Calendar(calendarEl, {
eventReceive: function( info ) {
var $draggedEl = $( info.draggedEl );
var params = { method: "insert" };
$.ajaxSetup({ cache: false, async: false});
$.getJSON( myURL, params, function( data ){ // insert information into DB
info.event.setProp( "id", data.id );
});
},
eventClick: function( info ) {
var event = info.event;
var msg = "Are you sure to delete[" + event.title + "]?";
if ( confirm(msg) ) {
var params = { method: "deleteEvent", id: event._def.id };
$.get( myURL, params, function( data ){
event.remove();
});
}
},
});

Meteor pub/sub issues

This below is my collection code
Competitions = new Mongo.Collection("competitions");
var CompetitionsSchema = new SimpleSchema({
year: {
type: String
},
division: {
type : String,
allowedValues: ['Elite', '1st','2nd','3rd','4th','Intro']
},
teams:{
type : [TeamSchema],
allowedValues: (function () {
return Teams.find().fetch().map(function (doc) {
return doc.name;
});
}()) //here we wrap the function as expression and invoke it
}
});
In the allowedValues function
Teams.find is empty.
In the router I am subscribing to the publication as follows
this.route('competitions', {
path: '/admin/competitions',
layoutTemplate: 'adminLayout',
waitOn: function () {
return [
Meteor.subscribe('teams')
];
}
});
This is my publish function
Meteor.publish('teams', function() {
return Teams.find({},{sort: {
points: -1,
netRunRate : -1
}});
});
Do I have to do subscription some where else as well?
Your problem is in this piece of code:
allowedValues: (function () {
return Teams.find().fetch().map(function (doc) {
return doc.name;
});
}()) //here we wrap the function as expression and invoke it
This gets called when the page loads. At that point the Teams collection will still be empty on the client side. You need to wait until the data is ready. Since you are using waitOn in iron-router, it might be enough to just move this code to the onRendered callback.

Ajax doesn't trigger success - ASP

First of all I looked trough a lot of same questions on stack. My problem is as follows:
I'm working on a school project to make a card game (ginrummy)
In this web application (mvc 4) I want to move cards to sets (right side) and I want to do this with ajax.
added a picture to clearify.
The ajax perfectly triggers the controller and perfectly bring over the data I put through.
In firebug I checked the response and it even added a card to the right correct set
The problem is when the ajax is done, it doesn't trigger the succes function neither it updates the page.
Note: This is my first time I work with ajax.
The complete function returns OK status.
Now the code:
View:
var GameId = #Model.Id
$(function () {
$(".droppable").droppable({
drop: function (event, ui) {
var id = ui.draggable.find("a").attr("data-CardId");
var location = droppableId = $(this).attr("id");
$.ajax({
type: "POST",
url: '#Url.Action("ChangeCardLocation")',
data: { 'id': GameId, 'cardId': id, 'location': location },
succes: function () {
alert('wow');
},
complete:function (){
}
});
}
});
});
Controller:
public ActionResult ChangeCardLocation(int id, int cardId, Location location)
{
var game = db.Games.Find(id);
var card = db.Cards.Find(cardId);
game.ChangeCardLocationTo(card, location);
db.SaveChanges();
game.Info = game.GetInfo(id);
if (game.GameState == GameState.playerOneLayOn || game.GameState == GameState.playerTwoLayOn)
{
return View("LastTurn", game);
}
else
{
return View("Details", game);
}
}
Any suggestions on what is going wrong?
I'm a student and it is for a school project!
#comment:
When I did this:
error: function(xhr, error){
console.log(error);
console.log(xhr);
},
I noticed it didn't get triggerd.
After that I tried the same in complete:
complete:function (xhr, error){
console.log(error);
console.log(xhr);
}
The result was
succes
object that returned readystate 4
I misspelled success thats in the first part it wasn't working. But my next question is how do make it updating the contents of the page that the ajax call is getting back.
I am trying myself offcourse now. In the data succes is getting is my whole page delivered as I want to have it.
Is it because you have misspelt "success"?
$.ajax({
type: "POST",
url: '#Url.Action("ChangeCardLocation")',
data: { 'id': GameId, 'cardId': id, 'location': location },
success: function () {
alert('wow');
},
complete:function (){
}
});

How can I return a value from a function that uses a jQuery ajax call?

I have the following Javascript function that makes a call to an Asp.Net WebMethod that returns true if a username already exists and false if it does not.
The following will give me the correct answer in an alert box but if I change the
alert(result.d) to return result.d
the result of the function is always undefined.
How can I get the function that the Ajax call is contained in to return a value based on the response from the WebMethod?
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: function (result) {
alert(result.d);
},
error: function (err) {
alert(err);
}
});
}
The thing to note is that the ajax function is non blocking. You specify two callback functions, one for success and one for error, one of these functions will get executed when the underlying request is finished.
Your doesEnteredUserExist does not wait for the ajax call to complete, and thus, the return value of the function is undefined.
The proper way to continue execution based on the result of your call is to break your functionality out into a separate function, and call that from your success function.
Ajax is asynchronous so once the function "doesEnteredUserExist" returns, the ajax call is not yet finished. Then later in the success callback you have the value. From there you should continue with your code and display the info to the user.
Store the value of result.d in a variable, then use it for whatever you would like.
Change this:
success: function (result) {
alert(result.d);
},
to this:
success: function (result) {
var resultString = result.d;
},
Now whenever you need result.d, just use the variable resultString. Basically, the ajax call is the only thing that can call the function that you wanted to return the value for, so you need to store that value when the function is called.
Maybe give this a bash
function onSucess (data) {
alert(data.d);
}
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: onSucess,
error: function (err) {
alert(err);
}
});
}
I am guessing that you are trying to set result.d which is out of scope from the call which is why the alert (result.d) works as its in scope.
I may be getting the wrong end of the stick, you could use a global variable (not recommended), set that in the ajax return which you could then read from your function.
May need a bit more info or clarity on what your trying to achieve, as I read the question a couple of ways.
I normally do this (havent tested this):
function ajaxLoad(callback)
$.ajax({
type: 'POST',
async: true,
url: 'url.aspx',
data: d,
cache: false,
contentType: 'application/json',
dataType: 'json',
error: function (xmlHttpRequest, textStatus, errorThrown) {
//error stuff
},
success: function (data) {
if (typeof callback == 'function') { [callback(data)]; }
}
});
}
function callback(data)
{
alert(data);
}
call the function using
ajaxLoad('callback');
something like that!
Inside your success callback function if you return some value it doesn't set the return value for it's parent function. In this case the parent function is $.ajax and it always returns a jqXHR deferred object.
If you are using jQuery 1.5 or later the you can use deferreds. The idea is to save the jqXHR object returned from the AJAX request and wait for it to complete before returning it's value:
var jqXHR = $.ajax({...});
$.when(jqXHR).then(function (result) {
return result.d
});
Docs for $.when(): http://api.jquery.com/deferred.when
An example of doing this would be to return the jqXHR object from your function and then wait for the AJAX request to resolve outside the function:
function doesEnteredUserExist() {
return $.ajax({...});
}
$.when(doesEnteredUserExist).then(function (result) {
//you can access result.d here
});
As #timing has mentioned, by the time the value is returned from thefunction, the ajax call is not complete so everytime you get the undefined.
This is not a solution to the problem, but an alternative method you can try for displaying it would be instead of returning the value, just update the innerHTML of some element like div with the returned text.Below is what I mean:
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: function (result) {
//alert(result.d);
if(result.d==true){ //Just a check for the value whether true or 1 etc..
$("#notifications").html('Username Already Exists'); // Have a div where you can display the message (named it notifications here) , update the notifications div text to notify the user
}else{
$("#notifications").html('Username is Available');
}
},
error: function (err) {
alert(err);
}
});
}
This seems a good example of $.Deferred object usage
the idea is quite simple (really, I promise, :) see steps on the code)
Create a new deferred object
Make your ajax call. If result is false you will reject the deferred otherwise you will resolve it (you could reject it also on error ajax callback)
return the promise
Use .when() helper to check the status of the promise.
I create a fiddle which return randomically true or false in the response
function checkUserExist() {
var dfd = $.Deferred(); /* step 1 */
$.ajax({
url: "/echo/json/",
data: {
"json": JSON.stringify({d: (Math.random() < 0.5) })
},
type: "POST",
success: function (data) {
console.log("result (inside ajax callback) ", data.d);
if (!data.d) { dfd.reject() } else { dfd.resolve(); } /* step 2 */
},
error : ...
});
/* step 3 */
return dfd.promise();
}
$.when(checkUserExist()) /* step 4 */
.fail(function() { console.log("user don't exist (inside fail)"); })
.done(function() { console.log("user already exist (inside done)"); })
fiddle url : http://jsfiddle.net/Gh9cN/
(note: I've changed some internal details so to make it work on jsfiddle)

Good way to enable auto refresh of events on the fullCalendar jquery plugin?

Is there a good way to have the fullCalendar jquery plugin auto-refresh its events?
I am able to simply call 'refetchEvents' using a timer, but that presents issues if the user is currently dragging an event (throwing javascript errors during the refresh while the event is dragged). Is there a better way?
Good solution... but is not enough:
var calE = {
url: 'calendarEvents.do',
type: 'POST',
data: {
siteId: $("#siteId").val()
},
error: function() {
alert('there was an error while fetching events!');
}
};
function loadCal(){
$('#calendar').fullCalendar({
theme: true,
events: calE,
editable: false,
eventDrop: function(event, delta) {
alert(event.title + ' was moved ' + delta + ' days\n' +
'(should probably update your database)');
},
loading: function(bool) {
if (bool) $('#loading').show();
else $('#loading').hide();
},
viewDisplay: function(viewObj) {}
});
}
function reloadCalendar(){
$('#calendar').fullCalendar('removeEventSource', calEvent );
var source = {
url: 'calendarEvents.do',
type: 'POST',
data: {
siteId: $("#siteId").val()
},
error: function() {
alert('there was an error while fetching events!');
}
};
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('addEventSource', source );
$('#calendar').fullCalendar('rerenderEvents');
calE = source;
}
By using this you'll keep the original algorithm to fetch the data.
you'd just need to keep track of a flag, whether auto-refreshing should happen. it should be true by default, but set to false when dragging or resizing. you can set it based on the eventDragStart, eventDragStop, eventResizeStart, and eventResizeStop.
see http://arshaw.com/fullcalendar/docs/event_ui/ for a list of mouse-related triggers.

Resources