Rails webpack js and refresh on ajax - javascript

I have a calendar module rendered in webpack js - app/javascript/packs/application.js
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new Calendar(calendarEl, {
plugins: [ interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, momentPlugin ],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: '2018-01-12',
navLinks: true, // can click day/week names to navigate views
editable: true,
eventLimit: true, // allow "more" link when too many events
selectable: true,
events: '/events.json',
select: function(info) {
$.getScript('/events/new', function(){
$('#event_date_range').val(moment(info.start).format('YYYY-MM-DD HH:mm') + ' - ' + moment(info.end).format('YYYY-MM-DD HH:mm'));
$('#start_date').val(moment(info.start).format('YYYY-MM-DD HH:mm'));
$('#end_date').val(moment(info.end).format('YYYY-MM-DD HH:mm'));
});
}
});
calendar.render();
});
I have a create action and would like to re-render the calendar on successful callback - create.js.erb. How can I do this?

Note: I'm assuming you're using Rails 6. I'm also assuming you added format.js to your create action.
Forget about create.js.erb, you won't need it here.
Also, you shouldn't put your code in app/javascript/packs/application.js.
The comments in that file read:
This file is automatically compiled by Webpack, along with any other files present in this directory. You're encouraged to place your actual application logic in a relevant structure within app/javascript and only use these pack files to reference that code so it'll be compiled.
This is how you would structure it:
Create the folder app/javascript/calendar and inside that folder, create a file index.js with your code in it:
// import your calendar object (put it in a file calendar.js in the same folder)
import Calendar from './calendar';
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new Calendar(calendarEl, {
plugins: [ interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, momentPlugin ],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: '2018-01-12',
navLinks: true, // can click day/week names to navigate views
editable: true,
eventLimit: true, // allow "more" link when too many events
selectable: true,
events: '/events.json',
select: function(info) {
$.getScript('/events/new', function(){
$('#event_date_range').val(moment(info.start).format('YYYY-MM-DD HH:mm') + ' - ' + moment(info.end).format('YYYY-MM-DD HH:mm'));
$('#start_date').val(moment(info.start).format('YYYY-MM-DD HH:mm'));
$('#end_date').val(moment(info.end).format('YYYY-MM-DD HH:mm'));
});
}
});
// actually, you want to put that addEventListener on your form
// more on 'ajax:success': https://guides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
document.body.addEventListener('ajax:success', function(event) {
var detail = event.detail;
var data = detail[0], status = detail[1], xhr = detail[2];
if (status === 'OK') { // upon success
// do something
// re-render the calendar
calendar.render();
}
})
calendar.render();
});
Note the part I added:
// actually, you want to put that addEventListener on your form
// more on 'ajax:success': https://guides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
document.body.addEventListener('ajax:success', function(event) {
var detail = event.detail;
var data = detail[0], status = detail[1], xhr = detail[2];
if (status === 'OK') { // upon success
// do something
// re-render the calendar
calendar.render();
}
})
Next, you create your pack file app/javascript/packs/calendar.js and inside it, you just reference your module like so:
// importing calendar module
import '../calendar';
Now Webpack will compile your file automatically.
What's left is using the helper javascript_pack_tag that adds a script tag that references the named pack file compiled by webpack : <%= javascript_pack_tag 'calendar' %>. Add this at the bottom of your view file (for example index.html.erb).
Hope this helps.

You can use addEvent method to add the new event to the calendar
https://fullcalendar.io/docs/event-object
https://fullcalendar.io/docs/Calendar-addEvent-demo
in the success callback of create action
$.ajax({
...
}).done(function (response) {
// Add event to calendar
calendar.addEvent({
title: response.title,
start: response.start_date,
end: response.end_date,
allDay: response.all_day
})
})

Related

Calling function whenever full calendar view changes in Angular 8

I am using full calendar in my angular 8 app. Everything is working fine, but I want to call a function whenever the currentView of calendar changes. that is, I want to call a function/event whenever I change its view from month to week, or week to days.
For clarity, I want to detect view template changes (not date range changes). And by detecting it I want to highlight the button of respective current view.
This is my html code.
<p-fullCalendar #fc [events]="allEvents" [options]="options"></p-fullCalendar>
This is my .ts code
this.options = {
plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
defaultDate: moment().toDate(),
themeSystem: 'yeti',
header: {
left: 'prev,next',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
}, dateClick: (e) => {
this.dateClicked(e);
}, eventClick: (e) => {
this.eventClicked(e);
},
}
In fullCalendar 4 you can use the viewSkeletonRender callback - this runs whenever a new view template is loaded.
viewSkeletonRender: function(info)
{
console.log(info); //replace with whatever code you need.
}

Events are duplicated when switching months in Fullcalendar v4

