How to dynamically change event sources? - events

I am using the jQuery FullCalendar plug-in. I want to load initially the calendar with events as an array. I am doing this like:
events: <%= Model.Events %>
or
eventSources: [{
events: <%= Model.Events %>
}]
Both ways work fine. I am using MVC 3.0 and <%= Model.Events %> returns an array of events in JSON format.
I want to use the events array ONLY for the initial loading of the calendar. Later, every times events are needed to be fetched, I want my events to be loaded using the url '/Calendar/Events'.
How can be this implemented?
I tried difference scenarios with addEventSource/removeEventSource in the viewDisplay callback, but nothing worked fine for me.

.fullCalendar( {
eventSources : [ {
url : '/Calendar/Events',
type : 'GET'
} ],
viewDisplay : function( event ) {
// assuming this will point to the full calendar,
// might have to do something silly like
// $( '#myCal' ).fullCalendar( 'refetchEvents' );
this.refetchEvents();
}
} );

I know it's a very old question but I needed this right now. The answer wasn't here but I found it in another question.
Here what is solution.
My primary source of events is this(this is the events source from the default examples of Fullcalendar):
events: function(start, end, callback) {
$.ajax({
type: 'POST',
url: 'myurl',
dataType:'xml',
crossDomain: true,
data: {
// our hypothetical feed requires UNIX timestamps
start: Math.round(start.getTime() / 1000),
end: Math.round(end.getTime() / 1000),
'acc':'2',
},
success: function(doc) {
var events = [];
var allday = null; //Workaround
var Editable = null; //Workaround
$(doc).find('event').each(function()
{
if($(this).attr('allDay') == "false") //Workaround
allday = false; //Workaround
if($(this).attr('allDay') == "true") //Workaround
allday = true; //Workaround
if($(this).attr('editable') == "false") //Workaround
Editable = false; //Workaround
if($(this).attr('editable') == "true") //Workaround
Editable = true; //Workaround
events.push({
id: $(this).attr('id'),
title: $(this).attr('title'),
start: $(this).attr('start'),
end: $(this).attr('end'),
allDay: allday,
editable: Editable
});
});
//calendar.fullCalendar( 'addEventSource', othersources.folgas );
//calendar.fullCalendar( 'addEventSource', othersources.ferias );
//calendar.fullCalendar('refetchEvents');
callback(events);
}
});
}
Now i needed it to add more sources and to do this ouside the calendar (next to the date variables from fullcalendar examples) i made a variable like the code above, but with ajax calls similar to my primary: )
var othersources = {
anothersource: {
events: function(start, end, callback) {
$.ajax({
type: 'POST',
url: 'myurl',
data: {
// our hypothetical feed requires UNIX timestamps
start: Math.round(start.getTime() / 1000),
end: Math.round(end.getTime() / 1000),
'acc':'7',
},
success: function(doc) {
var events = [];
var allday = null; //Workaround
var Editable = null; //Workaround
$(doc).find('event').each(function()
{
if($(this).attr('allDay') == "false") //Workaround
allday = false; //Workaround
if($(this).attr('allDay') == "true") //Workaround
allday = true; //Workaround
if($(this).attr('editable') == "false") //Workaround
Editable = false; //Workaround
if($(this).attr('editable') == "true") //Workaround
Editable = true; //Workaround
events.push({
id: $(this).attr('id'),
title: $(this).attr('title'),
start: $(this).attr('start'),
end: $(this).attr('end'),
allDay: allday,
editable: Editable
});
});
callback(events); //notice this
}
});
},
cache: true,
//error: function() { alert('something broke with courses...'); },
color: 'green', //events color and stuff
textColor: 'white',
//className: 'course'
}
}
Now, he build diffrent sources and use like this both...
eventSources: [ othersources.anothersource ],
viewDisplay: function(view) {
if (view.name == 'month'){
calendar.fullCalendar( 'addEventSource', othersources.anothersource );
//calendar.fullCalendar('refetchEvents');
//Notice i'm not doing the refetch events. And its working for me. but i'm calling thi elsewhere, every time i make an action. So you must figure it out ;)
}
Link to above solution
And another way i found on github.
Basically the problem was that I can't change data parameters after calendar initialization. For events this worked:
events: {
url : '',
type: 'POST',
data: function () {
return {
action: 'view',
search_text: search_text
};
},
error: function() {
alert('there was an error while fetching events!');
},
color: '#31b0d5', // a non-ajax option
textColor: '#fff;', // a non-ajax option
},
for resources it didnt so I had to make like that:
resources: function(callback) {
var view = $("#calendar").fullCalendar("getView");
$.ajax({
url: "",
type: 'POST',
dataType: "json",
cache: false,
data: {
start : view.start.format(),
end : view.end.format(),
timezone : view.options.timezone,
action : 'projects_employees',
search_text: search_text
}
}).then(function(resources) {
callback(resources);
})
},
Simple ways like that do not work cuz are static and couldn't be changed after init:
events: {
url: '',
type: 'POST',
data: {
action: 'view',
search_text: search_text
}
},
resources: {
url: '',
type: 'POST',
data: {
action: 'projects_employees',
search_text: search_text
}
}
Here is the github link. Replied by peon501.
After to many try, i did solve my problem with use first part (stackoverflow) codes. The key for me defiying eventSource with "var" key and use it like this
//...
eventSources: [ othersources.anothersource ] ,
//...
I have collected all the data in a php file the way I want it. And the output of this page was a javascript with this
header('Content-Type: text/javascript');
$fromDB ="";
$sources = "sources = [";
foreach ($events as $value) { // value is source name
$fromDB .= "var $value = {
url: path + 'fetchEvents.php',
method: 'GET',
extraParams: {
value: $value,
code: new URLSearchParams(window.location.search).get('code'),
},
failure: function(error) {
console.log(error);
Swal.fire('Error!', '', 'error');
},
};
";
$sources .= $value. " ";
}
$sources .= " ];";
// this $sources give me
// sources = [anothersource ,othersource ,anothersource2 ];
This make like this
var anothersource = {
url: path + 'fetchEvents.php',
method: 'GET',
extraParams: {
value: $value,
code: new URLSearchParams(window.location.search).get('code'),
},
failure: function(error) {
console.log(error);
Swal.fire('Error!', '', 'error');
},
};
var othersource = {
url: path + 'fetchEvents.php',
method: 'GET',
extraParams: {
value: $value,
code: new URLSearchParams(window.location.search).get('code'),
},
failure: function(error) {
console.log(error);
Swal.fire('Error!', '', 'error');
},
};
var anothersource2 = {
url: path + 'fetchEvents.php',
method: 'GET',
extraParams: {
value: $value,
code: new URLSearchParams(window.location.search).get('code'),
},
failure: function(error) {
console.log(error);
Swal.fire('Error!', '', 'error');
},
};
sources = [anothersource ,othersource ,anothersource2 ];
.fullCalendar( {
eventSources : sources , // here, we use dynamic eventsources
viewDisplay : function( event ) {
// assuming this will point to the full calendar,
// might have to do something silly like
// $( '#myCal' ).fullCalendar( 'refetchEvents' );
this.refetchEvents();
}
} );
I added the main javascript file, which will do all the operations, at the bottom of this php file.
//...
$file = "my/fullcalender/initjavascript/file.js"
file_get_contents($file) . PHP_EOL;
//...
This code opens the javascript file in the $file path and takes whatever is in it and adds it to this file.
I hope that will be useful.

