Django Javascript Explanation - javascript

I have this code and I'm trying to make sense of it - I'm not really sure how it works-
{% if book %}
<script type='text/javascript'>
$(document).ready(function() {
$.get('/ajax/book/{{ book.id }}/timetable/', {}, function(data) {
data = JSON.parse(data);
var events = new Array();
for (var i in data) {
events.push({
id: data[i].id,
title: '{{ request.user.name }}',
start: Date.parse(data[i].startTime, "yyyy-MM-dd HH:mm:ss"),
end: Date.parse(data[i].endTime, "yyyy-MM-dd HH:mm:ss"),
allDay: false
});
}
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaDay,agendaWeek'
},
theme: true,
contentHeight: 400,
defaultView: 'agendaWeek',
selectable: true,
selectHelper: true,
eventClick: function(calEvent, jsEvent, view) {
},
select: function(start, end, allDay) {
var title = '{{ request.user.name }}';
$.post('/ajax/book/{{ book.id }}/timetable/new/', {
csrfmiddlewaretoken: getCookie('csrftoken'),
startTime: start.format("yyyy-mm-dd HH:MM:ss"),
endTime: end.format("yyyy-mm-dd HH:MM:ss"),
}, function(data) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
});
calendar.fullCalendar('unselect');
},
editable: true,
events: events,
eventResize: function(event, dayDelta, minuteDelta, revertFunc) {
alert(
"The end date of " + event.title + " has been moved " +
dayDelta + " days and " +
minuteDelta + " minutes."
);
if (!confirm("Is this okay?")) {
revertFunc();
}
}
});
});
});
</script>
From what I can tell, ajax/book/.../timetable and ajax/book/.../timetable/new call book_timetable(request,id) and book_timetable_new(request,id)-
url(r'^ajax/book/(?P<bookid>\d+)/timetable/$', twobooks.ajax.views.book_timetable),
url(r'^ajax/book/(?P<bookid>\d+)/timetable/new/$', twobooks.ajax.views.book_timetable_new),
where the functions are -
def book_timetable(request, bookid):
book = get_object_or_404(Book, id=bookid)
rawslots = TimeSlot.objects.filter(user=request.user).filter(book=book)
slots = []
for rawslot in rawslots:
slot = {
'id': rawslot.id,
'startTime': str(rawslot.startTime),
'endTime': str(rawslot.endTime),
}
slots.append(slot)
return HttpResponse(simplejson.dumps(slots))
def book_timetable_new(request, bookid):
book = get_object_or_404(Book, id=bookid)
startTime = datetime.strptime(request.POST['startTime'], "%Y-%m-%d %H:%M:%S")
endTime = datetime.strptime(request.POST['endTime'], "%Y-%m-%d %H:%M:%S")
timeslot = TimeSlot(
user = request.user,
book = book,
startTime = startTime,
endTime = endTime,
)
timeslot.save()
return JSONify("")
I'm trying to do something similar to this, except with other data, which is why I'm trying to get how this works. If anyone could explain it to me it'd be great!

This is a fairly standard AJAX pattern. The template is rendered by the original view, as normal. In the course of rendering, some elements of the Javascript which are marked as Django template variables are filled in - eg {{ book.id }} and {{ request.user.name }} - so that by the time it gets to the browser, those are indistinguishable from the rest of the JS.
Now, the Javascript makes a call to the server, passing those elements. The server responds with JSON data, which is parsed by the function which is the third parameter to the .get call. I haven't looked too deeply into that function, but it seems to be using that data to instantiate a fullCalendar, which is presumably a separate jQuery script.
One slightly strange thing is that the AJAX call is set to run as soon as the browser has loaded the page - normally there's no point doing that, since you could simply include the data in the original template. Usually AJAX is set to execute in response to some event in the browser, such as a button click.

Related

Adding a button to each cell in fullcalendar to allow user to add an event using jQuery

