Skip to content

Commit 07fab6c

Browse files
committed
Implemented event persistence demo using localStorage; Added Delete Event functionality; Fixed time offset typo for dropped events
1 parent 3921684 commit 07fab6c

File tree

6 files changed

+146
-19
lines changed

6 files changed

+146
-19
lines changed

css/test.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,12 @@
3232
.internal {
3333
border-color: #66A;
3434
color: #66A; }
35+
36+
.deleteevent {
37+
float: right;
38+
font-size: 50%;
39+
color: #A00;
40+
border: 1px solid #aa0000;
41+
text-align: center;
42+
padding: 1px 3px;
43+
margin: 2px; }

js/rc_calendar.js

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88
// view-specific settings
99
render : 'view_week',
1010
render_event : 'view_week_render_event',
11-
get_time_offset : function( event, ui ){return ui.offset.top - event.target.offsetTop;},
11+
get_time_offset : function( evt, ui ){return ui.offset.top - evt.target.offsetTop;},
12+
13+
// persistent event storage accessor functions
14+
// (override with application functions in rc_calendar constructor call)
15+
persist : function( evt ){},
16+
retrieve : function(){ return [] },
17+
remove : function(){},
1218

1319
min_time : '07:00', // 7am
1420
max_time : '20:00', // 8pm
@@ -55,6 +61,7 @@
5561
var calendar = new Calendar( element, options );
5662
element.data('rc_Calendar', calendar);
5763
calendar.render(1375293414903);
64+
calendar.initialize_events();
5865
});
5966

6067
return this;
@@ -107,7 +114,13 @@ function Calendar( element, options )
107114
t.resources[$(this).attr('id')] = new Resource($(this),'localtest');
108115
});
109116

110-
t.eventmanager = new rc_EventManager();
117+
t.initialize_events = function(){
118+
t.eventmanager = new rc_EventManager( t.options.retrieve,
119+
t.options.persist,
120+
t.options.remove,
121+
t.resources,
122+
t[t.options.render_event] );
123+
}
111124

112125

113126
//--- Public Methods ---
@@ -151,8 +164,7 @@ function Calendar( element, options )
151164

