fullcalendar do something when view change - javascript

I need to do something when view change. For example when from motnh go to agendaDay.
Didnt work anythink.any ideas?
viewRender:(function() {
var lastViewName;
return function(view) {
var view = $('#calendar').fullCalendar('getView');
alert('The new title of the view is ' + view.title);
}
}),
and
viewRender:(function(view) {
var view = $('#calendar').fullCalendar('getView');
alert('The new title of the view is ' + view.title);
}),

In FullCalendar 5 this seems to be datesSet: https://fullcalendar.io/docs/datesSet

Small error in the code. You want the function inside the () to return another function but it isn't running. The correct form is:
(function() {
return function(){...};
})(); //extra parentheses run the function
This is called a Self-Executing Anonymous Function.
Your code works when you do:
viewRender: (function () {
var lastViewName;
return function (view) {
var view = $('#calendar').fullCalendar('getView');
alert('The new title of the view is ' + view.title);
}
})(),

Little late but try:
eventAfterAllRender: (function (view) {
// your code
}),

As noted by #Willow (thanks), accepted answer will not work in version 5x.
viewRender, eventAfterAllRender, datesRender are all obsolete and break in version 5. Below are some FullCalendar documentations I found listing breaking changes per release.
ver. 4 Upgrading from v3
ver. 5 Upgrading from v4
DatesSet is the property to be used. Screenshot from ver. 5 documentation:
Taking your code example, below works for me. In case it benefits someone else.
// version 5.11.0 based code
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
...
datesSet: function (dateInfo) {
var view = dateInfo.view;
alert('The new title of the view is ' + view.title);
},
...
});
calendar.render();
});

Related

Dojo function not fired only on IE7

