2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
|
|
|
|
2011-10-03 16:14:01 +00:00
|
|
|
/*@
|
2012-06-05 08:25:27 +00:00
|
|
|
Ox.CalendarEditor <f> Calendar Editor
|
|
|
|
([options[, self]]) -> <o:Ox.SplitPanel> Calendar Editor
|
2012-05-21 19:23:16 +00:00
|
|
|
options <o> Options
|
|
|
|
self <o> Shared private variable
|
2012-06-17 22:38:26 +00:00
|
|
|
loadlist <!> loadlist
|
2011-10-03 16:14:01 +00:00
|
|
|
@*/
|
2012-04-09 08:42:00 +00:00
|
|
|
|
2012-06-05 08:25:27 +00:00
|
|
|
Ox.CalendarEditor = function(options, self) {
|
2011-10-03 16:14:01 +00:00
|
|
|
|
|
|
|
self = self || {};
|
|
|
|
var that = Ox.Element({}, self)
|
|
|
|
.defaults({
|
2011-10-09 21:13:16 +00:00
|
|
|
addEvent: null,
|
2012-02-20 18:31:45 +00:00
|
|
|
collapsible: false,
|
|
|
|
editEvent: null,
|
2011-10-03 16:37:05 +00:00
|
|
|
events: [],
|
2012-02-20 18:31:45 +00:00
|
|
|
hasMatches: false,
|
2011-10-03 16:14:01 +00:00
|
|
|
height: 256,
|
2012-02-20 18:31:45 +00:00
|
|
|
mode: 'add',
|
2011-10-03 16:14:01 +00:00
|
|
|
pageLength: 100,
|
2012-02-20 18:31:45 +00:00
|
|
|
removeEvent: null,
|
|
|
|
selected: '',
|
2011-10-31 12:45:08 +00:00
|
|
|
showControls: false,
|
2011-10-03 16:37:05 +00:00
|
|
|
sort: [{key: 'name', operator: '+'}],
|
2011-10-03 16:14:01 +00:00
|
|
|
width: 256
|
|
|
|
})
|
|
|
|
.options(options || {})
|
2012-05-28 19:35:41 +00:00
|
|
|
.update({
|
|
|
|
height: function() {
|
|
|
|
// fixme: should be .resizeList
|
|
|
|
self.$list.size();
|
|
|
|
self.$calendar.resizeCalendar();
|
|
|
|
},
|
|
|
|
width: function() {
|
|
|
|
self.$calendar.resizeCalendar();
|
|
|
|
}
|
|
|
|
})
|
2011-10-03 16:14:01 +00:00
|
|
|
.css({
|
|
|
|
width: self.options.width + 'px',
|
|
|
|
height: self.options.height + 'px'
|
|
|
|
});
|
|
|
|
|
2011-10-11 07:05:45 +00:00
|
|
|
self.durationCache = {};
|
2012-02-20 18:31:45 +00:00
|
|
|
self.durationSize = {
|
|
|
|
86400: 10,
|
|
|
|
31622400: 12
|
|
|
|
};
|
2011-10-11 07:05:45 +00:00
|
|
|
|
2011-10-03 16:14:01 +00:00
|
|
|
self.columns = [
|
|
|
|
{
|
2012-02-20 18:31:45 +00:00
|
|
|
format: function(value, data) {
|
|
|
|
var eventDuration = (Ox.parseDate(data.end) - Ox.parseDate(data.start)) / 1000,
|
|
|
|
iconSize = 8;
|
|
|
|
Ox.forEach(self.durationSize, function(size, duration) {
|
2012-03-07 12:02:08 +00:00
|
|
|
if (eventDuration > duration) {
|
2012-02-20 18:31:45 +00:00
|
|
|
iconSize = size;
|
|
|
|
} else {
|
2012-05-25 07:46:34 +00:00
|
|
|
Ox.Break();
|
2012-02-20 18:31:45 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return data.type
|
|
|
|
? $('<div>')
|
|
|
|
.addClass('OxEvent Ox' + Ox.toTitleCase(data.type))
|
|
|
|
.css({
|
|
|
|
width: iconSize + 'px',
|
|
|
|
height: iconSize + 'px',
|
|
|
|
margin: [0, 0, 0, -3].map(function(v) {
|
|
|
|
return v + (14 - iconSize) / 2 + 'px';
|
|
|
|
}).join(' '),
|
|
|
|
borderRadius: '2px'
|
|
|
|
})
|
|
|
|
: '';
|
|
|
|
},
|
|
|
|
id: 'type',
|
|
|
|
operator: '+',
|
|
|
|
title: 'Type',
|
|
|
|
titleImage: 'icon',
|
|
|
|
visible: true,
|
|
|
|
width: 16
|
|
|
|
},
|
|
|
|
{
|
|
|
|
format: function(value, data) {
|
|
|
|
return data.type
|
|
|
|
? value
|
|
|
|
: $('<span>').addClass('OxWarning').html(value);
|
|
|
|
},
|
2011-10-03 16:14:01 +00:00
|
|
|
id: 'name',
|
|
|
|
operator: '+',
|
|
|
|
removable: false,
|
|
|
|
title: 'Name',
|
|
|
|
visible: true,
|
|
|
|
width: 144
|
|
|
|
},
|
|
|
|
{
|
|
|
|
editable: false,
|
|
|
|
format: function(value) {
|
|
|
|
return value.join('; ');
|
|
|
|
},
|
|
|
|
id: 'alternativeNames',
|
|
|
|
operator: '+',
|
|
|
|
title: 'Alternative Names',
|
|
|
|
visible: true,
|
|
|
|
width: 144
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'start',
|
2011-10-10 12:38:54 +00:00
|
|
|
map: function(value) {
|
|
|
|
return Ox.parseDate(value);
|
|
|
|
},
|
2011-10-03 16:14:01 +00:00
|
|
|
operator: '-',
|
|
|
|
title: 'Start',
|
|
|
|
visible: true,
|
|
|
|
width: 144
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'end',
|
2011-10-10 12:38:54 +00:00
|
|
|
map: function(value) {
|
|
|
|
return Ox.parseDate(value);
|
|
|
|
},
|
2011-10-03 16:14:01 +00:00
|
|
|
operator: '-',
|
|
|
|
title: 'End',
|
|
|
|
visible: true,
|
|
|
|
width: 144
|
|
|
|
},
|
|
|
|
{
|
2011-10-10 12:38:54 +00:00
|
|
|
format: function(value, data) {
|
2011-10-11 07:05:45 +00:00
|
|
|
var key = data.start + ' - ' + data.end;
|
|
|
|
if (!self.durationCache[key]) {
|
2012-02-02 02:32:41 +00:00
|
|
|
self.durationCache[key] = data.start
|
|
|
|
? Ox.formatDateRangeDuration(data.start, data.end, true)
|
|
|
|
: '';
|
2011-10-11 07:05:45 +00:00
|
|
|
}
|
2011-11-03 15:42:41 +00:00
|
|
|
return self.durationCache[key];
|
2011-10-10 12:38:54 +00:00
|
|
|
},
|
|
|
|
id: 'id',
|
|
|
|
map: function(value, data) {
|
|
|
|
return Ox.parseDate(data.end) - Ox.parseDate(data.start);
|
|
|
|
},
|
2011-10-03 16:14:01 +00:00
|
|
|
operator: '-',
|
|
|
|
title: 'Duration',
|
2011-10-10 12:38:54 +00:00
|
|
|
unique: true,
|
2011-10-03 16:14:01 +00:00
|
|
|
visible: true,
|
2011-10-10 12:38:54 +00:00
|
|
|
width: 256
|
2011-10-03 16:14:01 +00:00
|
|
|
},
|
|
|
|
{
|
2012-02-22 10:14:25 +00:00
|
|
|
format: function(value) {
|
|
|
|
return Ox.encodeHTMLEntities(value);
|
|
|
|
},
|
2011-10-03 16:14:01 +00:00
|
|
|
id: 'user',
|
|
|
|
operator: '+',
|
|
|
|
title: 'User',
|
|
|
|
visible: false,
|
|
|
|
width: 96
|
|
|
|
},
|
|
|
|
{
|
|
|
|
format: function(value) {
|
|
|
|
return value.replace('T', ' ').replace('Z', '');
|
|
|
|
},
|
|
|
|
id: 'created',
|
|
|
|
operator: '-',
|
|
|
|
title: 'Date Created',
|
|
|
|
visible: false,
|
2012-05-26 15:48:19 +00:00
|
|
|
width: 128
|
2011-10-03 16:14:01 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
format: function(value) {
|
|
|
|
return value.replace('T', ' ').replace('Z', '');
|
|
|
|
},
|
|
|
|
id: 'modified',
|
|
|
|
operator: '-',
|
|
|
|
title: 'Date Modified',
|
|
|
|
visible: false,
|
2012-05-26 15:48:19 +00:00
|
|
|
width: 128
|
2011-10-03 16:14:01 +00:00
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2012-02-20 18:31:45 +00:00
|
|
|
self.options.hasMatches && self.columns.push({
|
|
|
|
align: 'right',
|
|
|
|
id: 'matches',
|
|
|
|
operator: '-',
|
|
|
|
title: 'Matches',
|
|
|
|
visible: true,
|
2012-05-26 15:48:19 +00:00
|
|
|
width: 64
|
2012-02-20 18:31:45 +00:00
|
|
|
});
|
|
|
|
|
2011-10-03 16:14:01 +00:00
|
|
|
self.$listToolbar = Ox.Bar({
|
|
|
|
size: 24
|
|
|
|
});
|
|
|
|
|
|
|
|
self.$findElement = Ox.FormElementGroup({
|
|
|
|
elements: [
|
|
|
|
self.$findSelect = Ox.Select({
|
|
|
|
items: [
|
|
|
|
{id: 'all', title: 'Find: All'},
|
|
|
|
{id: 'name', title: 'Find: Name'},
|
|
|
|
{id: 'alternativeNames', title: 'Find: Alternative Names'},
|
|
|
|
],
|
|
|
|
overlap: 'right',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
change: function(data) {
|
2011-12-21 15:33:52 +00:00
|
|
|
var key = data.value,
|
2011-10-03 16:14:01 +00:00
|
|
|
value = self.$findInput.value();
|
|
|
|
value && updateList(key, value);
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
self.$findInput = Ox.Input({
|
|
|
|
clear: true,
|
|
|
|
placeholder: 'Find in List',
|
|
|
|
width: 234
|
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
submit: function(data) {
|
|
|
|
var key = self.$findSelect.value(),
|
|
|
|
value = data.value;
|
|
|
|
updateList(key, value);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
]
|
|
|
|
})
|
|
|
|
.css({float: 'right', margin: '4px'})
|
|
|
|
.appendTo(self.$listToolbar);
|
|
|
|
|
2012-06-27 07:41:10 +00:00
|
|
|
self.$list = Ox.TableList({
|
2011-10-03 16:14:01 +00:00
|
|
|
columns: self.columns,
|
|
|
|
columnsRemovable: true,
|
|
|
|
columnsVisible: true,
|
2011-10-10 12:38:54 +00:00
|
|
|
// we have to clone so that when self.options.events changes,
|
|
|
|
// self.$list.options({items: self.options.events}) still
|
|
|
|
// registers as a change
|
|
|
|
items: Ox.clone(self.options.events, true),
|
2012-02-20 18:31:45 +00:00
|
|
|
keys: ['matches'],
|
|
|
|
max: 1,
|
|
|
|
min: 0,
|
2011-10-03 16:14:01 +00:00
|
|
|
pageLength: self.options.pageLength,
|
|
|
|
scrollbarVisible: true,
|
2012-02-20 18:31:45 +00:00
|
|
|
selected: self.options.selected ? [self.options.selected] : [],
|
2011-10-03 16:14:01 +00:00
|
|
|
sort: self.options.sort
|
|
|
|
})
|
|
|
|
.bindEvent({
|
2011-10-10 12:38:54 +00:00
|
|
|
'delete': removeEvent,
|
2011-10-03 16:37:05 +00:00
|
|
|
init: initList, // fixme: won't fire from static list
|
2011-10-03 16:14:01 +00:00
|
|
|
key_0: function() {
|
|
|
|
self.$calendar.panToEvent();
|
|
|
|
},
|
|
|
|
key_equal: function() {
|
|
|
|
self.$calendar.zoom(1);
|
|
|
|
},
|
|
|
|
key_minus: function() {
|
|
|
|
self.$calendar.zoom(-1);
|
|
|
|
},
|
|
|
|
key_shift_0: function() {
|
2012-02-20 18:31:45 +00:00
|
|
|
self.$calendar.zoomToEvent();
|
2011-10-03 16:14:01 +00:00
|
|
|
},
|
|
|
|
load: function() {
|
|
|
|
that.triggerEvent('loadlist');
|
|
|
|
},
|
|
|
|
open: openItem,
|
2012-06-10 11:01:06 +00:00
|
|
|
select: function(data) {
|
|
|
|
selectItem(data);
|
|
|
|
}
|
2011-10-03 16:14:01 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
self.$listStatusbar = Ox.Bar({
|
|
|
|
size: 16
|
|
|
|
});
|
|
|
|
|
|
|
|
self.$status = Ox.Element()
|
|
|
|
.css({paddingTop: '2px', margin: 'auto', fontSize: '9px', textAlign: 'center'})
|
2011-10-03 16:37:05 +00:00
|
|
|
.html(
|
|
|
|
Ox.formatNumber(self.options.events.length) + ' Event' + (
|
|
|
|
self.options.events.length == 1 ? '' : 's'
|
|
|
|
)
|
|
|
|
)
|
2011-10-03 16:14:01 +00:00
|
|
|
.appendTo(self.$listStatusbar);
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$calendar = Ox.Calendar({
|
2012-02-20 18:31:45 +00:00
|
|
|
date: new Date(0),
|
|
|
|
//events: Ox.clone(self.options.events, true),
|
|
|
|
events: self.options.events.filter(function(event) {
|
|
|
|
return !!event.type;
|
|
|
|
}),
|
|
|
|
height: self.options.height,
|
|
|
|
showControls: self.options.showControls,
|
|
|
|
showToolbar: true,
|
|
|
|
showZoombar: true,
|
|
|
|
width: self.options.width - 514,
|
|
|
|
zoom: 4
|
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
resize: function(data) {
|
|
|
|
// triggered by SplitPanel
|
|
|
|
self.$calendar.resizeCalendar();
|
|
|
|
},
|
|
|
|
select: selectEvent
|
|
|
|
});
|
2011-10-03 16:14:01 +00:00
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$eventTitlebar = Ox.Bar({
|
2011-10-03 16:14:01 +00:00
|
|
|
size: 24
|
|
|
|
});
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$eventTitle = $('<div>')
|
|
|
|
.hide()
|
|
|
|
.appendTo(self.$eventTitlebar);
|
|
|
|
self.$eventName = Ox.Label({
|
|
|
|
title: '',
|
|
|
|
width: 228
|
|
|
|
})
|
|
|
|
.css({float: 'left', margin: '4px'})
|
|
|
|
.bindEvent({
|
|
|
|
singleclick: function() {
|
|
|
|
self.$calendar.panToEvent();
|
|
|
|
},
|
|
|
|
doubleclick: function() {
|
|
|
|
self.$calendar.zoomToEvent();
|
|
|
|
}
|
2012-03-18 12:39:11 +00:00
|
|
|
})
|
|
|
|
.appendTo(self.$eventTitle);
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$deselectEventButton = Ox.Button({
|
|
|
|
title: 'close',
|
|
|
|
tooltip: 'Done',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.css({float: 'left', margin: '4px 4px 4px 0'})
|
|
|
|
.bindEvent({
|
|
|
|
click: function() {
|
2012-02-20 18:31:45 +00:00
|
|
|
self.$list.options({selected: []});
|
|
|
|
// FIXME: list doesn't fire select event
|
|
|
|
selectItem({ids: []});
|
2011-10-09 21:13:16 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.appendTo(self.$eventTitle);
|
2011-10-03 16:14:01 +00:00
|
|
|
|
2012-02-20 18:31:45 +00:00
|
|
|
self.$eventData = Ox.Element();
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$eventForm = Ox.Form({
|
|
|
|
items: [
|
|
|
|
self.$nameInput = Ox.Input({
|
|
|
|
id: 'name',
|
|
|
|
label: 'Name',
|
|
|
|
labelWidth: 64,
|
|
|
|
width: 240
|
|
|
|
}),
|
|
|
|
self.$alternativeNamesInput = Ox.ArrayInput({
|
|
|
|
id: 'alternativeNames',
|
|
|
|
label: 'Alternative Names',
|
|
|
|
max: 10,
|
|
|
|
values: [],
|
|
|
|
width: 240
|
|
|
|
}),
|
|
|
|
Ox.Select({
|
|
|
|
id: 'type',
|
|
|
|
items: [
|
|
|
|
{id: 'date', title: 'Date'},
|
|
|
|
{id: 'place', title: 'Place'},
|
|
|
|
{id: 'person', title: 'Person'},
|
|
|
|
{id: 'other', title: 'Other'}
|
|
|
|
],
|
|
|
|
label: 'Type',
|
|
|
|
labelWidth: 64,
|
|
|
|
width: 240
|
|
|
|
}),
|
|
|
|
self.$startInput = Ox.Input({
|
|
|
|
id: 'start',
|
|
|
|
label: 'Start',
|
|
|
|
labelWidth: 64,
|
|
|
|
width: 240
|
|
|
|
}),
|
|
|
|
self.$endInput = Ox.Input({
|
|
|
|
id: 'end',
|
|
|
|
label: 'End',
|
|
|
|
labelWidth: 64,
|
|
|
|
width: 240
|
|
|
|
}),
|
|
|
|
self.$durationInput = Ox.Input({
|
|
|
|
disabled: true,
|
2012-04-19 06:44:17 +00:00
|
|
|
id: 'durationText',
|
2011-10-09 21:13:16 +00:00
|
|
|
label: 'Duration',
|
|
|
|
labelWidth: 64,
|
|
|
|
width: 240
|
|
|
|
})
|
|
|
|
],
|
2011-10-03 16:14:01 +00:00
|
|
|
width: 240
|
|
|
|
})
|
|
|
|
.css({margin: '8px'})
|
2011-10-09 21:13:16 +00:00
|
|
|
.hide()
|
|
|
|
.bindEvent({
|
|
|
|
change: function(data) {
|
2012-01-13 16:25:47 +00:00
|
|
|
var exists = false, values;
|
2011-10-09 21:13:16 +00:00
|
|
|
if (['name', 'alternativeNames'].indexOf(data.id) > -1) {
|
|
|
|
exists = '';
|
|
|
|
values = data.id == 'name' ? [data.data.value] : data.data.value;
|
|
|
|
Ox.forEach(self.options.events, function(event) {
|
|
|
|
Ox.forEach(values, function(value) {
|
2012-06-13 08:00:02 +00:00
|
|
|
if (event.type && (
|
|
|
|
event.name == data.data.value
|
|
|
|
|| event.alternativeNames.indexOf(data.data.value) > -1
|
|
|
|
)) {
|
2011-10-09 21:13:16 +00:00
|
|
|
exists = value;
|
2012-05-25 07:46:34 +00:00
|
|
|
Ox.Break();
|
2011-10-09 21:13:16 +00:00
|
|
|
}
|
|
|
|
});
|
2012-05-25 07:46:34 +00:00
|
|
|
exists && Ox.Break();
|
2011-10-09 21:13:16 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
if (data.id == 'name') {
|
|
|
|
if (!exists) {
|
|
|
|
// FIXME: can we change this to data.value?
|
|
|
|
editEvent('name', data.data.value);
|
|
|
|
} else {
|
|
|
|
self.$nameInput.addClass('OxError');
|
|
|
|
}
|
|
|
|
} else if (data.id == 'alternativeNames') {
|
|
|
|
if (!exists) {
|
|
|
|
editEvent('alternativeNames', data.data.value);
|
|
|
|
} else {
|
|
|
|
self.$alternativeNamesInput.setErrors([exists]);
|
|
|
|
}
|
|
|
|
} else if (data.id == 'type') {
|
2011-12-21 15:33:52 +00:00
|
|
|
editEvent('type', data.data.value);
|
2011-10-09 21:13:16 +00:00
|
|
|
} else if (data.id == 'start') {
|
|
|
|
editEvent('start', data.data.value);
|
|
|
|
} else if (data.id == 'end') {
|
|
|
|
editEvent('end', data.data.value);
|
|
|
|
}
|
|
|
|
}
|
2012-02-20 18:31:45 +00:00
|
|
|
})
|
|
|
|
.appendTo(self.$eventData);
|
|
|
|
|
|
|
|
if (self.options.hasMatches) {
|
|
|
|
self.$matchesInput = Ox.Input({
|
|
|
|
disabled: true,
|
|
|
|
id: 'matches',
|
|
|
|
label: 'Matches',
|
|
|
|
labelWidth: 64,
|
|
|
|
type: 'int',
|
|
|
|
width: 240
|
|
|
|
})
|
|
|
|
.css({margin: '8px'})
|
2012-04-19 05:48:31 +00:00
|
|
|
.hide()
|
2012-02-20 18:31:45 +00:00
|
|
|
.appendTo(self.$eventData);
|
|
|
|
}
|
2011-10-03 16:14:01 +00:00
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$eventStatusbar = Ox.Bar({
|
2011-10-03 16:14:01 +00:00
|
|
|
size: 24
|
|
|
|
});
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$newEventButton = Ox.Button({
|
|
|
|
title: 'New Event',
|
2012-02-20 18:31:45 +00:00
|
|
|
width: 70
|
2011-10-09 21:13:16 +00:00
|
|
|
})
|
2012-02-20 18:31:45 +00:00
|
|
|
.css({float: 'left', margin: '4px'})
|
2011-10-09 21:13:16 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: addEvent
|
|
|
|
})
|
|
|
|
.appendTo(self.$eventStatusbar);
|
|
|
|
|
|
|
|
self.$removeEventButton = Ox.Button({
|
|
|
|
title: 'Remove Event',
|
2012-02-20 18:31:45 +00:00
|
|
|
width: 90
|
2011-10-09 21:13:16 +00:00
|
|
|
})
|
2012-02-20 18:31:45 +00:00
|
|
|
.css({float: 'right', margin: '4px'})
|
2011-10-09 21:13:16 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: removeEvent
|
|
|
|
})
|
|
|
|
.hide()
|
|
|
|
.appendTo(self.$eventStatusbar);
|
|
|
|
|
2012-02-20 18:31:45 +00:00
|
|
|
if (self.options.mode == 'define') {
|
|
|
|
self.$defineEventButton = Ox.Button({
|
|
|
|
title: 'Define Event',
|
|
|
|
width: 80
|
|
|
|
})
|
|
|
|
.css({float: 'right', margin: '4px 0 4px 0'})
|
|
|
|
.bindEvent({
|
|
|
|
click: function() {
|
|
|
|
if (this.options('title') == 'Define Event') {
|
|
|
|
defineEvent();
|
|
|
|
} else {
|
|
|
|
clearEvent();
|
2011-10-09 21:13:16 +00:00
|
|
|
}
|
2012-02-20 18:31:45 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.hide()
|
|
|
|
.appendTo(self.$eventStatusbar);
|
|
|
|
}
|
|
|
|
|
2012-04-19 05:48:31 +00:00
|
|
|
that.setElement(
|
|
|
|
Ox.SplitPanel({
|
2012-02-20 18:31:45 +00:00
|
|
|
elements: [
|
|
|
|
{
|
|
|
|
collapsible: self.options.collapsible,
|
|
|
|
element: Ox.SplitPanel({
|
|
|
|
elements: [
|
|
|
|
{
|
|
|
|
element: self.$listToolbar,
|
|
|
|
size: 24
|
|
|
|
},
|
|
|
|
{
|
|
|
|
element: self.$list
|
|
|
|
},
|
|
|
|
{
|
|
|
|
element: self.$listStatusbar,
|
|
|
|
size: 16
|
|
|
|
}
|
|
|
|
],
|
|
|
|
orientation: 'vertical'
|
|
|
|
}),
|
|
|
|
resizable: true,
|
|
|
|
resize: [256, 384, 512],
|
|
|
|
size: 256
|
|
|
|
},
|
|
|
|
{
|
2012-05-26 15:48:19 +00:00
|
|
|
element: self.$calendar
|
2012-02-20 18:31:45 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
collapsible: self.options.collapsible,
|
|
|
|
element: Ox.SplitPanel({
|
|
|
|
elements: [
|
|
|
|
{
|
|
|
|
element: self.$eventTitlebar,
|
|
|
|
size: 24
|
|
|
|
},
|
|
|
|
{
|
|
|
|
element: self.$eventData
|
|
|
|
},
|
|
|
|
{
|
|
|
|
element: self.$eventStatusbar,
|
|
|
|
size: 24
|
|
|
|
}
|
|
|
|
],
|
|
|
|
orientation: 'vertical'
|
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
resize: function(data) {
|
|
|
|
self.$eventTitleName.options({width: data.size - 48});
|
|
|
|
// fixme: pass width through form
|
|
|
|
/*
|
|
|
|
self.$eventFormItems.forEach(function($item) {
|
|
|
|
$item.options({width: data.size - 16});
|
|
|
|
});
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
resizable: true,
|
|
|
|
resize: [256, 384],
|
|
|
|
size: 256
|
|
|
|
}
|
|
|
|
],
|
|
|
|
orientation: 'horizontal'
|
|
|
|
})
|
2012-06-05 08:25:27 +00:00
|
|
|
.addClass('OxCalendarEditor')
|
2012-02-20 18:31:45 +00:00
|
|
|
);
|
2011-10-03 16:14:01 +00:00
|
|
|
|
2012-02-21 11:20:03 +00:00
|
|
|
// if loaded with selection, set calendar and form
|
|
|
|
self.options.selected && self.$list.triggerEvent({
|
|
|
|
select: {ids: [self.options.selected]}
|
|
|
|
});
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
function addEvent() {
|
2011-11-04 15:54:28 +00:00
|
|
|
Ox.Log('Calendar', 'ADD', self.$calendar.getBounds())
|
2011-10-09 21:13:16 +00:00
|
|
|
var bounds = self.$calendar.getBounds(),
|
|
|
|
middle = +self.$calendar.options('date'),
|
2011-10-10 12:38:54 +00:00
|
|
|
startTime = +new Date((+bounds.startTime + middle) / 2),
|
|
|
|
endTime = +new Date((+bounds.endTime + middle) / 2),
|
2011-10-09 21:13:16 +00:00
|
|
|
event = {},
|
|
|
|
i = 1;
|
|
|
|
event.name = 'Untitled';
|
|
|
|
while (nameExists(event.name)) {
|
|
|
|
event.name = 'Untitled [' + (++i) + ']';
|
|
|
|
};
|
|
|
|
event.alternativeNames = [];
|
|
|
|
event.type = 'other';
|
2011-10-10 12:38:54 +00:00
|
|
|
event.start = Ox.formatDate(startTime, '%Y-%m-%d %H:%M:%S', true);
|
|
|
|
event.end = Ox.formatDate(endTime, '%Y-%m-%d %H:%M:%S', true);
|
2011-11-04 15:54:28 +00:00
|
|
|
Ox.Log('Calendar', event);
|
2012-06-10 11:01:06 +00:00
|
|
|
self.$newEventButton.options({disabled: true});
|
|
|
|
self.$removeEventButton.options({disabled: true});
|
2012-02-21 12:33:27 +00:00
|
|
|
self.options.addEvent(encodeValues(event), function(result) {
|
2011-10-11 09:48:24 +00:00
|
|
|
if (result.status.code == '200') {
|
|
|
|
event.id = result.data.id;
|
2012-06-10 11:01:06 +00:00
|
|
|
if (self.options.hasMatches) {
|
|
|
|
event.matches = result.data.matches;
|
|
|
|
}
|
2011-10-11 09:48:24 +00:00
|
|
|
self.options.events.push(event);
|
2012-06-10 11:01:06 +00:00
|
|
|
// var time0 = +new Date()
|
2011-10-11 09:48:24 +00:00
|
|
|
self.$list.options({items: Ox.clone(self.options.events, true)});
|
2012-06-10 11:01:06 +00:00
|
|
|
// Ox.Log('Calendar', 'TIME TO SET LIST OPTIONS:', +new Date() - time0);
|
2011-10-11 09:48:24 +00:00
|
|
|
self.$calendar.addEvent(event);
|
|
|
|
selectEvent(event);
|
2011-12-18 09:44:11 +00:00
|
|
|
self.$nameInput.focusInput(true);
|
2012-06-10 11:01:06 +00:00
|
|
|
self.$newEventButton.options({disabled: false});
|
|
|
|
self.$removeEventButton.options({disabled: false});
|
2011-10-11 09:48:24 +00:00
|
|
|
} else {
|
2012-02-02 02:32:41 +00:00
|
|
|
// FIXME
|
2012-02-20 18:31:45 +00:00
|
|
|
// alert(result.status.text);
|
2011-10-11 09:48:24 +00:00
|
|
|
}
|
2011-10-09 21:13:16 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-02-20 18:31:45 +00:00
|
|
|
function clearEvent() {
|
|
|
|
var event = Ox.getObjectById(self.options.events, self.options.selected),
|
|
|
|
values = {
|
|
|
|
id: self.options.selected,
|
|
|
|
alternativeNames: [], type: '',
|
|
|
|
start: '', end: ''
|
|
|
|
};
|
|
|
|
self.$defineEventButton.options({disabled: true, title: 'Clear Event'});
|
2012-02-21 12:33:27 +00:00
|
|
|
self.options.editEvent(encodeValues(values), function() {
|
2012-02-20 18:31:45 +00:00
|
|
|
Ox.forEach(values, function(value, key) {
|
|
|
|
self.$list.value(self.options.selected, key, value);
|
|
|
|
});
|
|
|
|
self.$list.reloadList();
|
|
|
|
self.$calendar.removeEvent();
|
|
|
|
self.$eventForm.hide();
|
|
|
|
self.$defineEventButton.options({disabled: false, title: 'Define Event'});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-02-21 12:33:27 +00:00
|
|
|
function decodeValues(place) {
|
|
|
|
return Ox.map(place, function(value) {
|
2012-06-02 14:59:08 +00:00
|
|
|
var type = Ox.typeOf(value);
|
|
|
|
return type == 'string' ? Ox.decodeHTMLEntities(value)
|
|
|
|
: type == 'array' ? Ox.map(value, function(value) {
|
|
|
|
return decodeValues(value);
|
2012-02-21 12:33:27 +00:00
|
|
|
})
|
|
|
|
: value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-02-20 18:31:45 +00:00
|
|
|
function defineEvent() {
|
|
|
|
var bounds = self.$calendar.getBounds(),
|
|
|
|
middle = +self.$calendar.options('date'),
|
|
|
|
startTime = +new Date((+bounds.startTime + middle) / 2),
|
|
|
|
endTime = +new Date((+bounds.endTime + middle) / 2),
|
|
|
|
event = Ox.getObjectById(self.options.events, self.options.selected);
|
|
|
|
event.name = self.$list.value(self.options.selected, 'name');
|
|
|
|
event.alternativeNames = [];
|
|
|
|
event.type = 'other';
|
|
|
|
event.start = Ox.formatDate(startTime, '%Y-%m-%d %H:%M:%S', true);
|
|
|
|
event.end = Ox.formatDate(endTime, '%Y-%m-%d %H:%M:%S', true);
|
|
|
|
self.$list.options({items: Ox.clone(self.options.events, true)});
|
|
|
|
self.$calendar.addEvent(event);
|
|
|
|
self.$defineEventButton.options({title: 'Clear Event'});
|
|
|
|
}
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
function editEvent(key, value) {
|
2011-10-10 12:38:54 +00:00
|
|
|
var id = self.selectedEvent,
|
2012-01-04 08:11:05 +00:00
|
|
|
index = Ox.getIndexById(self.options.events, id),
|
2011-10-10 12:38:54 +00:00
|
|
|
data = {id: id};
|
2011-10-11 09:48:24 +00:00
|
|
|
data[key] = value;
|
2012-02-21 12:33:27 +00:00
|
|
|
self.options.editEvent(encodeValues(data), function(result) {
|
2011-10-11 11:22:16 +00:00
|
|
|
if (result.status.code == 200) {
|
|
|
|
self.options.events[index][key] = value;
|
2012-06-13 08:00:02 +00:00
|
|
|
if (self.options.hasMatches) {
|
|
|
|
self.options.events[index].matches = result.data.matches;
|
|
|
|
}
|
|
|
|
self.$list.options({items: Ox.clone(self.options.events, true)});
|
2012-01-30 23:27:27 +00:00
|
|
|
self.$calendar.editEvent(id, key, value);
|
2011-10-11 11:22:16 +00:00
|
|
|
if (key == 'name') {
|
|
|
|
self.$eventName.options({title: value});
|
|
|
|
} else if (['start', 'end'].indexOf(key) > -1) {
|
2011-12-21 15:33:52 +00:00
|
|
|
self.$durationInput.value(
|
|
|
|
Ox.formatDateRangeDuration(
|
|
|
|
self.$startInput.value(),
|
|
|
|
self.$endInput.value()
|
2011-10-11 11:22:16 +00:00
|
|
|
|| Ox.formatDate(new Date(), '%Y-%m-%d %H%:%M:%S'),
|
|
|
|
true
|
|
|
|
)
|
2011-12-21 15:33:52 +00:00
|
|
|
);
|
2011-10-11 11:22:16 +00:00
|
|
|
}
|
2012-06-13 08:00:02 +00:00
|
|
|
self.options.hasMatches && self.$matchesInput.value(result.data.matches);
|
2012-02-20 18:31:45 +00:00
|
|
|
self.options.mode == 'define' && self.$removeEventButton.options({
|
|
|
|
disabled: !!result.data.matches
|
|
|
|
});
|
2011-10-11 11:22:16 +00:00
|
|
|
} else {
|
2012-01-30 23:27:27 +00:00
|
|
|
// ...
|
2011-10-11 07:05:45 +00:00
|
|
|
}
|
2011-10-09 21:13:16 +00:00
|
|
|
});
|
|
|
|
}
|
2011-10-03 16:14:01 +00:00
|
|
|
|
2012-06-13 08:00:02 +00:00
|
|
|
function encodeValues(place) {
|
|
|
|
return Ox.map(place, function(value) {
|
|
|
|
var type = Ox.typeOf(value);
|
|
|
|
return type == 'string' ? Ox.encodeHTMLEntities(value)
|
|
|
|
: type == 'array' ? Ox.map(value, function(value) {
|
|
|
|
return encodeValues(value);
|
|
|
|
})
|
|
|
|
: value;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-10-03 16:37:05 +00:00
|
|
|
function initList(data) {
|
|
|
|
self.$status.html(
|
|
|
|
Ox.formatNumber(data.items) + ' Event' + (
|
|
|
|
data.items == 1 ? '' : 's'
|
|
|
|
)
|
|
|
|
);
|
2011-10-03 16:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
function nameExists(name) {
|
|
|
|
var exists = false;
|
|
|
|
Ox.forEach(self.options.events, function(event) {
|
|
|
|
if (
|
|
|
|
event.name == name
|
|
|
|
|| event.alternativeNames.indexOf(name) > -1
|
|
|
|
) {
|
|
|
|
exists = true;
|
2012-05-25 07:46:34 +00:00
|
|
|
Ox.Break();
|
2011-10-09 21:13:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return exists;
|
2011-10-03 16:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
function openItem(data) {
|
|
|
|
selectItem(data);
|
|
|
|
self.$calendar.zoomToEvent(data.ids[0]);
|
2011-10-03 16:37:05 +00:00
|
|
|
}
|
|
|
|
|
2011-10-09 21:13:16 +00:00
|
|
|
function removeEvent() {
|
2011-10-10 12:38:54 +00:00
|
|
|
var id = self.selectedEvent,
|
2012-01-04 08:11:05 +00:00
|
|
|
index = Ox.getIndexById(self.options.events, id);
|
2012-06-10 11:01:06 +00:00
|
|
|
self.$newEventButton.options({disabled: true});
|
|
|
|
self.$removeEventButton.options({disabled: true});
|
2011-10-10 12:38:54 +00:00
|
|
|
self.options.removeEvent({id: id}, function(result) {
|
2011-10-11 11:22:16 +00:00
|
|
|
if (result.status.code == '200') {
|
2012-06-10 11:01:06 +00:00
|
|
|
selectEvent({});
|
2011-10-11 11:22:16 +00:00
|
|
|
self.options.events.splice(index, 1);
|
|
|
|
var time0 = +new Date();
|
|
|
|
self.$list.options({items: Ox.clone(self.options.events, true)});
|
2011-11-04 15:54:28 +00:00
|
|
|
Ox.Log('Calendar', 'TIME TO SET LIST OPTIONS:', +new Date() - time0);
|
2011-10-11 11:22:16 +00:00
|
|
|
self.$calendar.removeEvent();
|
2012-06-10 11:01:06 +00:00
|
|
|
self.$newEventButton.options({disabled: false});
|
|
|
|
self.$removeEventButton.options({disabled: false});
|
2011-10-11 11:22:16 +00:00
|
|
|
} else {
|
2012-02-20 18:31:45 +00:00
|
|
|
// FIXME
|
|
|
|
// alert(result.status.text);
|
2011-10-11 11:22:16 +00:00
|
|
|
}
|
2011-10-09 21:13:16 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function selectEvent(event) {
|
2012-02-20 18:31:45 +00:00
|
|
|
// Select event on calendar
|
|
|
|
var isUndefined = !!self.options.selected
|
|
|
|
&& !self.$list.value(self.options.selected, 'type');
|
|
|
|
self.selectedEvent = event.id || '';
|
2012-04-19 06:44:17 +00:00
|
|
|
if (!self.selectedEvent && isUndefined) {
|
2012-02-20 18:31:45 +00:00
|
|
|
// deselect triggered by selecting an undefined item,
|
|
|
|
// so do nothing
|
|
|
|
} else {
|
|
|
|
self.options.selected = self.selectedEvent;
|
|
|
|
self.$list.options({
|
|
|
|
selected: self.options.selected ? [self.options.selected] : []
|
|
|
|
});
|
2012-04-19 06:44:17 +00:00
|
|
|
selectItem({ids: self.$list.options('selected')}, event);
|
2012-02-20 18:31:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-19 06:44:17 +00:00
|
|
|
function selectItem(data, event) {
|
2012-02-20 18:31:45 +00:00
|
|
|
// Select item in list
|
2012-04-19 06:44:17 +00:00
|
|
|
var fromCalendar = !!event, isUndefined, selectedEvent;
|
2012-02-20 18:31:45 +00:00
|
|
|
self.options.selected = data.ids.length ? data.ids[0] : '';
|
2012-04-19 06:44:17 +00:00
|
|
|
event = event || (
|
|
|
|
self.options.selected
|
|
|
|
? self.$list.value(self.options.selected)
|
|
|
|
: {}
|
2012-06-10 11:01:06 +00:00
|
|
|
);
|
2012-04-19 06:44:17 +00:00
|
|
|
isUndefined = !fromCalendar && !!self.options.selected
|
2012-02-20 18:31:45 +00:00
|
|
|
&& !self.$list.value(self.options.selected, 'type');
|
2012-04-19 06:44:17 +00:00
|
|
|
if (!fromCalendar) {
|
|
|
|
selectedEvent = self.options.selected && !isUndefined
|
|
|
|
? self.options.selected
|
|
|
|
: '';
|
|
|
|
self.$calendar.options({selected: selectedEvent});
|
|
|
|
selectedEvent && self.$calendar.panToEvent();
|
|
|
|
}
|
2012-02-20 18:31:45 +00:00
|
|
|
if (self.options.selected) {
|
|
|
|
self.$eventName.options({title: event.name || ''});
|
2012-04-19 06:44:17 +00:00
|
|
|
self.$eventTitle.show();
|
2012-02-20 18:31:45 +00:00
|
|
|
if (!isUndefined) {
|
2012-02-21 12:33:27 +00:00
|
|
|
self.$eventForm.values(
|
|
|
|
decodeValues(Ox.extend({}, event, {
|
2012-04-19 05:48:31 +00:00
|
|
|
end: event.current ? '' : event.end,
|
2012-04-19 06:44:17 +00:00
|
|
|
durationText: Ox.formatDateRangeDuration(
|
2012-04-19 05:48:31 +00:00
|
|
|
event.start, event.end, true
|
|
|
|
)
|
2012-02-21 12:33:27 +00:00
|
|
|
}))
|
|
|
|
).show();
|
2012-02-20 18:31:45 +00:00
|
|
|
} else {
|
|
|
|
self.$eventForm.hide();
|
|
|
|
}
|
|
|
|
self.options.hasMatches && self.$matchesInput.value(event.matches || 0).show();
|
|
|
|
self.options.mode == 'define' && self.$defineEventButton.options({
|
|
|
|
disabled: !event.matches,
|
|
|
|
title: isUndefined ? 'Define Event' : 'Clear Event'
|
|
|
|
}).show();
|
|
|
|
self.$removeEventButton.options({
|
|
|
|
disabled: self.options.mode == 'define' && !!event.matches
|
|
|
|
}).show();
|
2011-10-09 21:13:16 +00:00
|
|
|
} else {
|
|
|
|
self.$eventTitle.hide();
|
|
|
|
self.$eventForm.hide();
|
2012-02-20 18:31:45 +00:00
|
|
|
self.options.hasMatches && self.$matchesInput.hide();
|
|
|
|
self.options.mode == 'define' && self.$defineEventButton.hide();
|
2011-10-09 21:13:16 +00:00
|
|
|
self.$removeEventButton.hide();
|
|
|
|
}
|
2011-10-03 16:14:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function updateList(key, value) {
|
2011-10-11 09:09:20 +00:00
|
|
|
var events;
|
|
|
|
if (value === '') {
|
|
|
|
events = Ox.clone(self.options.events);
|
|
|
|
} else {
|
|
|
|
events = [];
|
|
|
|
self.options.events.forEach(function(event) {
|
|
|
|
if ((
|
2011-10-03 16:14:01 +00:00
|
|
|
['all', 'name'].indexOf(key) > -1
|
2011-10-11 09:09:20 +00:00
|
|
|
&& event.name.toLowerCase().indexOf(value) > -1
|
|
|
|
) || (
|
2011-10-03 16:14:01 +00:00
|
|
|
['all', 'alternativeNames'].indexOf(key) > -1
|
2011-10-11 09:09:20 +00:00
|
|
|
&& event.alternativeNames.join('\n').toLowerCase().indexOf(value) > -1
|
|
|
|
)) {
|
|
|
|
events.push(event)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
self.$list.options({items: events});
|
2011-10-03 16:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-10-03 16:37:05 +00:00
|
|
|
return that;
|
|
|
|
|
2012-01-13 16:25:47 +00:00
|
|
|
};
|