I have been using jQuery along with fullcalendar to create a calendar that displays events from a database using php and MYSQL.
The calendar looks like this.
The events are shown in red. I would like to be able to add a button in each of the cells that do not have an event to allow the user to be able to add one.
Here is the code I have tried
viewRender: function (view) {
$(".fc-content").append('<button>Add</button>')
}
my full code.
$(document).ready(() => {
const calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaWeek,agendaDay'
},
defaultView: 'agendaWeek',
defaultTimedEventDuration: '01:00',
allDaySlot: false,
scrollTime: '09:00',
businessHours: {
dow: [ 2, 3, 4, 5, 6 ],
start: '09:00',
end: '17:30'
},
//viewRender: function (view) {
// $(".fc-content").append('<button>Book</button>');
// },
long: /^en-/.test(navigator.language) ? 'en' : 'zh-cn',
eventOverlap: (stillEvent, movingEvent) => {
return true;
},
events:
<?php echo $json;?>
//'2018-12-12T15:00+08:00'
//},
//{
//title: '',
//start: '' //'2018-12-12T12:00+08.00'
,
eventColor: '#FF0000',
edittable: true,
selectable: true,
selectHelper: true,
select: (start, end) => {
const duration = (end - start) / 1000;
if(duration == 1800){
// set default duration to 1 hr.
end = start.add(30, 'mins');
return
calendar.fullCalendar('select', start, end);
}
let eventData;
if (title && title.trim()) {
eventData = {
title: title,
start: start,
end: end
};
calendar.fullCalendar('renderEvent', eventData);
}
calendar.fullCalendar('unselect');
},
eventRender: (event, element) => {
const start = moment(event.start).fromNow();
element.attr('title', start);
},
loading: () => {}
});
});
Ok first off, unless the button is required from UI/UX perspective, you can skip adding the button and just work with fullCalendars built-in method/events.
example (skipping irrelevant options):
fullCalendar({
...
editable: true,
selectable: true, // makes each day selectable
select: function (start, end) {
// in this select callback you are given the start and end dates of the user's selection
// when a user selects any cells this will fire and you can do stuff in here
// fullcalendar will always give 2 dates as callback, even if the user only selected 1
// date, the 'end' will correspond to the next day actually...
events: [{event1},{event2},{event3}], // use this to initialize the events already //existing
eventClick: function (event) {
// this is the handler that will run when the user clicks on an event, not a day! an //event on a day
}
}
})
I hope this helps, you can always read more on the docs
You do not need button ..
you can do it in function eventClick this trigger in click on any day
$('#calendar').fullcalendar({
eventClick : function(xEvent, jsEvent, view){ hus_eventClick(xEvent, jsEvent, view);} ,
});
and in function show dialog box to add event ..
https://fullcalendar.io/docs/dayClick

FullCalendar trying to fetch events from URL instead of array

Using FullCalendar v3.9.0 with jQuery v3.3.1. I have a SailsJS application that's getting the calendar data from MySQL.
this.me.calendar from MySQL currently looks like this.
[{"start":"2018-07-04T13:30:00","end":"2018-07-04T18:00:00","works":["2"]}]
And my FullCalendar code looks like this.
let that = this;
that.me.calendar = this.me.calendar;
$('#calendar').fullCalendar({
header: {
left: 'today prev,next',
center: 'title',
right: 'agendaWeek,agendaDay'
},
views: {
week: {
titleFormat: 'DD.MM.YYYY'
}
},
defaultView: 'agendaWeek',
locale: 'fi',
weekends: false,
scrollTime: '07:00',
businessHours: {
start: '7:00',
end: '21:00',
},
events: function(start, end, timezone, callback) {
let events = that.me.calendar ? that.me.calendar : [];
console.log(events);
callback(events);
},
editable: true,
selectable: true,
selectHelper: true,
select: (start, end) => {
let duration = (end - start) / 1000;
if (duration == 1800) {
// Set default duration to 1 hour
end = start.add(30, 'mins');
return $('#calendar').fullCalendar('select', start, end);
}
let eventData = {
start: start,
end: end,
works: []
}
$('#calendar').fullCalendar('renderEvent', eventData);
$('#calendar').fullCalendar('unselect');
},
eventClick: (event, element) => {
$('#event-works').text(event.works.join(','));
$('#start-date').text(moment(event.start).format('d.MM.YYYY HH:mm'));
$('#end-date').text(moment(event.end).format('d.MM.YYYY HH:mm'));
$('#workModal').modal('show');
$('#add-work-to-event').click(() => {
let work = $('#work').val();
if(_.includes(event.works, work)) return;
event.works.push(work);
$('#event-works').text(event.works.join(','));
});
}
});
While the code above doesn't send the GET, it doesn't display the events in the calendar. However, if I change the events to events: this.me.calendar, the SailsJS console displays GET /account/%22[%7B/%22start/%22:/%222018-07-04T13:30:00/%22,/%22end/%22:/%222018-07-04T18:00:00/%22,/%22works/%22:[/%222/%22]%7D]%22 (1ms 404).
I also tried changing it to events: JSON.stringify(this.me.calendar), which still gave the GET request in console.
If I enter the array in the events on it's own, it is working. Also the console.log inside the events function is returning the same array.
Is there a way for me to simply enter my array for FullCalendar, or do I have to make it get the JSON from an URL?
I managed to solve the issue by changing the let events inside of my events function to let events = that.me.calendar ? JSON.parse(that.me.calendar) : []; and now the events are being displayed.

