FullCalendar pass events array as simple argument - express

Currently iam trying to pass an array of events in my database as a simple parameter. Below i attach my backend callback, the query document and the pure javascript Full Calendar implementation. So i tried forEach but gives me error . If i pass directly the objects array anaylitically then all works fine, but my issue is that i cannot render events by providing the array variable as argument. I wont like use JSON feed feature because my api is not able to be configurated. Any suggestion welcomed, thank you in advance
calendar:35 Uncaught ReferenceError: eventsArray is not defined
at HTMLDocument.<anonymous>
Express Js Callback
exports.getcalendar=async function (req,res,next){
var bookdata={};
try{
bookdata=await booking.aggregate().match({resourceID:mongoose.Types.ObjectId(req.params.id)}).project({
'title':'$Project_title',
'start':'$date_started',
'end':'$date_finished',
'_id':0
})
}catch (error){
return next(error);
}
finally {
console.log(JSON.parse(JSON.stringify(bookdata)));
res.render('calendar',{databook:JSON.parse(JSON.stringify(bookdata))});
}
};
bookdata
[
{
title: 'prj',
start: '2021-04-08T20:25:00.000Z',
end: '2021-04-09T20:25:00.000Z'
},
{
title: 'Proej3',
start: '2021-04-12T00:58:00.000Z',
end: '2021-04-13T00:58:00.000Z'
},
{
title: 'May proj',
start: '2021-05-10T11:00:00.000Z',
end: '2021-05-11T11:00:00.000Z'
},
{
title: 'prj',
start: '2021-04-28T15:00:00.000Z',
end: '2021-04-28T18:00:00.000Z'
}
]
FullCalendar Constructor
script.
document.addEventListener('DOMContentLoaded', function (databook) {
var calendarEl = document.getElementById('calendar');
var initdate = new Date();
var calendar = new FullCalendar.Calendar(calendarEl, {
function(){
var eventsArray=[];
bookdata.forEach(function (element){
eventsArray.push({
title:element.title,
start:element.start,
end:element.end })
})
},
initialView: 'dayGridMonth',
timeZone:'Europe/Athens',
initialDate: initdate,
handleWindowResize:true,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
eventTimeFormat:{
hour: 'numeric',
minute: '2-digit',
},
eventDisplay:'auto',
views:{
timeGrid:{
formatDateTime:'DD/MM/YYYY HH:mm'
}
},
events:eventsArray
});
calendar.addEvent()
calendar.render();
});

Don't create the eventsArray variable inside the calendar variable. You can initialize it right before the calendarEl is created for example

Related

Highcharts-vue - Calling my own tooltip label formatter function