Related

Ckeditor custom plugin- populate dialog data from ajax

I have created a custom plugin to tag a list of usernames in ckeditor. The methodology for implementing is to get the data from the ajax controller. The following is the ajax function to get the list of user names.
$org = new VA_Logic_Organization($orgid);
if ($groupid) {
$group = new VA_Logic_Group($groupid);
if ($group->assigntomanager == 1) {
$manager = new VA_Logic_Avatar($group->managerid);
$avatarlist[$group->managerid] = $manager->firstname . ' ' . $manager->lastname;
} else {
$avatarlist = $group->getAvatarListByName($name, $form->hideleveldifference);
}
} else if ($form->defaultassigngroup) {
$group = new VA_Logic_Group($form->defaultassigngroup);
if ($group->assigntomanager == 1) {
$manager = new VA_Logic_Avatar($group->managerid);
$avatarlist[$group->managerid] = $manager->firstname . ' ' . $manager->lastname;
} else {
$avatarlist = $group->getAvatarListByName($name, $form->hideleveldifference);
}
} else {
$avatarlist = $org->getAvatarListByName($name, $form->hideleveldifference);
}
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(TRUE);
echo json_encode($avatarlist);
The following is the ckedior pluginname.js.
elements: [
{
type: 'select',
id: 'exam_ID',
label: 'Select Exam',
items :function(element)
{
$.ajax({
type: 'POST',
url: baseurl +"employee/ajax/assignedtoselect/groupid/" ,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: false,
});
}
}
]
I need to populate the json data on click of the dialog text box.
Finally found the solution.
The onShow function was very helpful,
The working code for pluginname.js is here
CKEDITOR.dialog.add( 'abbrDialog', function( editor ) {
return {
// Basic properties of the dialog window: title, minimum size.
title: 'Tag Avatars',
minWidth: 250,
minHeight: 100,
// Dialog window contents definition.
contents: [
{
// Definition of the Basic Settings dialog tab (page).
id: 'tab-basic',
label: 'Avatars',
// The tab contents.
elements: [
{
// Text input field for the abbreviation text.
type: 'text',
id: 'avatarid',
label: 'Type an avatar name to tag'
},
]
},
{
// Definition of the Basic Settings dialog tab (page).
id: 'tab-advanced',
label: 'Items/Modules',
// The tab contents.
elements: [
{
// Text input field for the abbreviation text.
type: 'text',
id: 'instanceid',
label: 'Type an item to tag'
},
{
type: 'checkbox',
id: 'checkid',
label: 'check to add link'
}
]
}
// Definition of the Advanced Settings dialog tab (page).
],
onShow: function() {
var assigned_config = {
source: baseurl+"employee/ajax/assignedtoselect/",
select: function(event, ui){
$("#cke_79_textInput").val(ui.item.value);
$("#cke_79_textInput").val(ui.item.id);
window.abbr1 = ui.item.id;
},
change: function (ev, ui) {
if (!ui.item){
$("#cke_79_textInput").val("");
}
}
};
$("#cke_79_textInput").autocomplete(assigned_config);
var ac_config = {
source: baseurl+"employee/module/parentlist/",
select: function(event, ui){
$("#cke_84_textInput").val(ui.item.value);
$("#cke_84_textInput").val(ui.item.id);
window.instanceid = ui.item.id;
},
change: function (ev, ui) {
if (!ui.item){
$("#cke_84_textInput").val("");
}
}
};
$("#cke_84_textInput").autocomplete(ac_config);
},
// This method is invoked once a user clicks the OK button, confirming the dialog.
onOk: function() {
var dialog = this;
if(window.abbr1 === undefined){
var checkid = document.getElementById('cke_88_uiElement');
if (checkid.checked) {
var url = baseurl+ '/employee/module/view/instanceformid/'+instanceid;
abbr = dialog.getValueOf( 'tab-advanced', 'instanceid' );
var inst = '<a target="_blank" href='+url+'>'+abbr+'</a>';
editor.insertHtml(inst);
}
else{
var inst = '\$\[' +instanceid+ '\!\description]';
editor.insertHtml( inst );
}
}
else{
abbr = dialog.getValueOf( 'tab-basic', 'avatarid' );
var url = baseurl + '/employee/avatar/friendsprofilepopup/avatarid/' +abbr1;
var htmlavatar = '<a class="infopopup20" href= '+url+' >'+abbr+ '</a>';
editor.insertHtml( htmlavatar );
}
}
};
});

