--- /dev/null
+/*!
+ * Ext JS Library 3.3.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+/**
+ * @class Ext.calendar.EventEditWindow
+ * @extends Ext.Window
+ * <p>A custom window containing a basic edit form used for quick editing of events.</p>
+ * <p>This window also provides custom events specific to the calendar so that other calendar components can be easily
+ * notified when an event has been edited via this component.</p>
+ * @constructor
+ * @param {Object} config The config object
+ */
+Ext.calendar.EventEditWindow = function(config) {
+ var formPanelCfg = {
+ xtype: 'form',
+ labelWidth: 65,
+ frame: false,
+ bodyStyle: 'background:transparent;padding:5px 10px 10px;',
+ bodyBorder: false,
+ border: false,
+ items: [{
+ id: 'title',
+ name: Ext.calendar.EventMappings.Title.name,
+ fieldLabel: 'Title',
+ xtype: 'textfield',
+ anchor: '100%'
+ },
+ {
+ xtype: 'daterangefield',
+ id: 'date-range',
+ anchor: '100%',
+ fieldLabel: 'When'
+ }]
+ };
+
+ if (config.calendarStore) {
+ this.calendarStore = config.calendarStore;
+ delete config.calendarStore;
+
+ formPanelCfg.items.push({
+ xtype: 'calendarpicker',
+ id: 'calendar',
+ name: 'calendar',
+ anchor: '100%',
+ store: this.calendarStore
+ });
+ }
+
+ Ext.calendar.EventEditWindow.superclass.constructor.call(this, Ext.apply({
+ titleTextAdd: 'Add Event',
+ titleTextEdit: 'Edit Event',
+ width: 600,
+ autocreate: true,
+ border: true,
+ closeAction: 'hide',
+ modal: false,
+ resizable: false,
+ buttonAlign: 'left',
+ savingMessage: 'Saving changes...',
+ deletingMessage: 'Deleting event...',
+
+ fbar: [{
+ xtype: 'tbtext',
+ text: '<a href="#" id="tblink">Edit Details...</a>'
+ },
+ '->', {
+ text: 'Save',
+ disabled: false,
+ handler: this.onSave,
+ scope: this
+ },
+ {
+ id: 'delete-btn',
+ text: 'Delete',
+ disabled: false,
+ handler: this.onDelete,
+ scope: this,
+ hideMode: 'offsets'
+ },
+ {
+ text: 'Cancel',
+ disabled: false,
+ handler: this.onCancel,
+ scope: this
+ }],
+ items: formPanelCfg
+ },
+ config));
+};
+
+Ext.extend(Ext.calendar.EventEditWindow, Ext.Window, {
+ // private
+ newId: 10000,
+
+ // private
+ initComponent: function() {
+ Ext.calendar.EventEditWindow.superclass.initComponent.call(this);
+
+ this.formPanel = this.items.items[0];
+
+ this.addEvents({
+ /**
+ * @event eventadd
+ * Fires after a new event is added
+ * @param {Ext.calendar.EventEditWindow} this
+ * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
+ */
+ eventadd: true,
+ /**
+ * @event eventupdate
+ * Fires after an existing event is updated
+ * @param {Ext.calendar.EventEditWindow} this
+ * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
+ */
+ eventupdate: true,
+ /**
+ * @event eventdelete
+ * Fires after an event is deleted
+ * @param {Ext.calendar.EventEditWindow} this
+ * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was deleted
+ */
+ eventdelete: true,
+ /**
+ * @event eventcancel
+ * Fires after an event add/edit operation is canceled by the user and no store update took place
+ * @param {Ext.calendar.EventEditWindow} this
+ * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
+ */
+ eventcancel: true,
+ /**
+ * @event editdetails
+ * Fires when the user selects the option in this window to continue editing in the detailed edit form
+ * (by default, an instance of {@link Ext.calendar.EventEditForm}. Handling code should hide this window
+ * and transfer the current event record to the appropriate instance of the detailed form by showing it
+ * and calling {@link Ext.calendar.EventEditForm#loadRecord loadRecord}.
+ * @param {Ext.calendar.EventEditWindow} this
+ * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} that is currently being edited
+ */
+ editdetails: true
+ });
+ },
+
+ // private
+ afterRender: function() {
+ Ext.calendar.EventEditWindow.superclass.afterRender.call(this);
+
+ this.el.addClass('ext-cal-event-win');
+
+ Ext.get('tblink').on('click',
+ function(e) {
+ e.stopEvent();
+ this.updateRecord();
+ this.fireEvent('editdetails', this, this.activeRecord);
+ },
+ this);
+ },
+
+ /**
+ * Shows the window, rendering it first if necessary, or activates it and brings it to front if hidden.
+ * @param {Ext.data.Record/Object} o Either a {@link Ext.data.Record} if showing the form
+ * for an existing event in edit mode, or a plain object containing a StartDate property (and
+ * optionally an EndDate property) for showing the form in add mode.
+ * @param {String/Element} animateTarget (optional) The target element or id from which the window should
+ * animate while opening (defaults to null with no animation)
+ * @return {Ext.Window} this
+ */
+ show: function(o, animateTarget) {
+ // Work around the CSS day cell height hack needed for initial render in IE8/strict:
+ var anim = (Ext.isIE8 && Ext.isStrict) ? null: animateTarget;
+
+ Ext.calendar.EventEditWindow.superclass.show.call(this, anim,
+ function() {
+ Ext.getCmp('title').focus(false, 100);
+ });
+ Ext.getCmp('delete-btn')[o.data && o.data[Ext.calendar.EventMappings.EventId.name] ? 'show': 'hide']();
+
+ var rec,
+ f = this.formPanel.form;
+
+ if (o.data) {
+ rec = o;
+ this.isAdd = !!rec.data[Ext.calendar.EventMappings.IsNew.name];
+ if (this.isAdd) {
+ // Enable adding the default record that was passed in
+ // if it's new even if the user makes no changes
+ rec.markDirty();
+ this.setTitle(this.titleTextAdd);
+ }
+ else {
+ this.setTitle(this.titleTextEdit);
+ }
+
+ f.loadRecord(rec);
+ }
+ else {
+ this.isAdd = true;
+ this.setTitle(this.titleTextAdd);
+
+ var M = Ext.calendar.EventMappings,
+ eventId = M.EventId.name,
+ start = o[M.StartDate.name],
+ end = o[M.EndDate.name] || start.add('h', 1);
+
+ rec = new Ext.calendar.EventRecord();
+ rec.data[M.EventId.name] = this.newId++;
+ rec.data[M.StartDate.name] = start;
+ rec.data[M.EndDate.name] = end;
+ rec.data[M.IsAllDay.name] = !!o[M.IsAllDay.name] || start.getDate() != end.clone().add(Date.MILLI, 1).getDate();
+ rec.data[M.IsNew.name] = true;
+
+ f.reset();
+ f.loadRecord(rec);
+ }
+
+ if (this.calendarStore) {
+ Ext.getCmp('calendar').setValue(rec.data[Ext.calendar.EventMappings.CalendarId.name]);
+ }
+ Ext.getCmp('date-range').setValue(rec.data);
+ this.activeRecord = rec;
+
+ return this;
+ },
+
+ // private
+ roundTime: function(dt, incr) {
+ incr = incr || 15;
+ var m = parseInt(dt.getMinutes(), 10);
+ return dt.add('mi', incr - (m % incr));
+ },
+
+ // private
+ onCancel: function() {
+ this.cleanup(true);
+ this.fireEvent('eventcancel', this);
+ },
+
+ // private
+ cleanup: function(hide) {
+ if (this.activeRecord && this.activeRecord.dirty) {
+ this.activeRecord.reject();
+ }
+ delete this.activeRecord;
+
+ if (hide === true) {
+ // Work around the CSS day cell height hack needed for initial render in IE8/strict:
+ //var anim = afterDelete || (Ext.isIE8 && Ext.isStrict) ? null : this.animateTarget;
+ this.hide();
+ }
+ },
+
+ // private
+ updateRecord: function() {
+ var f = this.formPanel.form,
+ dates = Ext.getCmp('date-range').getValue(),
+ M = Ext.calendar.EventMappings;
+
+ f.updateRecord(this.activeRecord);
+ this.activeRecord.set(M.StartDate.name, dates[0]);
+ this.activeRecord.set(M.EndDate.name, dates[1]);
+ this.activeRecord.set(M.IsAllDay.name, dates[2]);
+ this.activeRecord.set(M.CalendarId.name, this.formPanel.form.findField('calendar').getValue());
+ },
+
+ // private
+ onSave: function() {
+ if (!this.formPanel.form.isValid()) {
+ return;
+ }
+ this.updateRecord();
+
+ if (!this.activeRecord.dirty) {
+ this.onCancel();
+ return;
+ }
+
+ this.fireEvent(this.isAdd ? 'eventadd': 'eventupdate', this, this.activeRecord);
+ },
+
+ // private
+ onDelete: function() {
+ this.fireEvent('eventdelete', this, this.activeRecord);
+ }
+});
\ No newline at end of file