/** * @class Ext.ensible.cal.CalendarList * @extends Ext.Panel *

This is a {@link Ext.Panel panel} subclass that renders a list of available calendars * @constructor * @param {Object} config The config object * @xtype calendarpanel */ Ext.ensible.cal.CalendarList = Ext.extend(Ext.Panel, { title: 'Calendars', collapsible: true, autoHeight: true, layout: 'fit', menuSelector: 'em', width: 100, // this should be overridden by this container's layout

/** * @cfg {Ext.data.Store} store * A {@link Ext.data.Store store} containing records of type {@link Ext.ensible.cal.CalendarRecord CalendarRecord}. * This is a required config and is used to populate the calendar list. The CalendarList widget will also listen for events from * the store and automatically refresh iteself in the event that the underlying calendar records in the store change. */ // private initComponent: function(){ this.addClass('x-calendar-list'); Ext.ensible.cal.CalendarList.superclass.initComponent.call(this); }, // private afterRender : function(ct, position){ Ext.ensible.cal.CalendarList.superclass.afterRender.call(this); if(this.store){ this.setStore(this.store, true); } this.refresh(); this.body.on('click', this.onClick, this); this.body.on('mouseover', this.onMouseOver, this, {delegate: 'li'}); this.body.on('mouseout', this.onMouseOut, this, {delegate: 'li'}); }, // private getListTemplate : function(){ if(!this.tpl){ this.tpl = !(Ext.isIE || Ext.isOpera) ? new Ext.XTemplate( '' ) : new Ext.XTemplate( '' ); this.tpl.compile(); } return this.tpl; },
/** * Sets the store used to display the available calendars. It should contain * records of type {@link Ext.ensible.cal.CalendarRecord CalendarRecord}. * @param {Ext.data.Store} store */ setStore : function(store, initial){ if(!initial && this.store){ this.store.un("load", this.refresh, this); this.store.un("add", this.refresh, this); this.store.un("remove", this.refresh, this); this.store.un("update", this.onUpdate, this); this.store.un("clear", this.refresh, this); } if(store){ store.on("load", this.refresh, this); store.on("add", this.refresh, this); store.on("remove", this.refresh, this); store.on("update", this.onUpdate, this); store.on("clear", this.refresh, this); } this.store = store; }, // private onUpdate : function(ds, rec, operation){ // ignore EDIT notifications, only refresh after a commit if(operation == Ext.data.Record.COMMIT){ this.refresh(); } },
/** * Refreshes the calendar list so that it displays based on the most current state of * the underlying calendar store. Usually this method does not need to be called directly * as the control is automatically bound to the store's events, but it is available in the * event that a manual refresh is ever needed. */ refresh: function(){ if(this.skipRefresh){ return; } var data = [], i = 0, o = null, CM = Ext.ensible.cal.CalendarMappings, recs = this.store.getRange(), len = recs.length; for(; i < len; i++){ o = { cmpId: this.id + '__' + recs[i].data[CM.CalendarId.name], title: recs[i].data[CM.Title.name], colorCls: this.getColorCls(recs[i].data[CM.ColorId.name]) }; if(recs[i].data[CM.IsHidden.name] === true){ o.hiddenCls = 'ext-cal-hidden'; } data[data.length] = o; } this.getListTemplate().overwrite(this.body, data); }, // private getColorCls: function(colorId){ return 'x-cal-'+colorId+'-ad'; }, // private toggleCalendar: function(id, commit){ var rec = this.store.getById(id), CM = Ext.ensible.cal.CalendarMappings, isHidden = rec.data[CM.IsHidden.name]; rec.set([CM.IsHidden.name], !isHidden); if(commit !== false){ rec.commit(); } }, // private showCalendar: function(id, commit){ var rec = this.store.getById(id); if(rec.data[Ext.ensible.cal.CalendarMappings.IsHidden.name] === true){ this.toggleCalendar(id, commit); } }, // private hideCalendar: function(id, commit){ var rec = this.store.getById(id); if(rec.data[Ext.ensible.cal.CalendarMappings.IsHidden.name] !== true){ this.toggleCalendar(id, commit); } }, // private radioCalendar: function(id){ var i = 0, recId, calendarId = Ext.ensible.cal.CalendarMappings.CalendarId.name, recs = this.store.getRange(), len = recs.length; for(; i < len; i++){ recId = recs[i].data[calendarId]; // make a truthy check so that either numeric or string ids can match if(recId == id){ this.showCalendar(recId, false); } else{ this.hideCalendar(recId, false); } } // store.commitChanges() just loops over each modified record and calls rec.commit(), // which in turns fires an update event that would cause a full refresh for each record. // To avoid this we simply set a flag and make sure we only refresh once per commit set. this.skipRefresh = true; this.store.commitChanges(); delete this.skipRefresh; this.refresh(); }, // private onMouseOver: function(e, t){ Ext.fly(t).addClass('hover'); }, // private onMouseOut: function(e, t){ Ext.fly(t).removeClass('hover'); }, // private getCalendarId: function(el){ return el.id.split('__')[1]; }, // private getCalendarItemEl: function(calendarId){ return Ext.get(this.id+'__'+calendarId); }, // private onClick : function(e, t){ var el; if(el = e.getTarget(this.menuSelector, 3, true)){ this.showEventMenu(el, e.getXY()); } else if(el = e.getTarget('li', 3, true)){ this.toggleCalendar(this.getCalendarId(el)); } }, // private handleColorChange: function(menu, id, colorId, origColorId){ var rec = this.store.getById(id); rec.data[Ext.ensible.cal.CalendarMappings.ColorId.name] = colorId; rec.commit(); }, // private handleRadioCalendar: function(menu, id){ this.radioCalendar(id); }, // private showEventMenu : function(el, xy){ var id = this.getCalendarId(el.parent('li')), rec = this.store.getById(id), colorId = rec.data[Ext.ensible.cal.CalendarMappings.ColorId.name]; if(!this.menu){ this.menu = new Ext.ensible.cal.CalendarListMenu(); this.menu.on('colorchange', this.handleColorChange, this); this.menu.on('radiocalendar', this.handleRadioCalendar, this); } this.menu.setCalendar(id, colorId); this.menu.showAt(xy); } }); Ext.reg('extensible.calendarlist', Ext.ensible.cal.CalendarList);