DateTime conversion from FullCalendar to Controller PHP

I'm using FullCalendar to display a calendar on the web page (no surprise there).
A user can add events on the calendar, which is then passed through POST to the CodeIgniter controller. The controller executes a function in the model to insert the data in the database.
The problem I'm facing is that the date time, when inserted in the database adds 4 minutes for a reason i do not understand.
This is the JavaScript used for FullCalendar:
$(document).ready(function() {
var today = moment().day();
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
defaultView: 'agendaWeek',
eventLimit: true, // allow "more" link when too many events
selectable: true,
selectHelper: true,
select: function(start, end) {
var title = "<?=$anim['NOMANIM']?>";
var id = "<?=$anim['CODEANIM']?>";
if (title) {
start = moment(start).format('YYYY-MM-DD HH:mm:ss');
end = moment(end).format('YYYY-MM-DD HH:mm:ss');
$.ajax({
url: '<?php echo base_url("index.php/activite/add_activite"); ?>',
data: 'title='+ title+'&id='+ id+'&start='+ start +'&end='+ end,
type: "POST",
success: function(json) {
alert(start); // THIS SHOWS THE CORRECT DATETIME
}
})
};
$('#calendar').fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
}, true); // stick? = true
$('#calendar').fullCalendar('unselect');
},
events: <?=$events?>
});
});
And here is the controller function:
public function add_activite() {
$title = $_POST['title'];
$id = $_POST['id'];
$datetime_start = strtotime($_POST['start']);
$datetime_end = strtotime($_POST['end']);
$date = date('Y-m-d', $datetime_start);
$start = date('H:m:s', $datetime_start);
$end = date('H:m:s', $datetime_end);
$this->EZ_query->insert_activite($date, $start, $end);
}
If you think there is something I'm doing not correctly beside the time problem, I'm open to any pointers :), Thanks!
Your data formatting in php is not correct, minutes are denoted by i not m (which is used my month already). See here: http://php.net/manual/en/function.date.php
So change:
$start = date('H:i:s', $datetime_start);
$end = date('H:i:s', $datetime_end);

Display date from database using jquery fullcalendar

I'm using the jquery fullcalendar plugin. I can display dynamic dates on a button click. The issue I have now is when loading the dates from the db all the dates populate just one day.
Here is the code with the call to the web service:
$('#calendar').fullCalendar({
header: {
left: 'prev, next today',
center: 'title',
right: 'month, agendaWeek, agendaDay'
},
defaultView: 'month',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
events: 'DAL/WebService1.asmx/GetEvents',
allDay:false
});
Here is the date from that web method
$('#calendar').fullcalendar('renderEvent',event_object,'stick')
This will attach your event to its date on the calendar. The event_object only needs a title and a start date to be valid, but I'd suggest adding an id to make editing/deleting easier.
Render event documentation
Figured out how to get the calendar to render dates separately with this code here. Hopefully helps somebody in the future
var events = [];
$('#calendar').fullCalendar({
events: function (start, end, timezone,callback) {
$.ajax({
url: 'DAL/WebService1.asmx/GetEvents',
dataType: 'json',
success: function (data) {
console.log(data);
var events = [];
$(data).each(function (index, d) {
events.push({
title: d.title,
start: d.startDate
});
});
callback(events);
}
});
}
});