knockout validation for array of objects

I have an array of dynamically added objects and I want to validate this array for required fields and numeric values.
I have 3 buttons, one for adding note, another for removing note and one for saving
How to validate every object ?
.. the code:
$(function () {
var initialData = [{
Title: "",
NoteText: "",
Suggestion: "",
MediaTime: ""
}];
var CreateNewNoteModel = function (Notes) {
var self = this;
self.Notes = ko.observableArray(ko.utils.arrayMap(Notes, function (Note) {
return { Title: Note.Title, NoteText: Note.NoteText, Suggestion: Note.Suggestion, MediaTime: Note.MediaTime };};
}));
var i = 1;
self.addNote = function () {
self.Notes.push({
Title: "", NoteText: "", Suggestion: "", MediaTime: ""
});
$('#editor' + i).wysihtml5();
$('#editorB' + i).wysihtml5();
i++;
};
self.removeNote = function (Note) {
self.Notes.remove(Note);
};
self.save = function () {
self.lastSavedJson(JSON.stringify(ko.toJS(self.Notes), null, 2));
var jsondata = self.lastSavedJson();
$.ajax({
url: "/api/Notes/?mid=" + m + "&p=" + p,
cache: false,
type: 'Post',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: jsondata,
success: function () {
alert("Success");
document.location.reload(true);
}
});
};
self.lastSavedJson = ko.observable("")
};
ko.applyBindings(new CreateNewNoteModel(initialData));
});
I am using jQuery validate plugin to add validation to knockout-js by using jQuery's validation methods: "$.validator.addMethod" and "$.validator.addClassRules".
Example:
First define your validation methods and css classes. Later on, we add the css classes to your inputs to validate your fields.
function DefineValidationRules() {
$.validator.addMethod("validateNumber", ValidateInteger, "This field is not a number");
$.validator.addMethod("validateRequired", $.validator.methods.required, "This field is required");
$.validator.addMethod("validateMin", $.validator.methods.min, $.format("This number be greater than or equal to {0}"));
$.validator.addMethod("validateMax", $.validator.methods.min, $.format("This number must be less than or equal to {0}"));
$.validator.addMethod("validateMinlength", $.validator.methods.minlength, $.format("This field must contain at least {0} characters"));
$.validator.addMethod("validateRangelength", $.validator.methods.rangelength, $.format("This field must contain between {0} and {1} characters"));
$.validator.addClassRules("validate-number", { validateNumber: true });
$.validator.addClassRules("validate-number-min", { validateNumber: true, validateMin: 1 });
$.validator.addClassRules("validate-required-number-min", { validateRequired: true, validateNumber: true, validateMin: 1 });
$.validator.addClassRules("validate-required", { validateRequired: true });
$.validator.addClassRules("validate-rangelengthmax6", { validateRangelength: [0,6] });
}
DefineValidationRules();
You can also add your own custom validation method:
function ValidateInteger(value) {
//do whatever you want to check
}
Having an input in knockout:
<input class="validate-required validate-number" type="text" data-bind="value: examplefield, valueUpdate: 'afterkeydown', attr: { attrname: 'itsvalue'}" />
Checking on submit:
$("#yoursubmitbutton").on("click", function () {
var formtosubmit = $("#idofyourform");
//check for validation errors
if (isValid(formtosubmit)) {
formtosubmit.submit();
//
// code to proceed to next step
}
});
function isValid(el) {
var $thisform = el;
$thisform.validate({
errorElement: "label",
errorPlacement: function (error, element) {
//eventual different error placing
if (element.attr("name") == "fname" || element.attr("name") == "lname") {
element.css("border", "2px solid red");
error.insertAfter("#lastname");
} else {
error.insertAfter(element);
}
}
});
return $thisform.valid();
}