152165
// [TODO - abstract user-added attributes]
153166
capacity : 10
154-
},
155-
t[t.options.render_event]
167+
}
156168
);
157169
}
158170
else
@@ -168,8 +180,7 @@ function Calendar( element, options )
168180
{
169181
start : start_time,
170182
date : date,
171-
},
172-
t[t.options.render_event]
183+
}
173184
) ) {
174185
// was able to render in the new position, delete the original
175186
dragged.remove();
@@ -216,6 +227,12 @@ function Calendar( element, options )
216227

217228
$('#'+evt.attr.parent).append( newev );
218229

230+
newev.find('.deleteevent').click(function(event){
231+
event.stopPropagation();
232+
confirm( "You are about to delete this event; this action can not be undone! Confirm deletion?",
233+
t.eventmanager.deleteEvent, evt.attr.id );
234+
});
235+
219236
newev.draggable({
220237
appendTo : 'body',
221238
helper : 'clone',
@@ -363,13 +380,29 @@ function rc_Event( options )
363380
// Manages updates to/from the server
364381
//
365382

366-
function rc_EventManager( )
383+
function rc_EventManager( retrieve_events, save_event, delete_event, resources, display )
367384
{
368-
var to_write = [];
385+
var render = display;
386+
var persistEvent= save_event;
387+
var killEvent = delete_event;
388+
var to_write = []; // [NOTE] - this may disappear, it is for async writes to a server
369389
var t = this;
370-
t.Events = [];
371390

372-
t.createEvent = function( parent, resource, options, render ) {
391+
t.Events = retrieve_events();
392+
393+
for( var i in t.Events ) {
394+
var evt = t.Events[i];
395+
if( undefined != resources[evt.attr.resource] ) {
396+
resources[evt.attr.resource].addEvent( evt );
397+
render( evt );
398+
}
399+
else {
400+
// [TODO] - remove from list??
401+
}
402+
403+
}
404+
405+
t.createEvent = function( parent, resource, options ) {
373406
var new_event = new rc_Event( options );
374407
var id = new_event.attr.id;
375408

@@ -380,12 +413,13 @@ function rc_EventManager( )
380413
new_event.attr.resource = resource.id;
381414
new_event.attr.parent = parent.attr('id'); // div in which this event currently resides
382415
render( new_event );
416+
persistEvent( new_event );
383417
}
384418

385419
return new_event;
386420
}
387421

388-
t.moveEvent = function( evt, parent, old_resource, new_resource, options, render) {
422+
t.moveEvent = function( evt, parent, old_resource, new_resource, options ) {
389423
to_write[evt.attr.id] = true;
390424

391425
// have to update event attributes before attempting to move the event,
@@ -410,6 +444,7 @@ function rc_EventManager( )
410444
evt.attr.resource = new_resource.id;
411445
evt.attr.parent = parent.attr('id');
412446
render( evt );
447+
persistEvent( evt );
413448
return true;
414449
}
415450
else {
@@ -418,6 +453,12 @@ function rc_EventManager( )
418453
}
419454
}
420455

456+
t.deleteEvent = function( id ){
457+
t.Events[ id ] = undefined;
458+
$('#'+id).remove();
459+
killEvent( id );
460+
}
461+
421462
return t;
422463
}
423464

@@ -443,11 +484,7 @@ var init_resource = {
443484
Room2:{title:"Narwhal",capacity:50,location:"Rochester North"},
444485
Room3:{title:"Walrus",capacity:500,location:"Rochester East"},
445486
};
446-
var init_resource_events = {
447-
Room1:[0,1,2,3],
448-
Room2:[4,5,6,7],
449-
Room3:[8,9,10,11]
450-
}
487+
451488
//--- END TEST DATA ---------------------------------------------------
452489

453490

js/rc_utilities.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,35 @@ function convert_to_time( t, ampm )
209209
return hours + ':' + mins;
210210
}
211211

212+
213+
//
214+
// Unfortunately, Pines Notify does not have a "confirm" function, which would be nice for consistency
215+
// Using a jquery ui dialog, code lifted/adapted from here:
216+
// http://www.vrusso.com.br/blog/2011/03/unobtrusive-confirm-javascript-replacement-with-jquery-ui-dialog/
217+
//
218+
function confirm(message, callback, param) {
219+
$('body').append('<div id="confirm" style="display:none">'+message+'</div>'); // dont forget to hide this!
220+
$( "#confirm" ).dialog({
221+
resizable: false,
222+
title: 'Please Confirm',
223+
modal: true,
224+
buttons: [
225+
{
226+
text: "Yes",
227+
click: function() {
228+
$(this).dialog("close");
229+
if ($.isFunction(callback)) {
230+
callback( param );
231+
}
232+
233+
}
234+
},{
235+
text: "No",
236+
click: function() { $(this).dialog("close");}
237+
}
238+
],
239+
close: function(event, ui) {
240+
$('#confirm').remove();
241+
}
242+
});
243+
}

sass/test.scss

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,15 @@
3737

3838
.internal {
3939
border-color:#66A;
40-
color:#66A;
40+
color:#66A;
4141
}
42+
43+
.deleteevent{
44+
float:right;
45+
font-size:50%;
46+
color: #A00;
47+
border:1px solid #A00;
48+
text-align:center;
49+
padding:1px 3px;
50+
margin:2px;
51+
}

templates/week.template.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
return this.toString().replace(/.*\/\*\n([\s\S]*)\n\*\/.*/m, "$1");
44
};
55

6+
7+
// [TODO] Add support for per-day opening/closing times
8+
69
//
710
// Template for a calendar for a single resource
811
//
@@ -64,7 +67,7 @@ var render_week_event = doT.template((function(){/*
6467
style="top:{{=it.attr.t_offset}}px;height:{{=it.attr.t_height}}px;"
6568
id="{{=it.attr.id}}">
6669
<div class="rc_event_prepad" style="height:{{=it.attr.t_prepad}}px;"></div>
67-
<div class="rc_event_head">{{=it.attr.start}} - {{=it.attr.end}}</div>
70+
<div class="rc_event_head">{{=it.attr.start}} - {{=it.attr.end}}<div class='deleteevent'>X</div></div>
6871
<div class="rc_event_body">{{=it.attr.ev_text}}</div>
6972
<div class="rc_event_postpad" style="height:{{=it.attr.t_postpad}}px;"></div>
7073
</div>

test.html

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,45 @@ <h3>Resource Calendar</h3>
125125
return false;
126126
}
127127

128+
//
129+
// Example functions for making events persistent
130+
// This example uses HTML5 localstorage; a 'real' system would be
131+
// Ajaxed. Even better... Ajax + localstorage with localstorage change
132+
// listeners to allow offline working and sync-on-connect.
133+
//
134+
function saveEvent( evt )
135+
{
136+
localStorage.setItem( evt.attr.id, JSON.stringify(evt) );
137+
}
138+
139+
function loadEvents( )
140+
{
141+
// this function should be written as a generator.. when yield is universally available
142+
var records = {};
143+
144+
for( var i=0; i<=localStorage.length-1; i++ )
145+
{
146+
var key = localStorage.key(i);
147+
var val = JSON.parse(localStorage.getItem(key));
148+
149+
records[key] = val ;
150+
}
151+
152+
return records;
153+
}
154+
155+
function removeEvent( id )
156+
{
157+
localStorage.removeItem( id );
158+
}
159+
128160

129161
$(document).ready(function() {
130-
$('.calendar').rc_calendar();
162+
$('.calendar').rc_calendar({
163+
persist: saveEvent,
164+
retrieve: loadEvents,
165+
remove: removeEvent
166+
});
131167
$('.calendar').rc_calendar( 'external_events_init', $('.in_palette') );
132168
});
133169

0 commit comments

Comments
 (0)