How can i read events from my database table and show them in their respective dates in java script and jquery

i use Full calendar plugin to do this and i have done something but still did not get up to mark.
hear is my scripting code
$('#calendar').fullCalendar({
//theme: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
buttonText: {//This is to add icons to the visible buttons
prev: "<span class='fa fa-caret-left'></span>",
next: "<span class='fa fa-caret-right'></span>",
today: 'today',
month: 'month',
week: 'week',
day: 'day'
},
editable: true,
droppable: true, // this allows things to be dropped onto the calendar
drop: function(date) { // this function is called when something is dropped
// retrieve the dropped element's stored Event Object
var originalEventObject = $(this).data('eventObject');
// we need to copy it, so that multiple events don't have a reference to the same object
var copiedEventObject = $.extend({}, originalEventObject);
// assign it the date that was reported
copiedEventObject.start = date;
copiedEventObject.backgroundColor = $(this).css("background-color");
copiedEventObject.borderColor = $(this).css("border-color");
console.log(copiedEventObject);
// render the event on the calendar
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
// is the "remove after drop" checkbox checked?
/*alert(date + ' was moved ' + allDay + ' days\n' +
'(should probably update your database)');*/
},
//events:"web_master/mycal/ajax_fetch_calendar_data",
events: function(start, end, timezone, callback) {
$.ajax({
url: 'web_master/mycal/ajax_fetch_calendar_data',
dataType: 'json',
type: "POST",
success: function(doc) {
//console.log(doc);
var events = [];
$(doc).find('event').each(function(){
console.log(doc);
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
}
});
},
});
in this i successfully found my doc in events section.
here is the code to fetch events from DB
public function ajax_fetch_calendar_data()
{
try
{
$info = $this->mod_rect->fetch_calendar();
#pr($info);
for($i = 0 ; $i < count($info) ; $i++)
{
$rows[]= array("id"=>$info[$i]['i_id'],
"title"=> $info[$i]['s_title'],
"start"=> $info[$i]['dt_start_date'],
"end"=>$info[$i]['dt_end_date'],
"allDay"=> $info[$i]['s_allDay']);
}
if($rows)
{
echo json_encode($rows);
}
}
catch(Exception $err_obj)
{
show_error($err_obj->getMessage());
}
}
but there is an find(event) function which is didn't found.
Basically what i need to do that
i have some events, those are fetch from DB and i have to drag them on the specific date on the date that comes(upto this done), but i want to store that in Db and fetch them from DB.
I am new to java script and jquery and i didn't know about JSON also.
any help regarding this will helpfull to me.
Thanks.
Well
After few days I have done it myself.
And I think it would be help full to someone So i update my Question
In the Events Section of Fullcalendar for reading multiple events and showing them in your Fullcalendar
events: function(start, end, callback) {
$.ajax({
url: 'web_master/mycal/ajax_fetch_calendar_data',
dataType: 'json',
type: "POST",
success: function(doc) {
var eventObject = [];
for(i=0;i<doc.length;i++)
{
eventObject.push({
id : doc[i].id,
start : doc[i].start,
end : doc[i].end,
title : doc[i].title
//allDay : doc[i].allDay,
//backgroundColor : doc[i].backgroundColor,
//borderColor : doc[i].borderColor
});
}
callback(eventObject);
}
});
},
And i fetch it from my DB in this way
public function ajax_fetch_calendar_data()
{
try
{
$info = $this->mod_rect->fetch_calendar();
echo json_encode($info);
}
catch(Exception $err_obj)
{
show_error($err_obj->getMessage());
}
}

Categories

Resources