Kendo UI reload treeview

I load a complex treeview with kendo ui via ajax because I need to load the tree with one request (works fine):
$(document).ready(function() {
buildTree();
});
function buildTree(){
$.getJSON("admin_get_treedata.php", function (data) {
$("#treeview").kendoTreeView({
select: function(item) { editTreeElement(item,'tree'); },
dataSource: data
});
})
}
If I try to reload the complete tree after changing some data via ajax the new build tree does not work correct and does not update the text.
$.ajax({
type: 'POST',
url: 'ajax/ajax_update_layer.php',
data: {
layerid:id,
...
},
success: function(data){
buildTree();
}
});
What can Ido?
Thanks
Sven
try this on ajax success callback
var data = $("#treeView").data('kendoTreeView');
data.dataSource.read();
I got mine to work.
This is what I did:
Function that creates the tree view:
function CreateNotificationTree(userId)
{
var data = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "../api/notifications/byuserid/" + userId,
contentType: "application/json"
}
},
schema: {
model: {
children: "notifications"
}
}
});
$("#treeview").kendoTreeView({
dataSource: data,
loadOnDemand: true,
dataUrlField: "LinksTo",
checkboxes: {
checkChildren: true
},
dataTextField: ["notificationType", "NotificationDesc"],
select: treeviewSelect
});
function treeviewSelect(e)
{
var $item = this.dataItem(e.node);
window.open($item.NotificationLink, "_self");
}
}
Modification & data source refresh:
$('#btnDelete').on('click', function()
{
var treeView = $("#treeview").data("kendoTreeView");
var userId = $('#user_id').val();
$('#treeview').find('input:checkbox:checked').each(function()
{
var li = $(this).closest(".k-item")[0];
var notificationId = treeView.dataSource.getByUid(li.getAttribute('data-uid')).ID;
if (notificationId == "undefined")
{
alert('No ID was found for one or more notifications selected. These notifications will not be deleted. Please contact IT about this issue.');
}
else
{
$.ajax(
{
url: '../api/notifications/deleteNotification?userId=' + userId + '&notificationId=' + notificationId,
type: 'DELETE',
success: function()
{
CreateNotificationTree(userId);
alert('Delete successful.');
},
failure: function()
{
alert('Delete failed.');
}
});
treeView.remove($(this).closest('.k-item'));
}
});
});
Hope that helps.