I am new to dojo. I am debugging a js that's using dojo 1.9.1
require(["dojo/ready", "dojo/hash", "dojo/topic"], function (ready, hash, topic) {
ready(function(){
try {
dimXsl = getDimensionXSLT("somepath.xsl"); // 1
topic.subscribe("/dojo/hashchange", callback); // 2
var djConfig = ""; // 3
djConfig.hashPollFrequnecy = 10; // 4
} catch (e) {
console.log('Error ' + e);
}
});
});
function callback() {// blbla }
The above code works for IE8 and above to fire callback(), but not IE7.
My investigations:
I searched Dojo documentation. for version 1.7, the doc https://dojotoolkit.org/reference-guide/1.7/dojo/hash.html suggests a blank html page. So, I did below:
change js dojo link to 1.7 when href it.
Added blank blank.html in project, and replaced //3-4 with
var dojoConfig = "";
dojoConfig.hashPollFrequnecy = 10;
dojoConfig.dojoBlankHtmlUrl = "/blank.html";
Another replacement //3-4 try was:
var dojoConfig = {
hashPollFrequnecy: 10,
dojoBlankHtmlUrl: "/blank.html"
};
But no luck. I also tried to carry above changes with dojo version 1.9.1, but still no luck.
Any ideas please? Thank you very much.

Globalize.js E_DEFAULT_LOCALE_NOT_DEFINED error

I'm developping an ASP MVC application that use Globalize.js. In the _Layout.cshtml I added this code
<script>
(function () {
$(function () {
$.when(
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/likelySubtags.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/numbers.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/numberingSystems.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/ca-gregorian.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/timeZoneNames.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/timeData.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/weekData.json")")
).then(function () {
// Normalize $.get results, we only need the JSON, not the request statuses.
return [].slice.apply(arguments, [0]).map(function (result) {
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale("fr");
});
});
})();
</script>
It's working. But when I tried to use it in other page in $(document).ready or $(window).load I Have the error JavaScript: E_DEFAULT_LOCALE_NOT_DEFINED: Default locale has not been defined.
It seems Like that The Globalize is not yet loaded.
I know that this is a very old story, but I stumbled upon it and the answer is pretty simple - instead of doing what you want to do on the $(document).ready event, you have to wait for the globalize to finish loading the resources and then do your stuff.
The simple way of doing this is to trigger your own event after you loaded globalize like this:
function loadcldr() {
var currentCultureCode = $("#hfTwoCharsCultureCode").val();
var publicCdnGlobalizeCompleteUrl = "/Resources/cldr/";
$.when(
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/ca-gregorian.json"),
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/numbers.json"),
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/currencies.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/likelySubtags.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/timeData.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/weekData.json")
).then(function () {
// Normalize $.get results, we only need the JSON, not the request statuses.
return [].slice.apply(arguments, [0]).map(function (result) {
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale(currentCultureCode);
customNumberParser = Globalize.numberParser();
$(document).trigger("globalizeHasBeenLoadedEvent");
});
}
The line that is of interest for you is $(document).trigger("globalizeHasBeenLoadedEvent"); because this triggers the custom event.
And then you can wait for that event to happen and then do your stuff:
$(document).on("globalizeHasBeenLoadedEvent",
function () {
alert("I'm done loading globalize...");
});
Hope it helps someone in the future... (not once I had an issue and I've searched on SO and found my own answers) :-))

Call Javascript After Saving Calendar Item

I am having a script as below:-
function getColorValue(aId,atitle) {
try{
var clientContext = new SP.ClientContext();
var oWebsite = clientContext.get_web();
var oList = oWebsite.get_lists().getByTitle('Item type');
var oListItem = oList.getItemById(parseInt(aId));
clientContext.load(oListItem);
clientContext.executeQueryAsync(function () {
var listItem = oListItem;
var colorname = listItem.get_item('Color_x0020_Name');
if (typeof colorname != 'undefined') {
if (colorname != null) {
$("div[title$='" + atitle + "']").css("background-color", colorname);
}
}
}, onColorQueryFail);
}
catch(e){
}
}
I need to call this script each time after a SharePoint Calendar Item is created.
Can anyone help?
The following JavaScript example demonstrates how to register event that will be triggered after Calendar item is created:
//custom handler that will be triggered after Calendar item is created
function onEventCreated(){
alert('Event has been created...');
}
function registerCalendarEventOnItemCreated(event)
{
var currentCtx = getCurrentContextInfo();
var calContainer = SP.UI.ApplicationPages.CalendarInstanceRepository.lookupInstance(currentCtx.ctxId);
for(var name in calContainer) {
if(calContainer.hasOwnProperty(name)) {
var p = calContainer[name];
if(p instanceof SP.UI.ApplicationPages.CalendarNewFormDialog) {
p.get_events().addHandler("newitemcreated",event);
}
}
}
}
//get current context info
function getCurrentContextInfo()
{
var currentListId = new SP.Guid(_spPageContextInfo.pageListId);
for(var ctxKey in g_ctxDict){
var curCtx = g_ctxDict[ctxKey];
if(curCtx.listName == currentListId.toString()){
return curCtx;
}
}
return null;
}
//register Calendar events
$('body').on('click', 'div#AsynchronousViewDefault_CalendarView', function() {
registerCalendarEventOnItemCreated(onEventCreated);
});
Has been tested against SharePoint 2013/Online
In your case the function getColorValue could be invoked from onEventCreated, for example:
function onEventCreated(){
getColorValue (id,title);
}
How to apply changes
Switch the page into Edit mode
Add Script Editor webpart into page.
Put the specified code by wrapping it using script tag code into the Script Editor, for example: <script type="text/javascript">{JavaScipt code goes here}</script>
Save the page
Results
Create an Event Receiver with List Item Events for type and Calendar for Source then check 'An item is being added' in handling the event.
Then in the code behind of your Event Receiver:
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
//Call your function through this
Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "MyFunction()", true);
}
Hope that helps :)
I know this is an old question, but there is an issue with the solution given.
I had a requirement to implement an workaround to the missing Resource Reservation feature in Sharepoint online. It was not possible to use an approach more suitable to the Modern Experience, due its dependency of Azure (no Azure subscription available for it), so I use Sharepoint API calls to perform the the same functionality of Resource Reservation.
To use the Sharepoint API, some Ajax calls were needed. But I observed that two calls were executed for each request.
The point is when you register calendar events, it is needed to attach the click event using one, as seen below, to prevent the click event to be fired more than once.
//register Calendar events
$('body').one('click', 'div#AsynchronousViewDefault_CalendarView', function() {
registerCalendarEventOnItemCreated(onEventCreated);
});

Tab independent jQuery on Firefox extension

I'm developping a Firefox based on jQuery as described in this Answer here.
After implementing the example provided in the answer, eveything works fine, but the problem is the code between Firefox Tabs is somehow linked, and example.doc always refers to the last opened tab.
Opened tab1 : the plugin-example has been added and to the current page.
this.doc refers to tab1.
Oepened tab2: the plugin-example has been added to to current page (tab2).
this.doc now refers to tab2
back to viewing tab1 : this.doc still refers to tab1.
clicking on plugin-example on tab1 will act on the plugin-example in tab2 instead.
How can I make my code independent between tabs?
Here is an excrept from the code:
(function() {
jQuery.noConflict();
$ = function(selector,context) {
return new jQuery.fn.init(selector,context||example.doc);
};
$.fn = $.prototype = jQuery.fn;
example = new function(){};
example.run = function(doc,aEvent) {
if (doc.getElementById("plugin-example")) return;
this.doc = doc;
this.main = main = $('<div id="plugin-example">').appendTo(doc.body).html('Example Loaded!');
this.main.click(function() { //<--- added this function
example.main.html(example.doc.location.href);
});
main.css({
background:'#FFF',color:'#000',position:'absolute',top:0,left:0,padding:8
});
};
// Bind Plugin
var delay = function(aEvent) {
var doc = aEvent.originalTarget; setTimeout(function() {
example.run(doc,aEvent);
}, 1);
};
var load = function() {
gBrowser.addEventListener("DOMContentLoaded", delay, true);
};
window.addEventListener("pageshow", load, false);
})();
Your code (overlay script) will only run once per window, not once per tab. So there is only one example instance per window. And hence example.doc will be set to whatever dispatched DOMContentLoaded last.
Your function should properly close over the document and avoid global state.
This is who I would write it (then again, I would avoid jquery (in add-ons) like the plague...)
// Use strict mode in particular to avoid implicitly var declarations
(function() {
"use strict";
// Main runner function for each content window.
// Similar to SDK page-mod, but without the security boundaries.
function run(window, document) {
// jquery setup. per https://stackoverflow.com/a/496970/484441
$ = function(selector,context) {
return new jq.fn.init(selector,context || document);
};
$.fn = $.prototype = jq.fn;
if (document.getElementById("my-example-addon-container")) {
return;
}
let main = $('<div id="my-example-addon-container">');
main.appendTo(document.body).text('Example Loaded!');
main.click(function() { //<--- added this function
main.text(document.location.href);
});
main.css({
background:'#FFF',color:'#000',position:'absolute',top:0,left:0,padding:8
});
};
const log = Components.utils.reportError.bind(Components.utils);
// Do not conflict with other add-ons using jquery.
const jq = jQuery.noConflict(true);
gBrowser.addEventListener("DOMContentLoaded", function load(evt) {
try {
// Call run with this == window ;)
let doc = evt.target.ownerDocument || evt.target;
if (!doc.location.href.startsWith("http")) {
// Do not even attempt to interact with non-http(s)? sites.
return;
}
run.call(doc.defaultView, doc.defaultView, doc);
}
catch (ex) {
log(ex);
}
}, true);
})();
Here is a complete add-on as a gist. Just drop in a copy of jquery and it should be good to go.
PS: Reposted this at in the jquery in extensions question

Simple client-side framework/pattern to simplify doing async calls?

We're currently not using any serious client side framework besides jQuery (and jQuery.ui + validation + form wizard plugins).
A problem that surfaces a few times in our code is this:
We have a button that initiates an Ajax call to the server.
While the call is taking place, we display a "loading" icon with some text
If the server returns a result too quickly (e.g. < 200 ms), we "sleep" for 200 millis (using setTimeout()), to prevent flickering of the waiting icon & text.
After max(the call returns, a minimal timeout), we clear the loading icon & text.
We then either display an error text, if there was some problem in the ajax call (the server doesn't return 500, but a custom json that has an "error message" property. In fact, sometimes we have such a property in the response per form field ... and we then match errors to form fields ... but I digress).
In case of success, we do ... something (depends on the situation).
I'm trying to minimize code reuse, and either write or reuse a pattern / piece of code / framework that does this. While I probably won't start using an entire new heavy-duty framework just for this use case, I would still like to know what my options are ... perhaps such a client-side framework would be good for other things as well. If there's a lightweight framework that doesn't require me to turn all my code upside down, and I could use just on specific cases, then we might actually use it instead of reinventing the wheel.
I just recently heard about Ember.js - is it a good fit for solving this problem? How would you solve it?
$(function(){
var buttonSelector = "#button";
$('body').on({'click': function(evt){
var $button = $(this);
$button.toggleClass('loading');
var time = new Date();
$.get('some/ajax').then(function(data,text,jqXhr){
// typical guess at load work
$button.empty();
$(data).wrap($button);
}).fail(function(data,text,jqXhr){
alert("failed");
}).done(function(data,text,jqXhr){
var elapsed = new Date();
if((elapsed - time) < 200){
alert("to short, wait");
}
$button.toggleClass('loading');
});
}},buttonSelector,null);
});
Just wrap the $.ajax in your own function. that way you can implement your own queing etc. I would suggest to do a jquery component for this. It can get pretty powerful, for example you can also pass http headers etc.
Regarding frameworks it depends on your requirements.
For example, you may consider Kendo UI, it has good framework for creating data sources:
http://demos.kendoui.com/web/datasource/index.html.
Working Sample Code (well, almost)
I was going for something along the lines of #DefyGravity's answer anyway - his idea is good, but is still pseudo-code/not fully complete. Here is my working code (almost working demo, up to the Ajax URL itself, and UI tweaks)
The code & usage example:
jQuery.fn.disable = function() {
$(this).attr("disabled", "disabled");
$(this).removeClass("enabled");
// Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
$(this).filter("button").button({disabled: true});
};
jQuery.fn.enable = function() {
$(this).removeAttr("disabled");
$(this).addClass("enabled");
// Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
$(this).filter("button").button({disabled: false});
};
function AjaxCallbackWaiter(ajaxUrl, button, notificationArea, loadingMessage, errorMessage, inSuccessHandler, inFailureHandler) {
// Every request that takes less than this, will be intentionally delayed to prevent a flickering effect
// http://ripper234.com/p/sometimes-a-little-sleep-is-ok/
var minimalRequestTime = 800;
var loadingIconUrl = 'http://loadinfo.net/images/preview/11_cyrcle_one_24.gif?1200916238';
var loadingImageContent = $("<img class='loading-image small' src='" + loadingIconUrl + "'/><span class='loading-text'>" + loadingMessage + "</span>");
var errorContentTemplate = $("<span class='error ajax-errors'></span>");
var requestSentTime = null;
button.click(clickHandler);
function displayLoadingMessage() {
clearNotificationArea();
notificationArea.html(loadingImageContent);
}
function clearNotificationArea() {
notificationArea.html("");
}
function displayError(message) {
var errorContent = errorContentTemplate.clone(errorContentTemplate).html(message);
notificationArea.html(errorContent);
}
function ajaxHandler(result) {
var requestReceivedTime = new Date().getTime();
var timeElapsed = requestReceivedTime - requestSentTime;
// Reset requestSentTime, preparing it for the next request
requestSentTime = null;
var sleepTime = Math.max(0, minimalRequestTime - timeElapsed);
function action() {
clearNotificationArea();
button.enable();
if (result) {
inSuccessHandler();
} else {
displayError(errorMessage);
inFailureHandler();
}
}
if (sleepTime <= 0) {
action();
} else {
setTimeout(action, sleepTime);
}
}
function failureHandler() {
}
function clickHandler(){
if (requestSentTime !== null) {
logError("Bad state, expected null");
}
requestSentTime = new Date().getTime();
displayLoadingMessage();
button.disable();
$.get(ajaxUrl, 'json').then(ajaxHandler, failureHandler);
}
}
// Usage:
var ajaxUrl = 'FILL IN YOUR OWN URL HERE';
var button = $("#clickme");
var notificationArea = $(".ajax-notification-area");
var waitingMessage = "Doing Stuff";
var errorMessage = "Not Good<br/> Please try again";
$(document).ready(function(){
new AjaxCallbackWaiter(
ajaxUrl,
button,
notificationArea,
waitingMessage,
errorMessage,
function(){
alert("All is well with the world");
},
function(){
alert("Not good - winter is coming");
});
});

Categories