how do i display the end time of an even in fullcalendar? My event is triggered right, but there is no end time displayed
This is an example event. Did i miss something?
title:'WM 2010 - 03.06.2010 - 00:00',
description: 'Bei uns ist jeden Tag WM Party',
start: new Date(2010, 5, 3, 00, 5),
end: new Date(2010, 6, 3, 23, 6),
allDay: true
The appropriate solution in the most recent version of fullCalendar is to use displayEventEnd.
This is because timeFormat afects more stuff.
displayEventEnd allows us to even specify the views where we want the end time to be shown.
displayEventEnd: {
month: false,
basicWeek: true,
"default": true
}
Related
I am trying to set the description of a Google Calendar event to have a different selected presenter that is chosen in a rotatory manner (it is a slide deck that needs to be presented by a different person each week). The Python script specifying the rationale would work as the following
import datetime
people = ['Person 1', 'Person 2', 'Person 3']
year, week, day = datetime.date.today().isocalendar()
print(people[week_of_year % len(people)])
the resulting person from this calculation would show up in the calendar event description. Is there any tool to do that?
I was not able to find a way to create a recurrent event with different descriptions for each event.
However, I found a workaround for you using Events: patch. You first create an event using Events: insert, get the ID of the event you created with Events: list, and after that, then get the ID of the recurrences using Events: instances. Lastly, you use Events: patch to add the new description.
It might sound long, but I'm adding a sample with explanations on how to use it.
# impor the libraries that you will use for the calendar API
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# The scopes that we need to use based on the Google documentation
# I added the information in the reference at the end of the answer
SCOPES = ['https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/calendar.events']
# creation of the credential, I use as a base the Google Documentation "Python quickstart"
def main():
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('calendar', 'v3', credentials=creds)
# The list of people that will be use in each event
peoples = ['Person 1', 'Person 2', 'Person 3', 'Person 4']
number_week = 0
event = {
# Event title
'summary': 'Testing create description',
# A test description will be replaced later, so you can add anything you want to it.
'description': 'test',
# The start and end dates need to be in ISO-8601 date format
# and the time zone needs to be formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich
'start': {
'dateTime': '2022-10-28T09:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'end': {
'dateTime': '2022-10-28T17:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'recurrence': [
# You can change the recurrence of the event
# for this example is a weekly event, and it has 4 recurrences
'RRULE:FREQ=WEEKLY;COUNT=4'
],
# The list of attendees
'attendees': [
{'email': 'test#email.xyz'},
{'email': 'test2#email.xyz'},
],
'reminders': {
'useDefault': False,
'overrides': [
{'method': 'email', 'minutes': 24 * 60},
{'method': 'popup', 'minutes': 10},
],
},
}
# We use insert to create the event
event = service.events().insert(calendarId='primary', body=event).execute()
# You can use the print in the next line to see the information about the event while you are testing
# print('Event created: %s' % (event.get('htmlLink')))
page_token = None
# Search for the event, using the method list and the event title q='Testing create description'
# you can use any other search key to get the event ID
events = service.events().list(calendarId='primary', pageToken=page_token, q='Testing create description').execute()
# get the ID of the event
for event in events['items']:
# print(event['id'])
id_event = event['id']
# Will search the ID of the recurrences of the event using the method instances
# e.g. xxxxxxxxxxxxxxxxx_20221028T160000Z
while True:
recurrences_for_events = service.events().instances(calendarId='primary', eventId=id_event,
pageToken=page_token).execute()
# run the dictionary of each iteration
for recurrence_instance in recurrences_for_events['items']:
id_to_update = recurrence_instance['id']
# I used the next print just to review the IDs of each event
# print(id_to_update)
# Create the new body of the event with the name of the people in the list of peoples
# instead of using year, week, day = datetime.date.today().isocalendar(). I use a simple counter to iterate on the list
body = {
'description': peoples[number_week],
}
# update the event description with patch
updated_event = service.events().patch(calendarId='primary', eventId=id_to_update, body=body).execute()
# print(updated_event['description'])
# next patch in case you have a large recurrence of the event
page_token = events.get('nextPageToken')
number_week += 1
# This will reset the counter, in case the number of people is less than the recurrences of the event
if number_week >= len(peoples):
number_week = 0
if not page_token:
break
except HttpError as error:
print('An error occurred: %s' % error)
if __name__ == '__main__':
main()
If the recurrent event has already been created, you only need to use the imports until the number_week = 0, and the part from:
events = service.events().list(calendarId='primary', pageToken=page_token, q='Testing create description').execute()
To the end, you might need to modify the for loop to only run once per recurrence.
Reference:
Python quickstart
Events: insert
Events: list
Events: instances
Events: patch
ISO 8601
I'm extremely confused about how to do this. The documentation of Awesome is not clear to me at all, nor following stuff from the rc.lua helps. All I wanna do is to pop up the calendar upon clicking the textclock widget (with LMB), though I don't know how to start with it because the documentation has no examples (or at least I could not find it after spending 1 hour of googling), and the rc.lua has many different lines and arguments in each of them, making me unable to do anything.
My idea was
awful.button({}, 1, function() wibox.widget.calendar.year(os.date('*t')) end)
, but I have no clue how to attach this to the textclock widget. Also, I'm not quite sure if that is going to work anyway (that is, after I manage to attach it to the textclock). I'd wanna avoid adding too many widgets that I can interact with, and keep it simple, with as few as possible.
Thank you in advance, and I hope I didn't make anyone pull their hair out...
AwesomeWM concept of "buttons" can be split into 2 APIs. First of all, there is the button widget, which actually doesn't do much and is just a glorified wibox.widget.imagebox. This is the part not super relevant to your question.
The other part, which is relevant, is the event model. There are 2 ways to get something to happen when you click on a widget. The first one are the signals. Each widget has a button::press, button::release, mouse::enter and mouse::leave signals. You can attach a function to a signal this way:
mytextclock:connect_signal("button::press", function(self, lx, ly, button, mods, metadata)
wibox.widget.calendar.year(os.date('*t'))
end)
That API is more rich than a simple button. You get a lot of geometry and layout information you don't get from awful.button. However, it is overkill for simple buttons, thus awful.button.
Each widget has a :buttons() method in AwesomeWM < v4.4 or a .buttons object property in AwesomeWM >= v4.4. There are several examples in rc.lua of how to add some awful.buttons to these widget. Here are the snippets for the mylayoutbox widget:
For < v4.4:
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
for >= v4.4:
s.mylayoutbox = awful.widget.layoutbox {
screen = s
}
s.mylayoutbox.buttons = {
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc(-1) end),
awful.button({ }, 5, function () awful.layout.inc( 1) end),
}
-- That works too.
s.mylayoutbox:add_button(awful.button({ }, 1, function () awful.layout.inc( 1) end))
As for the lack of examples in the documentation. That's a fair point. I will add some.
Is it possible to define custom day names, short day names, month names etc. in FullCalendar version 5? I believe most of the localization is now done natively using javascript's Intl object. But I need to define latin names, which are not to be found in the Intl object. Can it be done with a custom locale file or maybe upon initialization of the calendar by passing in a property? From my tests neither of the two are working but maybe I'm just not doing it right?
let calendar = new FullCalendar.Calendar(calendarEl, {
dayMaxEvents: true,
events: $events,
locale: 'la',
dayNames: ['Dies Solis','Dies Lunae','Dies Martis','Dies Mercurii','Dies Iovis','Dies Veneris','Dies Saturni'],
dayNamesShort: ['Sol','Lun','Mart','Merc','Iov','Ven','Sat']
});
and the locale file la.js :
FullCalendar.globalLocales.push(function () {
'use strict';
var la = {
code: "la",
week: {
dow: 1, // Monday is the first day of the week.
doy: 4 // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: "Prior",
next: "Prox",
today: "Hodie",
month: "Mensis",
week: "Hebdomada",
day: "Dies",
list: "Agenda"
},
weekText: "Hb",
allDayText: "Tota die",
moreLinkText: function(n) {
return "+alii " + n;
},
noEventsText: "Rei gestae non sunt"
};
return la;
}());
(which I am loading via a script tag: <script src='../lib/locales/la.js'></script>).
Some things are picked up from the locale file, for example I see hodie instead of today.
I've tried defining dayNames and dayNamesShort in the locale file but doesn't seem to work either.
I guess this is pretty common task in most languages, however it was not clear to me how to get this done in my Flutter app. How to retrieve DateTime object of the last midnight in Dart? Or potentially, any particular time today / tomorrow / yesterday?
This should do the same
var now = DateTime.now();
var lastMidnight = DateTime(now.year, now.month, now.day);
You can use this way to get different times of this day
var tomorrowNoon = DateTime(now.year, now.month, now.day + 1, 12);
var yesterdaySixThirty = DateTime(now.year, now.month, now.day - 1, 6, 30);
Depending on what you want can absolute values be more safe because adding/subtracting Duration can result in surprises because of leap years and daylight saving time.
Try this package Jiffy, uses the simplicity of momentjs syntax. See below
To get last midnight
var lastMidnight = Jiffy().subtract(days: 1).startOf(Units.DAY);
print(lastMidnight.dateTime); // 2019-10-20 00:00:00.000
//or you can also format it
print(lastMidnight.yMMMMEEEEdjm); // Sunday, October 20, 2019 12:00 AM
EDIT: Use this solution only if you are working with UTC (daylight saving times might mess it up), or rather use the accepted answer anyway.
The simplest solution I found so far:
final now = DateTime.now();
final lastMidnight = now.subtract(Duration(
hours: now.hour,
minutes: now.minute,
seconds: now.second,
milliseconds: now.millisecond,
microseconds: now.microsecond,
));
Then we can get any other time or day relative to today by subtracting or adding Duration, e.g.:
final tomorrowNoon = lastMidnight.add(Duration(days: 1, hours: 12));
final yesterdaySixThirty = lastMidnight
.subtract(Duration(days: 1))
.add(Duration(hours: 6, minutes: 30));
Note that DateTime is immutable and both methods (add, subtract) return a new object.
I use a popup form to add events to the fullcalendar.
When I click on the events I want that popup to show all the data filled in to change or to delete the event.
I succeed in adding all in the textboxes but my formatting of the date and time is wrong.
How can I change the format?
eventClick: function(calEvent, jsEvent, view) {
$("#id").val(calEvent.id);
$("#date").val(calEvent.start);
$("#start").val(calEvent.start);
$("#end").val(calEvent.end);
$("#allday").val(calEvent.allDay);
$("#title").val(calEvent.title);
$("#location").val(calEvent.location);
$("#description").val(calEvent.description);
$("#url").val(calEvent.url);
//open form
$(".modalbox").trigger('click');
}
I get the values as 2013-09-12 14:00:00
So I want to show the date as 2013-09-12 and the start/end-time as 14:00 e.g.
thx
You can use $.fullCalendar.formatDate(from, format); to convert date and time. Some example:
$('#calendar-container').fullCalendar({
eventClick: function(calEvent, jsEvent, view){
var start = $.fullCalendar.formatDate(calEvent._start, 'dd.MM.yyyy HH:mm:ss');
var end = $.fullCalendar.formatDate(calEvent._end, 'dd.MM.yyyy HH:mm:ss');
alert('start: ' + start + '; end: ' + end);
}
});
As of fullcalendar 2.1.1 formatDate no longer seems to be supported.
Happy to mention the integration of moment.js to fullCalendar.
Read Moment.js Documentation, formatting as such:
moment().format('MMMM Do YYYY, h:mm:ss a'); // September 16th 2014, 6:38:44 pm
moment().format('dddd'); // Tuesday
moment().format("MMM Do YY"); // Sep 16th 14
moment().format('YYYY [escaped] YYYY');