Issue in JQuery Confirmation Dialog inside form submit

In a JQuery dialog I have four fields. When I click on Save button I needs to check and validate the following
Validate all required fields ( On submit of form using validate.js and unobstrusive.js )
Check the value of dropdown and if it is of a partcular type ie (Redundant), Show user a confirmation dialog.
If the user confirm by pressing Yes, then close the confirmation dialog and call Ajax
But the problem is when I confirm by clicking Yes button on confirmation dialog, the dialog closes but the execution is not going down.
ie, Serializing the form data and make an Ajax call to call the webservice.
Please can anyone help.
$(function () {
$('form').submit(function () {
$('#result').html(" ");
var redunt = null;
redunt = $(ClientCrud_StatusCodeId).find('option:selected').text();
if ($(ClientCrud_StatusCodeId).find('option:selected').text() == "Redundant") {
$('#clientRedundantMessage2').html("Client once made redundant cannot be reactivated. Are you sure ?");
$("#RedundantMessage2").dialog(
{
autoOpen: false,
height: 170,
width: 420,
modal: true,
resizable: false,
title: "Confirmation for Redundant",
Content: "Fields cannot be left blank.",
buttons: {
"Yes": function () {
redunt = "Active";
$('#RedundantMessage2').dialog('close');
},
"No": function () {
$(this).dialog("close");
return false;
}
}
}) //.dialog("widget").draggable("option", "containment", "none");
$("#RedundantMessage2").dialog("open");
}
if ($(this).valid())
{
debugger;
if (redunt == "Active") {
$.ajax({
url: this.action,
type: this.method,
async: false,
cache: false,
data: $(this).serialize(),
error: function (request) {
$("#result").html(request.responseText);
// event.preventDefault();
},
success: function (result) {
if (result == "success") {
$.ajax({
url: "/Client/ClientGrid",
type: 'POST',
data: { "page": 0 },
datatype: 'json',
success: function (data) {
$('#grid').html(data);
},
error: function () {
alert('Server error');
}
});
$('#myEditClientDialogContainer').dialog('close');
$('#myEditClientDialogContainer').remove()
}
else {
clearValidationSummary();
var a = '<ul><li>' + result + '</li></ul>';
$('#result').html(a);
}
}
});
}
}
$("#griderrormsg1 li").hide().filter(':lt(1)').show();
return false;
});
editallowed = true;
});
I think you have a issue with the sequence of code, when the function $("#RedundantMessage2").dialog( ...... ); execute don't wait for the user response in this case "yes" or "no" so... your flag redunt = "Active" don't make sense.
the buttons option has function that execute when the opcion is choosen, so you must call a function to execute the post
$(function () {
$('form').submit(function () {
$('#result').html(" ");
var redunt = null;
redunt = $(ClientCrud_StatusCodeId).find('option:selected').text();
if ($(ClientCrud_StatusCodeId).find('option:selected').text() == "Redundant") {
$('#clientRedundantMessage2').html("Client once made redundant cannot be reactivated. Are you sure ?");
$("#RedundantMessage2").dialog(
{
autoOpen: false,
height: 170,
width: 420,
modal: true,
resizable: false,
title: "Confirmation for Redundant",
Content: "Fields cannot be left blank.",
buttons: {
"Yes": function () {
redunt = "Active";
trySend();
$('#RedundantMessage2').dialog('close');
},
"No": function () {
$(this).dialog("close");
return false;
}
}
}) //.dialog("widget").draggable("option", "containment", "none");
$("#RedundantMessage2").dialog("open");
}
$("#griderrormsg1 li").hide().filter(':lt(1)').show();
return false;
});
editallowed = true;
});
the other js function
function trySend(){
if ($('#IdOfYourForm').valid())
{
debugger;
if (redunt == "Active") {
$.ajax({
url: this.action,
type: this.method,
async: false,
cache: false,
data: $(this).serialize(),
error: function (request) {
$("#result").html(request.responseText);
// event.preventDefault();
},
success: function (result) {
if (result == "success") {
$.ajax({
url: "/Client/ClientGrid",
type: 'POST',
data: { "page": 0 },
datatype: 'json',
success: function (data) {
$('#grid').html(data);
},
error: function () {
alert('Server error');
}
});
$('#myEditClientDialogContainer').dialog('close');
$('#myEditClientDialogContainer').remove()
}
else {
clearValidationSummary();
var a = '<ul><li>' + result + '</li></ul>';
$('#result').html(a);
}
}
});
}
}
}