I'm using Fullcalendar v4 like this. Events are loaded correctly, but when I manually add a new one (it is also saved to SQL database via ajax call), then I change month and return back, this event is rendered twice. I'm not sure what cause this, because when I change months again, event is still doubled only, not trippled.
I've tried set lazyLoading or cache to false and also, for example, remove all events before rendering with $('.fc-event').remove(); but it did not help.
var calendar = new FullCalendar.Calendar(document.getElementById('calendar'), {
defaultView: 'resourceTimeline30',
views: {
resourceTimeline30: {
type: 'resourceTimeline',
duration: { days: 30 }
}
},
editable: false,
selectable: true,
resources: [ ... ],
events: 'https://www.example.com/?fullcalendar=load',
/*
// did not help
lazyLoading: true,
events: {
url: 'https://www.example.com/?fullcalendar=load',
cache: false,
extraParams: function() {
return {
cachebuster: new Date().valueOf()
};
}
}
*/
});
calendar.render();
So, if anybody needs it, according comments above, the working solution is:
Replace:
events: 'https://www.example.com/?fullcalendar=load',
With
eventSources: [{
'id': 1,
'url': 'https://www.example.com/?fullcalendar=load'
}],
And use that ID as second parameter in addEvent()
calendar.addEvent(event, 1);

Is it possible to email listWeek

Is it possible to send output to email instead of
<div id="fullCalendar" ></div>
after a full night, surfing the web, i cant find the solution, i'm no jquery programmer, so i realy hope some one can point me in the right direction
$(function() {
'use strict';
$('#fullCalendar').fullCalendar({
locale: 'nl',
defaultView: 'listWeek',
events: 'admin_app/kalender_load.php',
eventColor: '',
selectable:true,
selectHelper:true
});
});
$.post("email.php", { data : $("div#fullCalendar").html() }, function(result){
/* handle results */
});
I aspect to send the events from upcomming week true email,
but all i get is an empty mail
fullCalendar renders its content asynchronously - both the view and the events are rendered in separate asynchronous processes. You are trying to capture the content before it has been drawn (and in the case of the events, before the data has even been downloaded from your server).
You can use the viewRender callback to cause your code to wait until the calendar has been rendered.
Or if you need to include event data (which I guess you might) then you should use eventAfterAllRender instead, which waits until your events have been downloaded and drawn as well (this always occurs after the view has been rendered):
$(function() {
'use strict';
$('#fullCalendar').fullCalendar({
locale: 'nl',
defaultView: 'listWeek',
events: 'admin_app/kalender_load.php',
eventColor: '',
selectable: true,
selectHelper: true,
eventAfterAllRender: function(view) {
console.log($("div#fullCalendar").html())
$.post("email.php", {
data: $("div#fullCalendar").html()
}, function(result) {
/* handle results */
});
}
});
});
Demo: http://jsfiddle.net/baqdx94e/2/

Fullcalendar : Duplicates on agendaWeek view

I'm trying to use FullCalendar v2.4.0 (with jQuery 1.10.2 and moment.js 2.1) in order to display events that are stored in a database.
I'm using json to send events to FullCalendar.
I have some problems of duplicated events in the 'agendaWeek' view.
Everything is working properly for the other views ('month', 'basicWeek', 'basicDay', 'agendaDay').
As i read on stackoverflow, I tried to remove the event source, to remove events,... but i'm still facing the problem.
Here's how the code looks like :
$('#calendar').fullCalendar({
header: {
left: 'prev,next,today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '<?=date("Y-m-d")?>',
defaultView: 'agendaDay',
timeFormat: 'HH:mm',
displayEventEnd: true,
events: {
url: '/events_getlist_json.php',
type: 'GET',
cache: false,
error: function() {
alert('there was an error while fetching events!');
},
success: function(data) {
$(data).each(function(index) {
console.log( index + ": " + data[index].start );
})
}
}
});
$(document).ready(function() {
setTimeout(function(){
$('#calendar').fullCalendar('render');
}, 100);
});
The console log returns 2 events : "0: 2015-08-24T11:00:00" and "1: 2015-08-26T12:30:00" but i can see 4 of them on the calendar.
If you have any idea why duplicates happen in 'agendaWeek' view only, and how to remove them, it would be really nice to help.
Thank you in advance.
edit : added version of the 3 scripts
This was worked out in the comment between the OP and I.
Fullcalendar 2.4.0 conflicts with momentjs 2.1 causing duplicate events to appear in the agendaWeek view. Upgrade to the latest momentsjs to fix the issue.

fullCalendar renderEvent not sticking

I'm trying to insert an event to my fullcalendar and let it be there when i refresh the page but it's disappeared for some reason.
<script>
$(document).ready(function() {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
selectable: true,
selectHelper: true,
select: function(start, end) {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true);
}
$('#calendar').fullCalendar('unselect');
},
})
});
</script>
I have try to change the code as well so it look samthing like this
if (title)
{
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay },
true
);
}
calendar.fullCalendar('unselect');
},
but i just got nothing on the page like i missing something
The data disappears when you refresh the page because you haven't saved the new event anywhere, nor do you have any functions to retrieve the previously-saved events. The new event exists solely within browser document. As soon as you leave the page, the document's data is discarded.
You need to save the data somewhere—client-side or server-side—then you need to retrieve that saved data each time the page loads. Traditionally programmers store data server-side, usually in databases. Client-side storage stores data in the browser and can be useful if users only need to access their own data but comes with many limitations (e.g., your work computer and home computer will have different saved data).

Categories

Resources