I'm using the FullCalendar package as well as the below code which is working perfectly:
HTML:
<body>
{{>calendar}}
</body>
</template>
<template name="calendar">
{{#if showEditEvent}}
{{>editEvent}}
{{/if}}
<div class="container">
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div id="calendar">
</div>
</div>
<div class="col-md-2">
</div>
</div>
</div>
</template>
<template name="editEvent">
<!--Modal Dialog-->
<div class="modal" id="EditEventModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria- hidden="true">x</button>
<h4 class="modal-title">Agenda Item</h4>
</div>
<div class="modal-body">
<label for="title">Item: </label><input type="text" class="title" name="title" value="{{evt.title}}" id="title">
</div>
<div class="modal-footer">
Delete
Save
Cancel
</div>
</div>
</div>
</div>
JS:
// Set session defaults
Session.setDefault('editing_calevent', null);
Session.setDefault('showEditEvent', false);
Template.calendar.showEditEvent = function(){
return Session.get('showEditEvent');
}
Template.editEvent.evt = function(){
// run a query to the database
var calEvent = CalEvents.findOne({_id:Session.get('editing_calevent')});
return calEvent;
}
var updateCalendar = function(){
$('#calendar').fullCalendar( 'refetchEvents' );
}
Template.editEvent.events({
'click .save':function(evt,tmpl)
{updateCalEvent(Session.get('editing_calevent'),tmpl.find('.title').value);
Session.set('editing_calevent',null);
Session.set('showEditEvent',false);
},
'click .close':function(evt,tmpl){
Session.set('editing_calevent',null);
Session.set('showEditEvent',false);
$('#EditEventModal').modal("hide");
} ,
'click .remove':function(evt,tmpl){
removeCalEvent(Session.get('editing_calevent'));
Session.set('editing_calevent',null);
Session.set('showEditEvent',false);
$('#EditEventModal').modal("hide");
}
})
Template.calendar.rendered = function(){
$('#calendar').fullCalendar({
header:{
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
// Event triggered when someone clicks on a day in the calendar
dayClick:function( date, allDay, jsEvent, view) {
// Insert the day someone's clicked on
CalEvents.insert({title:'New Item',start:date,end:date});
// Refreshes the calendar
updateCalendar();
},
eventClick:function(calEvent,jsEvent,view){
// Set the editing_calevent variable to equal the calEvent.id
Session.set('editing_calevent',calEvent.id);
// Set the showEditEvent variable to true
Session.set('showEditEvent', true);
$('#EditEventModal').modal("show");
},
eventDrop:function(calEvent){
CalEvents.update(calEvent.id,
{$set: {start:calEvent.start,end:calEvent.end}});
updateCalendar();
},
events: function(start, end, callback) {
// Create an empty array to store the events
var events = [];
// Variable to pass events to the calendar
// Gets us all of the calendar events and puts them in the array
calEvents = CalEvents.find();
// Do a for each loop and add what you find to events array
calEvents.forEach(function(evt){
events.push(
{ id:evt._id,title:evt.title,start:evt.start,end:evt.end});
})
// Callback to pass events back to the calendar
callback(events);
},
editable:true
});
}
var removeCalEvent = function(id,title){
CalEvents.remove({_id:id});
updateCalendar();
}
var updateCalEvent = function(id,title){
CalEvents.update(id, {$set: {title:title}});
updateCalendar();
}
My two part question is:
A) how do i integrate something like the below in order to have more than one custom fields in the JSON feed?
B) how do I store the resultant data in a new Mongo Collection?
$(document).ready(function() {
$('#bootstrapModalFullCalendar').fullCalendar({
events: '/hackyjson/cal/',
header: {
left: '',
center: 'prev title next',
right: ''
},
eventClick: function(event, jsEvent, view) {
$('#modalTitle').html(event.title);
$('#modalBody').html(event.description);
$('#eventUrl').attr('href',event.url);
$('#fullCalModal').modal();
}
});
});
Thank you.
Related
So, I'm working on a calendar app and I'm using Laravel and FullCalendar for this.
I want to be able to delete an event - once I click on the event in the calendar, a modal popup show up with a delete button. In order to delete the event, I must know its ID, but I can't get.
I can get it via JS selectors and display it as a text, but I can't figure out how to get it as a PHP variable so that I could use it in the action parameter of the form.
The reason why I'm doing this in the way I did it is: If I get all the events and "foreach" them into the "events" array of FullCalendar, my source code when the calendar renders would be a mess, full of events and their details. By using this approach, I find that events are not displayed in the source and the page renders more quickly (but I might be mistaken).
The way I display events from the database is as follows:
EventsController
public function getEvents()
{
return Event::where('event_date', '>', '2022-01-01')
->join('hospitals', 'events.hospital_id', '=', 'hospitals.hospital_id')
->select('hospitals.hospital_color', 'hospitals.hospital_max_people', 'event_id', 'event_content', 'event_date', 'user_id')
->get()
->map(fn ($events) => [
'id' => $events->event_id,
'title' => $events->event_content,
'start' => $events->event_date,
'allDay' => true,
'editable' => false,
'backgroundColor' => $events->hospital_color,
'borderColor' => $events->hospital_color,
'hospital_max_people' => $events->hospital_max_people,
'volunteer' => User::find($events->user_id)->first_name .' '. User::find($events->user_id)->last_name
]);
}
Events blade template - FullCalendar settings:
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
editable: false,
droppable: true,
selectable: true,
initialView: 'dayGridWeek',
views: {
dayGridWeek: {
type: 'dayGridWeek',
duration: { weeks: 2 },
buttonText: '4 day'
}
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,listMonth'
},
themeSystem: 'bootstrap5',
locale: 'en',
firstDay: '1',
contentHeight: 500,
height: 700,
expandRows: true,
events: 'getEvents',
eventClick: function(calendar, jsEvent, view) {
$('#eventDetail').modal("show");
$('#id').html(calendar.event.id);
$('#title').html(calendar.event.title);
$('#start').html(moment(calendar.event.start).format('DD.MM.YYYY'));
$('#volunteer').html(calendar.event.extendedProps.volunteer);
}
});
calendar.render();
});
</script>
Events blade template for showing modal:
<div class="modal fade" id="eventDetail" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="bar" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Event details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Start: <p id="start"></p>
Volunteer: <p id="volunteer"></p>
Title: <p id="title"></p>
</div>
<div class="modal-footer">
<form method="POST" action="{{ route('calendar.destroy') }}" class="needs-validation" novalidate=""></p>
#csrf
#method('DELETE')
<div class="form-group">
<x-button tabindex="3">
{{ __('Delete event') }}
</x-button>
</div>
</form>
</div>
</div>
</div>
</div>
So, I did it in anoter way; just wanted to post the answer - I added a hidden input field: <input type="hidden" name="id" id="id" value=""> and the value is filled out when a modal opens with addition of this to the original id selector: $('#id').html(calendar.event.id).attr('value', calendar.event.id);
I also had to alter my delete route: Route::DELETE('calendar/destroy/{event_id}'
And that's it. Thank you anyway for your help
I want to enter a Calendar Event details using Bootstrap modal... But that modal is not invoking, when I click on date of a Calendar....
I google for it, it shows me the following code... But it won't work for me...
select: function(start, end, allDay)
{
$('#myModal').modal('show');
},
I followed the following URL Fullcalendar (Arshaw) - Adding an event with modal window
CalendarView
Calling Modal from Calendar
<head>
var calendar = $('#calendar').fullCalendar({
editable:true,
header:{
left:'prev,next today',
center:'title',
right:'month,agendaWeek,agendaDay'
},
events:'load',
selectable:true,
select: function(start, end, allDay)
{
$('#myModal').modal('show');
},
</head>
Modal to call
<div id="calendar">
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×
</button>
</div>
<!-- Modal body -->
<div class="modal-body">
Modal body..
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
You should enclose your scripts on a <script> tag:
<head>
<script>
var calendar = $('#calendar').fullCalendar({
editable:true,
header:{
left:'prev,next today',
center:'title',
right:'month,agendaWeek,agendaDay'
},
events:'load',
selectable:true,
select: function(start, end, allDay)
{
$('#myModal').modal('show');
},
</script>
</head>
Instead of 'select', try using 'dateClick' event when you click on an empty date cell, or 'eventClick' when you click on an event -perhaps you'd like to edit it.
Vue.component('full-calendar', {
template: '<div ref="calendar"></div>',
props: {
tasks: {
type: Array,
required: true
},
newtask: Object
},
watch: {
tasks: function (task) {
// this.tasks.push(task);
// this.cal.calendar.addEvent({
// title: task.title,
// start: task.start,
// end: task.end
// });
$("#addTaskModal").modal('hide');
}},
data () {
return {
cal: null
}
},
methods: {
init:function(){
var self = this;
self.cal = $(self.$refs.calendar);
var args = {
firstDay: 1,
lang: 'en',
header: {
left: 'prev,next today',
center: 'title',
right: 'addTaskButton / dayGridMonth,timeGridWeek,listMonth'
},
height: "auto",
allDaySlot: false,
slotEventOverlap: false,
timeFormat: 'HH:mm',
plugins: ["interaction", "dayGrid"],
eventLimit: true,
events: this.tasks,
dateClick: function(date)
{
self.$emit('date_clicked', date);
console.log('date clicked');
console.log(this);
},
eventClick: function(event)
{
self.$emit('event_clicked', event);
},
customButtons: {
addTaskButton: {
text: 'Add Task',
click: function() {
$("#addTaskModal").modal('show');
}
}
}
}
if (self.editable)
{
args.editable = true;
args.eventResize = function(event)
{
self.$emit('event::resized', event);
}
args.eventDrop = function(event)
{
self.$emit('event::dropped', event);
}
}
if (self.droppable)
{
args.droppable = true;
args.eventReceive = function(event)
{
self.$emit('event::received', event);
}
}
self.cal.calendar = new FullCalendar.Calendar(self.$el,args);
self.cal.calendar.render();
}
},
mounted () {
this.init();
}
})
let vm = new Vue({
el: '#app',
data () {
return {
tasks: [
{
title: 'Event1',
start: '2019-05-10 12:30:00',
end: '2019-05-10 16:30:00'
},
{
title: 'Event2',
start: '2019-05-07 17:30:00',
end: '2019-05-07 21:30:00'
}
],
editable: false,
selectedDate : moment().format('DD-MM-YYYY'),
task: {
title:null,
start: '2019-05-07 17:30:00',
end: '2019-05-07 21:30:00'
},
newtask: {}
}
},
methods: {
addTask: function(event){
var d = moment().format('YYYY-MM-DD');
var sel = new Date(this.selectedDate.replace( /(\d{2})-(\d{2})-(\d{4})/, "$2/$1/$3"));
//console.log();
var date = new Date(moment(sel).format('YYYY-MM-DD')+ 'T00:00:00'); // will be in local time
this.tasks.push({
title: this.task.title,
start: date,
end: date
});
this.$nextTick(function () {
// DOM is now updated
// `this` is bound to the current instance
//this.doSomethingElse()
})
},
dateClicked: function(date) {
this.selectedDate = moment(date.date).format('DD-MM-YYYY');
},
eventClicked: function(event) {
this.selectedDate = moment(event.event.start).format('DD-MM-YYYY');
},
showObject: function() {
console.log(this.tasks);
}
}
})
<link href="https://fullcalendar.io/releases/core/4.1.0/main.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script src="https://fullcalendar.io/releases/core/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/daygrid/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/interaction/4.1.0/main.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<div class="container mt-5" id="app">
<div>
<div class="row">
<div class="col-md-8">
<full-calendar
v-bind:tasks="tasks"
v-on:date_clicked="dateClicked"
v-on:event_clicked="eventClicked"
:newtask="newtask"
></full-calendar>
</div>
<div class="col-md-4">
<div class="pb-3">
<span id="CurrentDate" class="" style="cursor: pointer;">{{selectedDate}}</span>
<span class="badge badge-primary">{{tasks.length}}</span>
<button #click="showObject">show object</button>
</div>
<table class="table table-condensed">
<tbody v-for="task in tasks">
<tr>
<td>
<input
type="checkbox"
/>
</td>
<td>{{task.title}}</td>
<td></td>
</tr>
</tbody>
<tbody>
<tr v-if="tasks.length==0">
<td colspan="3" class="text-center">No tasks to display</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="addTaskModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add a task</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<input type="text" id="NewTaskTitle" placeholder="Enter task name" class="form-control" v-model="task.title" />
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success btn-sm" #click="addTask">Add</button>
<button data-bind="click: CancelAddNewTask" class="btn btn-seconday btn-sm" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
Hi everyone,
I am trying to bind an object ‘tasks’ with full calendar events however it is not working.
Please see example above provided. View it in full page please
When you add a task, I am expecting it to be added to the tasks objects and of course to be be binded to the events in full calendar.
Basically, I want to bind tasks array to full calendar events object, so if for example I remove an item should also be removed from the full calendar events
Please let me know if I am doing it wrong . thanks a bunch
[1]:
It should be as simple as updating the FullCalendar when new tasks are sent from the Parent (new Vue) to Child (full-calendar).
In your full-calendar component you should be able to just call the render() method which according to the FullCalendar docs will rerender the calendar if it already exists. In your architecture it is as simple as recalling the init() method. I also moved close modal logic to the appropriate place. This could probably user a bit more refactoriing but this should get you unstuck. Hope it helps.
watch: {
tasks: function (task) {
this.cal.calendar.render();
}
}
https://fullcalendar.io/docs/render
Vue.component('full-calendar', {
template: '<div ref="calendar"></div>',
props: {
tasks: {
type: Array,
required: true
},
newtask: Object
},
watch: {
tasks: function (task) {
this.init()
}
},
data () {
return {
cal: null
}
},
methods: {
init:function(){
var self = this;
self.cal = $(self.$refs.calendar);
var args = {
firstDay: 1,
lang: 'en',
header: {
left: 'prev,next today',
center: 'title',
right: 'addTaskButton / dayGridMonth,timeGridWeek,listMonth'
},
height: "auto",
allDaySlot: false,
slotEventOverlap: false,
timeFormat: 'HH:mm',
plugins: ["interaction", "dayGrid"],
eventLimit: true,
events: this.tasks,
dateClick: function(date)
{
self.$emit('date_clicked', date);
console.log('date clicked');
console.log(this);
},
eventClick: function(event)
{
self.$emit('event_clicked', event);
},
customButtons: {
addTaskButton: {
text: 'Add Task',
click: function() {
$("#addTaskModal").modal('show');
}
}
}
}
if (self.editable)
{
args.editable = true;
args.eventResize = function(event)
{
self.$emit('event::resized', event);
}
args.eventDrop = function(event)
{
self.$emit('event::dropped', event);
}
}
if (self.droppable)
{
args.droppable = true;
args.eventReceive = function(event)
{
self.$emit('event::received', event);
}
}
self.cal.calendar = new FullCalendar.Calendar(self.$el,args);
self.cal.calendar.render();
}
},
mounted () {
this.init();
}
})
let vm = new Vue({
el: '#app',
data () {
return {
tasks: [
{
title: 'Event1',
start: '2019-05-10 12:30:00',
end: '2019-05-10 16:30:00'
},
{
title: 'Event2',
start: '2019-05-07 17:30:00',
end: '2019-05-07 21:30:00'
}
],
editable: false,
selectedDate : moment().format('DD-MM-YYYY'),
task: {
title:null,
start: '2019-05-07 17:30:00',
end: '2019-05-07 21:30:00'
},
newtask: {}
}
},
methods: {
addTask: function(event){
var d = moment().format('YYYY-MM-DD');
var sel = new Date(this.selectedDate.replace( /(\d{2})-(\d{2})-(\d{4})/, "$2/$1/$3"));
//console.log();
var date = new Date(moment(sel).format('YYYY-MM-DD')+ 'T00:00:00'); // will be in local time
this.tasks.push({
title: this.task.title,
start: date,
end: date
});
$("#addTaskModal").modal('hide');
this.$nextTick(function () {
// DOM is now updated
// `this` is bound to the current instance
//this.doSomethingElse()
})
},
dateClicked: function(date) {
this.selectedDate = moment(date.date).format('DD-MM-YYYY');
},
eventClicked: function(event) {
this.selectedDate = moment(event.event.start).format('DD-MM-YYYY');
},
showObject: function() {
console.log(this.tasks);
}
}
})
<link href="https://fullcalendar.io/releases/core/4.1.0/main.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script src="https://fullcalendar.io/releases/core/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/daygrid/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/interaction/4.1.0/main.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<div class="container mt-5" id="app">
<div>
<div class="row">
<div class="col-md-8">
<full-calendar
v-bind:tasks="tasks"
v-on:date_clicked="dateClicked"
v-on:event_clicked="eventClicked"
:newtask="newtask"
></full-calendar>
</div>
<div class="col-md-4">
<div class="pb-3">
<span id="CurrentDate" class="" style="cursor: pointer;">{{selectedDate}}</span>
<span class="badge badge-primary">{{tasks.length}}</span>
<button #click="showObject">show object</button>
</div>
<table class="table table-condensed">
<tbody v-for="task in tasks">
<tr>
<td>
<input
type="checkbox"
/>
</td>
<td>{{task.title}}</td>
<td></td>
</tr>
</tbody>
<tbody>
<tr v-if="tasks.length==0">
<td colspan="3" class="text-center">No tasks to display</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="addTaskModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add a task</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<input type="text" id="NewTaskTitle" placeholder="Enter task name" class="form-control" v-model="task.title" />
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success btn-sm" #click="addTask">Add</button>
<button data-bind="click: CancelAddNewTask" class="btn btn-seconday btn-sm" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
watch: {
tasks: function (tasks) {
this.calendarOptions.events = tasks;
let calendarApi = this.$refs.fullcalendar.getApi();
calendarApi.render();
},
},
... ...
<FullCalendar
ref="fullcalendar"
:options="calendarOptions"
/>
Im a newbee on Meteorjs and Im testing an implementation of FullCalendar and meteor, and I got a strange problem with this modal in particular. is a modal for edit, It is supposed to trigger when you click on a list of links of events wich I successfuly test on other apps in the pass, I already have another modal for create events on this view and works fine. but in this case, it seems to not attach the js behavior correcly. the modal is displayed, but no effects and not working the close nor the submit buttons.
I wonder if in this particular case, Im losing something or some code tag or the FullCalendar is in conflict?, and for any help Thank you.
here is the demo deply on meteor.com gbelot.todo3.meteor.com
here is the code on gitHub: https://github.com/gbelot2003/meteor-todo-bt3/blob/todo3-icalendar/client/home
and here the controller and Templates code:
Meteor.subscribe("events");
Template.body.rendered = function () {
var fc = this.$('.fc');
this.autorun(function () {
Events.find();
fc.fullCalendar('refetchEvents');
});
};
Template.calendarEdit.helpers({
events: function(){
var fc = $('.fc');
return function (start, end, tz, callback) {
//subscribe only to specified date range
Meteor.subscribe('events', start, end, function () {
//trigger event rendering when collection is downloaded
fc.fullCalendar('refetchEvents');
});
var events = Events.find().map(function (it) {
return {
title: it.date,
start: it.date,
allDay: false
};
});
callback(events);
};
},
options: function() {
return {
id: 'myid2',
class: 'myCalendars',
lang: 'es',
allDaySlot: false,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
axisFormat: 'h:mm a',
timeFormat: {
agenda: 'h:mm a',
month: 'h:mm a',
agendaWeek: 'h:mm a'
},
firstHour: 7,
editable: true,
eventLimit: false,
events: function (start, end, timezone, callback) {
callback(Events.find({}).fetch());
},
defaultView: 'month'
};
}
});
Template.HomeTemplate.onRendered(function(){
var fc = this.$('.fc');
this.autorun(function () {
Events.find();
fc.fullCalendar('refetchEvents');
});
this.$('.datetimepicker').datetimepicker({
format: 'YYYY-MM-DD H:mm:ss'
});
});
Template.HomeTemplate.events({
'submit #new-event': function(event){
event.preventDefault();
var title = event.target.title.value;
var start = event.target.start.value;
var end = event.target.end.value;
var description = event.target.description.value;
Meteor.call("addEvent", title, start, end, description);
event.target.title.value = "";
event.target.start.value = "";
event.target.end.value = "";
event.target.description.value = "";
$("#createEvent").modal("hide");
},
/** this modal works well **/
/***************************/
'click .create': function(e){
e.preventDefault();
$("#createEvent").modal("show");
}
});
Template.HomeTemplate.helpers({
event: function(){
return Events.find();
}
});
Template.eventList.events({
'click .delete': function(event){
event.preventDefault();
id = this._id;
Meteor.call('deleteEvent', id);
},
/**** here is the call for the modal *****/
/** with problems. Did I miss something? */
/******************************************/
'click .update': function(e){
e.preventDefault();
$(".updateModal").show();
}
});
the homeTemplate here
<template name="HomeTemplate" id="home">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>Todos & FullCalendar Test</h2>
<hr/>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<h3>Full Calendar</h3>
<!--<button class="refresh">Refresh</button>-->
{{> calendarEdit }}
</div>
<div class="col-md-6 col-sm-12">
<h3>Events todo App <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span></h3>
<ul class="list-group">
{{#transition in="zoomIn" out="bounceOut"}}
{{#each event}}
{{> eventList}}
{{/each}}
{{/transition}}
</ul>
</div>
</div>
</div>
{{> createEvent}}
{{> updateModal}}
</template>
This is the Template where you click on link
<template name="eventList">
<li class="list-group-item">
<h4 class="list-group-item-heading">
<div class="row">
<div class="col-sm-10">
<a type="button" href="#" class="update">{{title}}</a>
</div>
<div class="col-sm-2">
<span class=" glyphicon glyphicon-trash text-danger" aria-hidden="true"></span>
</div>
</div>
</h4>
<p>{{start}} | {{end}}</p>
<p class="list-group-item-text">{{description}}</p>
</li>
</template>
this has been solve by using peppelg:bootstrap-3-modal, that package did the job!!!
I'm trying to edit objects with a modal Bootstrap. I've got that if you click over an event in Fullcalendar a form comes up with the info of that event (level,day,period) so I can edit the level and the day of that event(object). The problem is that when I click in the bottom save a new object is created instead of editing that event. Can't I get the params of the event clicked and change them??
This is my javascript where I set the eventClick function.
var y = "y";
function drawControl(controls) {
$('#calendar').fullCalendar({
editable: true,
aspectRatio: 1,
contentHeight: 500,
scrollTime: '24:00:00',
minTime: '01:00:00',
maxTime: '24:00:00',
defaultView: 'agendaWeek',
header:{left:"prev,next,today",
center:"title",
right:"month, agendaWeek, agendaDay"},
events: allControls(controls),
eventRender: function(event, element) {
var bloodLevel=event.title
if(bloodLevel >= 180) {
element.css('background-color', 'red');
}
else if(bloodLevel < 70) {
element.css('background-color', 'yellow');
}
},
eventClick: function(calEvent, jsEvent, view) {
x=calEvent.id;
$('#modalTitle').html(calEvent.title);
$('#control_day_edit').val(calEvent.start);
$('#control_level').val(calEvent.title.toString());
console.log(calEvent.title)
console.log(calEvent.start._i)
console.log(calEvent.id)
$('#eventUrl').attr('href',"/users/:user_id/controls/calEvent.id/edit");
$('#fullCalModal').modal();
y=calEvent;
}
})
}
});
document.getElementById('button_edit').addEventListener("click", editControl);
function editControl(event) {
event.preventDefault();
console.log(x);
var controlEdited = {
"level": document.getElementById('control_level').value,
"day": document.getElementById('control_day_edit').value,
"period": document.getElementById('control_period').value,
"id": x
}
$('#calendar').fullCalendar('updateEvent', y);
$.post("/editControls", JSON.stringify(controlEdited));
console.log(controlEdited)
};
This is the code of my controller
def editControls
if request.xhr?
#control = JSON.parse!(request.body.read.to_s)
Control.where(id: #control["id"])[0].update_attributes(level: #control["level"], day: #control["day"], period: #control["period"])
render json: "ok"
else
return error
end
end
This is the code of the view
<div id="fullCalModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span> <span class="sr-only">close</span></button>
<h4 id="modalTitle" class="modal-title"></h4>
</div>
<div id="modalBody" class="modal-body">
<%= render 'form_edit' %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button class="btn btn-primary"><a id="eventUrl" target="_blank">Event Page</a></button>
</div>
</div>
</div>
This is the form
<% modal ||= false %>
<% remote = modal ? true : false %>
<div class="">
<%= form_for [#user, #control],remote: remote, html: {role: :form, 'data-model' => 'control'} do |f| %>
<p class="new_control_text">Edit Control</p>
<div class="form-group">
<div class="input-group">
<%= f.label :level, class: "sr-only"%>
<%= f.number_field :level, class: "form-control", placeholder: "Enter level" %>
</div>
</div>
<div class="form-group container">
<div class="row datetimeselect">
<div class='col-sm-12'>
<div class="form-group">
<div class='input-group date' id='datetimepicker2'>
<%= f.text_field :day, default: #control_day, :class => 'form-control', id: "control_day_edit" %>
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="select_period">
<%= f.select :period, options_for_select([['pre-breakfast'], ['post-breakfast'],['pre-lunch'],['post-lunch'],['afternoon'],['pre-dinner'],['post-dinner']]), {}, class: "form-control" %>
</div>
<a href="#" id="button_edit" class="btn btn-default btn-lg" role="button">
Save
</a>
<% end %>
</div>
In your eventClick you have access to the calEvent object. You need to update this object to see it properly reflected in the calendar. Check out more of the event data methods in the fullCalendar docs
Your original event object has all the data inherent to your fullcalendar event. So you need to first get a hold of that object, then assign new values to the attributes you might want to change, and finally call the calendar with a with the "updateEvent" instruction.
The "updateEvent" reports changes to an event and renders them on the calendar.
.fullCalendar( 'updateEvent', event )
event must be the original Event Object for an event, not merely a reconstructed object. The original Event Object can obtained by callbacks such as eventClick, or by the clientEvents function.
Here is how you might update an event after a click:
$('#calendar').fullCalendar({
eventClick: function(event, element) {
event.title = "CLICKED!";
$('#calendar').fullCalendar('updateEvent', event);
}
});
Source: documentation
You need to make the event global.
Create a global variable
var evnt
Then within the fullcalendar click event give that variable the value of the event object.
eventClick: function (calEvent, jsEvent, view) {//click en un evento
evnt = calEvent;
//more actions
}
Then you have the event available for update in your modal or other function
function event_update(){
evnt.title = 'new title';
$('#calendar').fullCalendar('updateEvent', evnt);
}
I think you pretty much nailed it, you just needed to update the event object stored in the global y variable before calling updateEvent:
document.getElementById('button_edit').addEventListener("click", editControl);
function editControl(event) {
event.preventDefault();
console.log(x);
var controlEdited = {
"level": document.getElementById('control_level').value,
"day": document.getElementById('control_day_edit').value,
"period": document.getElementById('control_period').value,
"id": x
}
y.start = document.getElementById('control_day_edit').value;
y.title = document.getElementById('control_level').value;
$('#calendar').fullCalendar('updateEvent', y);
$.post("/editControls", JSON.stringify(controlEdited));
console.log(controlEdited)
};