postData not passing any parameters!

I'm not able to see any parameters value passing to server in firebug. Here is the code.
//BuyBackGridInit() start
function BuyBackGridInit(tabID){
$('table[id$="'+tabID+'_BuyBackGrid"]').jqGrid({
url :'/Controls/Advertiser/BuyBackControlNew.ascx.ashx?action=getBuyBackData',
datatype: 'json',
mtype: 'POST',
height:'100%',
width:'100%',
colNames: result.colNamesData,
colModel: result.colModelData,
postData: {
advertiserID: function() { return $('#advertiser_id').text(); },
CampaignsDdlSelectedValue: function() { return $('select[id$="CampaignDdl"] option:selected').val(); },
startDate: function() { return $('input[id$="'+tabID+'_FromCalBuyBack_CalendarTbx"] ').val(); },
endDate: function() { return $('input[id$="'+tabID+'_ToCalBuyBack_CalendarTbx"] ').val(); }
},
rowNum : 100,
shrinkToFit :false,
altRows: true,
altclass:'altRow',
autowidth: true,
multiselect: true,
gridComplete:function (){
var recs = parseInt( $('table[id$="'+tabID+'_BuyBackGrid"]').getGridParam("records"),10);
if (recs == 0){
$('div[id$="'+tabID+'_NoDataFoundBuyBackdiv"]').show();
$('input[id$="AddToCartBtn"]').hide();
$('input[id$="BuyBackDownloadBtn"]').hide();
}
else {
$('div[id$="'+tabID+'_NoDataFoundBuyBackdiv"]').hide();
$('input[id$="AddToCartBtn"]').show();
$('input[id$="BuyBackDownloadBtn"]').show();
}
},
serializeGridData: function (data){
return $.toJSON(data);
}
});//end of jQuery("#BuyBackGrid").jqGrid()
}//BuyBackGridInit() End
Thanks,
A
You current implementation of serializeGridData just remove all functions parameters from the postData. So you should either extend data parameter inside of serializeGridData instead of the usage of postData. Another way is to modify serializeGridData to the following:
serializeGridData: function (data){
var propertyName, propertyValue, dataToSend = {};
for (propertyName in data) {
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue
}
}
}
return JSON.stringify(dataToSend);
}
In the code above we enumerate all properties and call all functions explicitly. Moreover I prefer to use JSON.stringify function from json2.js. The function will be native implemented in many web browsers.
See the demo here.

Resources