4 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
5 * @author Cornelius Weiss <c.weiss@metaways.de>
6 * @copyright Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
12 Ext.ns('Ext.ux', 'Ext.ux.form');
15 * A combination range and paging control
17 * @namespace Ext.ux.form
18 * @class Ext.ux.form.PeriodPicker
19 * @extends Ext.form.Field
21 Ext.ux.form.PeriodPicker = Ext.extend(Ext.form.Field, {
24 * @cfg {String} availableRanges
25 * ranges available in range picker
26 * _('Day'), _('Week'), _('Month'), _('Year')
28 availableRanges: 'day,week,month',
37 * @cfg {Date} startDate
38 * defaults to toDay, will be constraint to period, gets overwritten by value
63 initComponent: function() {
64 Ext.ux.form.PeriodPicker.superclass.initComponent.call(this);
66 this.value = Ext.ux.form.PeriodPicker.getPeriod(this.value ? this.value.from : this.startDate || new Date(), this.range);
67 this.startDate = this.value.from;
68 this.startValue = this.value;
72 * @return {Object} {from: Date, until: Date}
74 getValue: function() {
79 * @param {Object} value {from: Date, until: Date}
81 setValue: function(value) {
82 this.range = Ext.ux.form.PeriodPicker.getRange(value);
83 this.value = Ext.ux.form.PeriodPicker.getPeriod(value.from, this.range);
84 this.startDate = this.value.from;
86 this.getRangeCombo().setValue(this.range);
91 dateString = Tine.Tinebase.common.dateRenderer(this.startDate);
94 // NOTE: '+1' is to ensure we display the ISO8601 based week where weeks always start on monday!
95 var wkStart = this.startDate.add(Date.DAY, this.startDate.getDay() < 1 ? 1 : 0);
97 dateString = wkStart.getWeekOfYear() + ' ' + this.startDate.format('Y');
100 dateString = Ext.DatePicker.prototype.monthNames[this.startDate.getMonth()] + ' ' + this.startDate.format('Y');
103 dateString = this.startDate.format('Y');
106 this.setPeriodText(dateString);
108 if (JSON.stringify(this.value) != JSON.stringify(this.startValue)){
109 this.fireEvent('change', this, this.value, this.startValue);
114 this.originalValue = this.startValue;
116 Ext.ux.form.PeriodPicker.superclass.reset.apply(this, arguments);
119 setStartDate: function(startDate) {
120 var value = Ext.ux.form.PeriodPicker.getPeriod(startDate, this.range);
121 this.setValue(value);
124 setPeriodText: function(text) {
125 this.el.child('.ux-pp-period').update(Ext.util.Format.htmlEncode(text));
129 onRangeComboChange: function() {
130 this.setValue(Ext.ux.form.PeriodPicker.getPeriod(this.startDate, this.getRangeCombo().getValue()));
134 onClick: function(e) {
135 var prev = e.getTarget('.ux-pp-prev'),
136 next = e.getTarget('.ux-pp-next'),
137 period = e.getTarget('.ux-pp-period');
140 this.setStartDate(this.value.until.add(Date.DAY, 1));
142 this.setStartDate(this.value.from.add(Date.DAY, -1));
144 this.getDatePickerMenu().show(period);
149 onRender : function(ct, position){
150 this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
151 Ext.ux.form.PeriodPicker.superclass.onRender.call(this, ct, position);
153 var rangeCombo = this.getRangeCombo();
154 rangeCombo.render(this.el.child('.ux-pp-range'));
155 rangeCombo.setWidth(this.getEl().getWidth() * 0.4);
157 this.setValue(this.value);
158 this.mon(this.getEl(), 'click', this.onClick, this);
162 onResize: function (w, h) {
163 Ext.ux.form.PeriodPicker.superclass.onResize.apply(this, arguments);
165 this.getRangeCombo().setWidth(this.getEl().getWidth() * 0.4);
168 getRangeCombo: function() {
169 if (! this.rangeCombo) {
171 Ext.each(this.availableRanges.split(','), function(range) {
172 fieldDef.push([range, i18n._hidden(Ext.util.Format.capitalize(range))]);
175 this.rangeCombo = new Ext.form.ComboBox({
177 triggerAction: 'all',
179 forceSelection: true,
183 // value: this.range,
186 select: this.onRangeComboChange
191 return this.rangeCombo;
195 * returns a new datepickerMenu
197 * @returns {Ext.menu.DateMenu}
199 getDatePickerMenu: function() {
202 return new Ext.menu.DateMenu({
203 value: this.startDate,
206 plugins: [new Ext.ux.DatePickerWeekPlugin({
207 weekHeaderString: Tine.Tinebase.appMgr.get('Calendar').i18n._hidden('WK'),
208 inspectMonthPickerClick: function(btn, e) {
209 if (e.getTarget('button')) {
210 me.getRangeCombo().setValue('month');
212 me.setStartDate(this.activeDate);
220 select: function(picker, value, weekNumber) {
221 this.getRangeCombo().setValue(weekNumber ? 'week' : 'day');
222 this.range = weekNumber ? 'week' : 'day';
223 this.setStartDate(value);
234 * @param {Date} startDate date within period
235 * @param {String} range day|week|month|year
236 * @return {Object} {from: Date, until: Date}
238 Ext.ux.form.PeriodPicker.getPeriod = function(startDate, range) {
242 from = startDate.clearTime(true);
243 until = from.add(Date.DAY, 1);
246 from = startDate.clearTime(true).add(Date.DAY, -1 * startDate.getDay())
247 .add(Date.DAY, Ext.DatePicker.prototype.startDay - (startDate.getDay() == 0 ? 7 : 0));
248 until = from.add(Date.DAY, 7);
251 from = startDate.clearTime(true).getFirstDateOfMonth();
252 until = from.getLastDateOfMonth().add(Date.DAY, 1);
255 var year = this.startDate.format('y');
256 from = Date.parse(year + '-0-0 00:00:00', 'Y-m-d H:i:s');
257 until = Date.parse(++year + '-0-0 00:00:00', 'Y-m-d H:i:s');
261 return {from: from, until: until};
268 * @param {Object} {from: Date, until: Date}
269 * @return {String} range day|week|month|year
271 Ext.ux.form.PeriodPicker.getRange = function(period) {
272 var ms = period.from.getElapsed(period.until),
275 if (ms > msDay * 300) {
277 } else if (ms > msDay * 20) {
279 } else if (ms > msDay * 5) {
286 Ext.reg('ux-period-picker', Ext.ux.form.PeriodPicker)