I have been trying to call my own function for formatting the x and y axis values in a tooltip in Highcharts vue.
Consider the following;
data() {
return {
currencySymbol: "$",
};
},
computed: {
chartOptions() {
var symbol = this.currencySymbol;
return {
chart: {
type: "spline"
},
title: {
text: "Sin chart"
},
yAxis: {
gridLineDashStyle: "Dot",
labels: {
style: {
color: "#000"
},
formatter: label => {
return (
symbol + Highcharts.Axis.prototype.defaultLabelFormatter.call(label)
);
}
}
},
tooltip: {
formatter: function () {
return Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
this.formatNumber(this.y, this.fractionalDigits, this.locale, this.currencySymbol);
}
},
series: [
{
data: [10, 0, 8, 2, 6, 4, 5, 5],
color: "#6fcd98"
}
]
};
}
}
The labels work fine but the tooltip function call will not work. I have tried putting my formatNumber() function in both methods() and outside of any of the Vue hooks. Neither work.
Note that fractionDigits, locale and currencySymbol have been resolved at this point.
Wondering if someone can advise on the correct approach?
Also note that the formatter works when I remove the call to my formatNumber() function. It's lack of scope appears to be where the problem lies.
If I should assume that this.formatNumber, this.fractionDigits, this.locale, and this.currencySymbol would be references to a component's internal data, then the problem would occurs because of this context within tooltip's formatter function, which does not actually indicate on the component, but on the object on which the formatter was called, namely the TooltipFormatterContextObject.
In order to fix it, you can save appropriate context in the beginning of the chartOptions computed property function, and just refer it when calling component functions. Please take a look on the example below, where I've put the 'template' function named like yours, and presented how it could be implemented.
Live example: https://codesandbox.io/s/highcharts-vue-demo-wqwzu
Kind regards!
Not sure if it's the most elegant but I found a solution to this problem for myself.
I created a utility js file called helper.js, added my exported function (I'll need it in other places anyway) and put it in a directory called utils.
The contents are as follows;
export function formatNumber(number, maxFractionDigits, locale, currencySymbol) {
// function logic here
}
Then I imported same into my component and simply called the method as follows;
import {formatNumber} from "../../utils/helper";
export default {
data() {
return {
currencySymbol: "$",
};
},
computed: {
chartOptions() {
var symbol = this.currencySymbol;
return {
chart: {
type: "spline"
},
title: {
text: "Sin chart"
},
...
tooltip: {
formatter: function () {
return Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
formatNumber(this.y, this.fractionalDigits, this.locale, this.currencySymbol);
}
},
series: [
{
data: [10, 0, 8, 2, 6, 4, 5, 5],
color: "#6fcd98"
}
]
};
}
}
}

Vue.js - Element UI - HTML message in MessageBox

I'm using vue-js 2.3 and element-ui. This question is more specific to the MessageBox component for which you can find the documentation here
Problem
I'd like to be able to enter html message in the MessageBox
More specifically I would like to display the data contained in dataForMessage by using a v-for loop.
Apparently, we can insert vnode in the message but I have no idea where to find some information about the syntax.
https://jsfiddle.net/7ugahcfz/
var Main = {
data:function () {
return {
dataForMessage: [
{
name:'Paul',
gender:'Male',
},
{
name:'Anna',
gender:'Female',
},
],
}
},
methods: {
open() {
const h = this.$createElement;
this.$msgbox({
title: 'Message',
message: h('p', null, [
h('span', null, 'Message can be '),
h('i', { style: 'color: teal' }, 'VNode '),
h('span', null, 'but I would like to see the data from '),
h('i', { style: 'color: teal' }, 'dataForMessage'),
])
}).then(action => {
});
},
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
I think this is what you want.
methods: {
open() {
const h = this.$createElement;
let people = this.dataForMessage.map(p => h('li', `${p.name} ${p.gender}`))
const message = h('div', null, [
h('h1', "Model wished"),
h('div', "The data contained in dataForMessage are:"),
h('ul', people)
])
this.$msgbox({
title: 'Message',
message
}).then(action => {
});
},
}
Example.
You can also use html directly and convert to vnodes by using domProps:
const html = '<div><h1>Model wished</h1><div>The data contained in dataForMessage are:</div><ul><li>Paul Male</li><li>Anna Female</li></ul></div>'
const message = h("div", {domProps:{innerHTML: html}})
(The above is simplified without the loop. Just to get the idea)
Fiddle

How do I operate the m.withAttr tutorials code?

A contrived example of bi-directional data binding
var user = {
model: function(name) {
this.name = m.prop(name);
},
controller: function() {
return {user: new user.model("John Doe")};
},
view: function(controller) {
m.render("body", [
m("input", {onchange: m.withAttr("value", controller.user.name), value: controller.user.name()})
]);
}
};
https://lhorie.github.io/mithril/mithril.withAttr.html
I tried the above code does not work nothing.
It was the first to try to append the following.
m.mount(document.body, user);
Uncaught SyntaxError: Unexpected token n
Then I tried to append the following.
var users = m.prop([]);
var error = m.prop("");
m.request({method: "GET", url: "/users/index.php"})
.then(users, error);
▼/users/index.php
<?php
echo '[{name: "John"}, {name: "Mary"}]';
Uncaught SyntaxError: Unexpected token n
How do I operate the m.withAttr tutorials code?
Try returning m('body', [...]) from your controller.
view: function (ctrl) {
return m("body", [
...
]);
}
render should not be used inside of Mithril components (render is only used to mount Mithril components on existing DOM nodes).
The example is difficult to operate because it's contrived, it's not meant to be working out-of-the-box. Here's a slightly modified, working version:
http://jsfiddle.net/ciscoheat/8dwenn02/2/
var user = {
model: function(name) {
this.name = m.prop(name);
},
controller: function() {
return {user: new user.model("John Doe")};
},
view: function(controller) {
return [
m("input", {
oninput: m.withAttr("value", controller.user.name),
value: controller.user.name()
}),
m("h1", controller.user.name())
];
}
};
m.mount(document.body, user);
Changes made:
m.mount injects html inside the element specified as first parameter, so rendering a body element in view will make a body inside a body.
Changed the input field event to oninput for instant feedback, and added a h1 to display the model, so you can see it changing when the input field changes.
Using m.request
Another example how to make an ajax request that displays the retrieved data, as per your modifications:
http://jsfiddle.net/ciscoheat/3senfh9c/
var userList = {
controller: function() {
var users = m.prop([]);
var error = m.prop("");
m.request({
method: "GET",
url: "http://jsonplaceholder.typicode.com/users",
}).then(users, error);
return { users: users, error: error };
},
view: function(controller) {
return [
controller.users().map(function(u) {
return m("div", u.name)
}),
controller.error() ? m(".error", {style: "color:red"}, "Error: " + controller.error()) : null
];
}
};
m.mount(document.body, userList);
The Unexpected token n error can happen if the requested url doesn't return valid JSON, so you need to fix the JSON data in /users/index.php to make it work with your own code. There are no quotes around the name field.

dojox.mobile: Custom ListItem widget: "... is not a constructor"

I want to create a custom ListItem widget for my dojox.mobile app. It works if i use it in my HTML Code, but it throws a TypeError if i try to use it programmatically.
This is the JS-Code for my custom ListItem:
define([
"dojo/_base/declare",
"dojo/dom-construct",
"dojox/mobile/ListItem"], function(declare, domConstruct, ListItem){
var LabeledInputListItem = declare("myapp.LabeledInputListItem", ListItem, {
labelText: "",
placeholder: "",
value: "",
_setItemLabelAttr: function(val) {
this.labelText = val;
this.qDescSpan.innerHTML = val;
},
_setPlaceholderAttr: function(val) {
this.placeholder = val;
},
_setValueAttr: function(val) {
this.value = val;
},
startup: function(){
if(this._started){ return; }
},
constructor: function(params) {
this.placeholder = params.placeholder;
this.labelText = params.labelText;
this.valu = params.value;
},
buildRendering: function(){
this.inherited(arguments);
this.qDescDiv = domConstruct.create("div", {className: "tableItemDescription", id: "asd"}, this.labelNode, "before");
this.qDescSpan = domConstruct.create("span", null, this.qDescDiv, "first");
this.qInputDiv = domConstruct.create("div", {className: "tableItemInput"}, this.qDescDiv, "after");
this.qInputText = domConstruct.create("input", {className: "mblTextBox sessionTextbox", placeholder: this.placeholder, value: this.value}, this.qInputDiv, "first");
console.log(this.labelText, this.placeholder, this.value);
},
});
return LabeledInputListItem; });
I can use this custom ListItem in my html Code like this:
<li data-dojo-type="myapp/LabeledInputListItem" data-dojo-props="itemLabel: 'asdasd', placeholder: 'placeholder', value: 'value'"></li>
However, if I try to create my custom ListItem programmatically it results in the following error:
TypeError: myapp.LabeledInputListItem is not a constructor
var childWidget = new myapp.LabeledInputListItem({placeholder: "placeholder"});
Does anybody know what i'm missing?
Thanks in advance for your help!
The only (obvious) reason I can think of would be that you did not require the module?
By the way Dojo is now moving towards a "no globals" approach, so it may be better to not give an explicit id to your class, and use the value of the AMD module instead of the global myapp.LabeledInputListItem.

RubyOnRails3 - FullCalendar

I would like to use calendar in my project, I already used table_builder gem and event_calendar gem but fullcalendar gem is more appropriate for me. The problem is I can't find any step by step tutorial to use it and somehow I'm new to RubyOnRails. Can any one help me to be able to understand how to use it please?
*I Figured Out how to use full calendar - just go to fullcalendar web site and download the required version of fullcalendar JavaScript and css files - include fullcalendar.js and fullcalendar.css in the header of layout - create a new js file called calendar and write the following code: *
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#my_calendar').fullCalendar({
editable: true,
droppable: true,
theme: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'month',
height: 500,
slotMinutes: 15,
loading: function(bool){
if (bool)
$('#loading').show();
else
$('#loading').hide();
},
// a future calendar might have many sources.
eventSources: [{
url: '/events/index/',
color: 'yellow',
textColor: 'black',
ignoreTimezone: false
}],
dragOpacity: "0.5",
//http://arshaw.com/fullcalendar/docs/event_ui/eventDrop/
eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc){
updateEvent(event);
},
// http://arshaw.com/fullcalendar/docs/event_ui/eventResize/
eventResize: function(event, dayDelta, minuteDelta, revertFunc){
updateEvent(event);
},
// http://arshaw.com/fullcalendar/docs/mouse/eventClick/
eventClick: function(event, jsEvent, view){
window.location = ('/events/show?id=' + event.id)
},
});
});
function updateEvent(the_event) {
$.ajax({
type: 'POST',
url: '/events/update_js?id='+ the_event.id +"&startd=" + the_event.start+"&endd=" + the_event.end, //the script to call to get data
data: {end: the_event.end, start: the_event.start } , //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function() //on receive of reply
{
alert("done!")
}
});
};
There are other code in the model and view in which the calendar will appear. also I changed the code of edit event function because it didn't work with me and function in the controller of event for edit- for any help I'm here any time. hope you can use it as I did