The Setup
I'm using Fullcalendar v4, and I'm having some trouble with extraParams and sending them to server via AJAX.
What I'm trying to do (and failing) is to use this:
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['interaction','dayGrid'],
defaultView: 'dayGridMonth',
selectable: true,
selectMirror:true,
.......
eventSources: [{
url: 'ajax/fc.php?dropdown='+$("#dropdown").val(),
method: 'POST',
cache: false,
extraParams: {
month: $("#monthPicker").val(),
dropdown: $("#dropdown").val(),
person: $("#person").val(),
phone: document.getElementById("phone").value,
testtext: 'hardcoded text'
},
}],
......
});
Values for month, dropdown, person, phone are picked up from a form.
The Problem
Dumping both the GET and the POST variables (sever-side), just to check what I've received gives back 0 / empty strings for everything other than the month parameter - it's shown correctly.
The GET parameter is there just for testing purposes, and so is document.getElementById bit - I wanted to see if anything would show up if I used them (nothing did).
The issue persists even if I change the code to use events instead of eventSources.
Upon further experimenting, it seems that the calendar is affected by the element values present upon its initialization - if I hardcode the values for dropdown, person, and other inputs / select elements, they, and only they get sent (any change in values is ignored). The same thing happens if I just set the initial value (ie <input id="person" name="person" value="Joe">).
The question
How can I force the calendar (short of destroying and recreating it) to actually notice changes in the input values I want to use as extraParams?
If I'm misunderstanding the use of extraParams, what are my alternatives? I need to be able to send various data to the server, in order to get a specific set of events.
Figured it out in the meantime, thanks to this SO answer. Since the parameters are dynamic, they need to be sent as stated in the documentation (part Dynamic extraParams parameter):
var calendar = new Calendar(calendarEl, {
events: {
url: '/myfeed.php',
extraParams: function() { // a function that returns an object
return {
dynamic_value: Math.random()
};
}
}
});
Which, in my case, would become:
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['interaction','dayGrid'],
defaultView: 'dayGridMonth',
selectable: true,
selectMirror:true,
.......
event: {
url: 'ajax/fc.php',
method: 'POST',
cache: false,
extraParams: function() {
return {
month: $("#monthPicker").val(),
dropdown: $("#dropdown").val(),
person: $("#person").val(),
phone: document.getElementById("phone").value,
testtext: 'hardcoded text'
}
},
},
......
});
Related
I'm working with Codeigniter 4, JQuery and AJAX
I added a calendar to my page using FullCalendar, the basic structure goes like this:
var base_url = $("#base_url").val();
var calendarEl = $("#calendar")[0];
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
headerToolbar: {
left:'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
events: base_url + '/calendar/fetch_activities',
editable: true,
buttonText: {
today: "Today",
month: "Month",
week: "Week",
day: "Day",
list: "List",
prev: "Prev",
next: "Next"
},
dateClick: function(info) {
// console.table(info);
}
});
I tried to fetch the events using
events: base_url + '/calendar/fetch_activities', which in theory should work as the structure it accepts is:
events: [
{
id: 'a',
title: 'my event',
start: '2018-09-01'
}
]
and my output from events: base_url + '/calendar/fetch_activities', is:
[{
"title":"Meeting with Mike",
"start":"2021-04-08 11:00:00",
"end":"2021-04-08 00:00:00"
},
{
"title":"Meeting with Mike",
"start":"2021-04-13 00:00:00",
"end":"2021-04-13 00:00:00"
}]
yet still I get this error for whatever reason
What could be the issue here?
==edit
+Is the error generated in FullCalendar code?
Yes.
+Does leaving out the event feed property in calendar options prevent the error?
Yes.
+Did testing confirm that the JSON posted is what the server returns from a GET request to the server with start and end values in the query component?
Yes.
+Did you test other things to rule them out as contributing to the error?
I've run out of ideas.
I've done a bit more digging and found out that this message doesn't always show because of a JSON error;
https://github.com/fullcalendar/fullcalendar/issues/4692
https://github.com/fullcalendar/fullcalendar/issues/4952
I rechecked the files, turns out the JSON file is at fault since it somehow includes a script tag sent by CodeIgniter's debugbar.
[{"title":"aaa22","start":"2021-04-01","end":"2021-04-01","id":"4"},{"title":"aaaeeee","start":"2021-03-30","end":"2021-03-30","id":"48"},{"title":"beep boop","start":"2021-03-31","end":"2021-03-31","id":"54"},{"title":"lorem ipsum edit","start":"2021-04-06","end":"2021-04-06","id":"55"}]
<script type="text/javascript" id="debugbar_loader" data-time="1618658976" src="localhost/myapp/?debugbar"></script><script type="text/javascript" id="debugbar_dynamic_script"></script><style type="text/css" id="debugbar_dynamic_style"></style>
I have no idea how this is happening but I'll have to look into it.
EDIT:
You can turn of debugging by going in Config/Boot/development.php and adding define('CI_DEBUG', false). It's running fine now.
I load the data to the eventSource through Ajax call,
then i retrieve the data as..
eventSources:
[
// your event source
{
url: '/ajax-load-holidaysExtra',// use the `url` property
type: 'POST',
datatype: "JSON",
data : function()
{ // a function that returns an object
var date = new Date($('#calendar1').fullCalendar('getDate'));
month_integer = date.getMonth();
year_integer = date.getFullYear();
return {
month: month_integer,
year: year_integer
}
},
error: function() {
alert('there was an error while fetching eventsin hol!');
},
color: 'rgba(244, 221, 38, 0.20)', // a non-ajax option
textColor: 'blue' // a non-ajax option
}
],
but i get the days which are shown in the calendar is not correct, it shows a date 1 or 2 days before the date which i intend to take from the eventSource..
I am new to full calendar please can anyone help...it will be grateful
I found the answer
Even the data was correct the format was not okay with the calendar...
events: [
{
title: 'Event1',
start: '2011-04-04'
},
{
title: 'Event2',
start: '2011-05-05'
}
// etc...
],
as in the documentation the month should be come as 2011-04-04 , but in my data it is 2011-4-4 so the result comes but full calendar shows a another day.
..hope this might be useful to someone, So that's why i keep this Question..if any suggestion open for discussion...
I am in desperate need of some help from JavaScript experts. I have spent the last 7 hours trying hundreds of combinations of code to get a basic Tag selection input field to work with the library x-editable and select2.
I am building a Project Management app which is going to have Project Task data shown in a popup Modal Div. In the Task Modal, all Task fields will be editable with in-line edit-in-place capability using AJAX.
I am using:
the jQuery edit in place library called X-Editable - http://vitalets.github.io/x-editable/
The drop down selection jQuery library Select2 - https://select2.github.io/
The jQuery MockAjax library to allow simulating AJAX request responses. https://github.com/jakerella/jquery-mockjax
I have setup a basic JSFiddle demo to experiment with just for this StackOverflow question. I don't have the thousands of lines of code from my actual application , however I do have majority of the 3rd part libraries that are being used included into the page. THe reason is to make sure that none of them are interfering with the results.
JSFiddle Demo: http://jsfiddle.net/jasondavis/Lusbqfhs/
The Goal:
Setup X-editable and Select2 on a Field to allow users to select and enter in Tags for a Project Task.
Fetch available Tag records from a backend server which will return a JSON response with Tag ID number and Tag Name and use this data to populate the Selection2 input field to allow a user to select multiple Tags.
Allow user to also type in a NEW tag and it will post and save the new Tags to the backend as well!
When tags are selected and the save button is clicked, it will save the list of selected Tags bu ID number back to a database.
Problems:
Now I have tried hundreds of variations of options and code combinations from my research in the past 7 hours. I cannot seem to get this basic functionality to work and majority of the examples I have found do not seem to work correctly anymore!
On this demo page for the library x-editable http://vitalets.github.io/x-editable/demo-plain.html?c=inline near the bottom of the examples in the table where it says Select2 (tags mode) that functionality is what I need! I just need it to load the available tags from an AJAX request and all the docs claim it can do this with no problem at all!
This is the Documentation section from X-Editable for Select2 fields - http://vitalets.github.io/x-editable/docs.html#select2
It also links to the Select2 documentation and claims that all the Options in Select2 can be set and used as well located here - https://select2.github.io/options.html
I use MockAjax library to simulate an AJAX response in pages like JSFiddle for testing. In my JSFiddle demo here http://jsfiddle.net/jasondavis/Lusbqfhs/ I have 2 MockAjax responses set up....
$.mockjax({
url: '/getTaskTags',
responseTime: 400,
response: function(settings) {
this.responseText = [
{id: 1, text: 'user1'},
{id: 2, text: 'user2'},
{id: 3, text: 'user3'},
{id: 4, text: 'user4'},
{id: 5, text: 'user5'},
{id: 6, text: 'user6'}
];
}
});
$.mockjax({
url: '/getTaskTagById',
responseTime: 400,
response: function(settings) {
this.responseText = [
{id: 1, text: 'user1'},
{id: 2, text: 'user2'},
{id: 3, text: 'user3'},
{id: 4, text: 'user4'},
{id: 5, text: 'user5'},
{id: 6, text: 'user6'}
];
}
});
They both are supposed to return a Mock JSON string for my Selection list to be populated with.
Here is my code for the demo...
$(function(){
//remote source (advanced)
$('#task-tags').editable({
mode: 'inline',
select2: {
width: '192px',
placeholder: 'Select Country',
allowClear: true,
//minimumInputLength: 1,
id: function (item) {
return item.CountryId;
},
// Get list of Tags from AJAX request
ajax: {
url: '/getTaskTags',
type: 'post',
dataType: 'json',
data: function (term, page) {
return { query: term };
},
results: function (data, page) {
return { results: data };
}
},
formatResult: function (item) {
return item.TagName;
},
formatSelection: function (item) {
return item.TagName;
},
initSelection: function (element, callback) {
return $.get('/getTaskTagById', {
query: element.val()
}, function (data) {
callback(data);
});
}
}
});
});
Now in the demo when you click the field to select Tags, it just keeps "loading" and never gets a result. Looking at the Console, it seems my MockAjax request is not working, however the 2nd one is working so I am not sure what is wrong with my AJAX request?
I could really use some help if someone can help to get this to work I would be very greatful, I have spent my whole night without sleep and am not even any closer to a working solution! Please help me!
Thank you
X-Editable uses Select2 3.5.2 which doesn't use jQuery.ajax() directly. It has its own ajax function and calls jQuery.ajax() like that:
transport = options.transport || $.fn.select2.ajaxDefaults.transport
...
handler = transport.call(self, params);
That's why $.mockjax({url: '/getTaskTags'... does not work.
To get it work you need to create your own transport function, something like that:
var transport = function (queryParams) {
return $.ajax(queryParams);
};
and set the transport option:
ajax: {
url: '/getTaskTags',
=> transport: transport,
type: 'post',
dataType: 'json',
data: function (term, page) {
return { query: term };
},
results: function (data, page) {
return { results: data };
}
},
In my MVC application, I am trying to create a SVG Map with data that comes from a database. Using jQuery, I call an action in the controller which returns data in the format that is expected in the MapSvg region's parameter.
The format that is expected goes as follows:
regions : {
'Yemen': {disabled: true},
'USA': {tooltip: 'USA: Click to go to Google.com', attr: {fill: '#ff0000', href: 'http://google.com', 'cursor': 'help'}}},
'France': {tooltip: 'This is France!', attr: {'cursor': 'help'}},
'Kazakhstan': {tooltip: 'Kazakhstan - the ninth largest country in the world.'}
},
In my controller, I have an action that will be called in the view by a jQuery ajax request
public ActionResult GetCountries()
{
List<ScratchMap> allitems = this.Worker.GetAllItems();
var allItemsAsArray = allitems.Select(x => string.Format("'{0}': {{ tooltip: 'Test', attr: {{ fill: '{1}' }} }}", x.PluginCountryName, x.Color)).ToArray();
return Json(allItemsAsArray, JsonRequestBehavior.AllowGet);
}
In the View, the following code is executed after the jQuery plugins and the MapSvg plugins are loaded:
$.get('/ScratchMap/GetCountries', {},
function (data) {
var regionsData = '{' + data + '}';
$('#map').mapSvg(
{
source: '#Url.Content("~/Content/Maps/world_high.svg")',
loadingText: 'Loading map...',
tooltipsMode: 'names',
responsive: true,
zoom: true,
pan: true,
zoomButtons: {
'show': true,
'location': 'right'
},
regions: regionsData
});
}), 'json';
When the page is rendered, the map does not fill any countries that were retrieved from the database. However, when I copy and assign the output of the regionsData variable directly to the regions parameter, the map loads everything correctly.
The following article teaches me that this could have something to do with the input data type. However, if I parse the regionsData to JSON, it tells me it is in a wrong format. But the given example by the creators of MapSvg is also in a wrong format.
Does anybody have any ideas for a workaround?
Thanks.
The problem is that even if the regions variable is edited the map plugin doesnt watch the change in its object contents so you must either wait till the data is returned before graphing the contents. Or re-graph with the method below.
If you wish to wait to graph till the data has been returned from your database call you can use a promise to delay the graphing of the object. Also important to know is the format in which the OPTS variables needs to have here is a sample.
var OPTS = {
source: sourcepath, // Path to SVG map
colors: {background: '#fff',base: '#0066FF', stroke: '#fff', selected: 10, disabled: '#ff0000'},
tooltipsMode: 'combined',
zoom: true,
pan: true,
responsive: true,
width: 1170,
zoomLimit: [0,100],
onClick: function (e, m) {
//do something here on each map click
},
regions:{
id_of_svg_path(the actual region you want to add data for):{
disabled:true,/*or whatever you need*/
tooltip:'<h4>Something to say</h4>'
}
}
}
In-order to re-graph I used the return object:
OPTS are just your specific chart options.
A variable javascript object that contains a regions variable.
var chartObj = $('#chart_container').mapSvg(OPTS);
chartObj.destroy();
This call will destroy then you re-graph it with OPTS that you have passed in.
Once you have destroyed it and passed in the new data you can just call.
var chartObj = $('#chart_container').mapSvg(OPTS);
Re-graphing it with the new data.
It turns out that it was an issue with the way I created the javascript output. The answer to this question can be found in this article.
If I have a data store on a grid like so:
store = Ext.create('Ext.data.Store', {
fields: [{
name: 'id'
}, {
name: 'filename'
}
// other fields here ...
],
proxy: {
type: 'ajax',
url: 'http://myniftyurl.com/blah',
simpleSortMode: true,
reader: {
type: 'json',
totalProperty: 'total',
root: 'result'
},
extraParams: {
'limit': Ext.get('itemsPerPage').getValue(),
'to': Ext.get('to_date').getValue()
// other params
}
},
model: 'Page',
remoteFilter: true,
remoteSort: true
});
The 'limit' and 'to' value will change based on user input, therein lies the problem. The data store keeps using the original parameters instead of the new inputs. How can I fix this?
Thanks in advance!
I normally load my grids manually by executing the store.load() in the controller.
That way prior to it I can change the store's params like so:
//getForm() retrieves the Ext.basic.Form (from Ext.panel.Form)
var params = this.getForm().getValues();
//Write over
grid.getStore().getProxy().extraParams = params;
//load
grid.getStore().load();
I'm using buffered grids which required a decent amount of rework to get completely working in 4.0.7. But that should work for you.
Another options is to use a beforeload listener but I'm not sure if changing the extraParams by then will do anything. You may be able to modified the Ext.data.Operation object that gets passed to the event handler?
Let me know how that works out for you.
Good luck!