1 | define([ |
---|
2 | "dojo/_base/declare", |
---|
3 | "dojo/_base/array", |
---|
4 | "dojo/_base/event", |
---|
5 | "dojo/_base/lang", |
---|
6 | "dojo/_base/sniff", |
---|
7 | "dojo/_base/fx", |
---|
8 | "dojo/_base/html", |
---|
9 | "dojo/on", |
---|
10 | "dojo/dom", |
---|
11 | "dojo/dom-class", |
---|
12 | "dojo/dom-style", |
---|
13 | "dojo/dom-geometry", |
---|
14 | "dojo/dom-construct", |
---|
15 | "dojo/query", |
---|
16 | "dojox/html/metrics", |
---|
17 | "dojo/i18n", |
---|
18 | "./ViewBase", |
---|
19 | "dojo/text!./templates/MatrixView.html", |
---|
20 | "dijit/_TemplatedMixin"], |
---|
21 | |
---|
22 | function( |
---|
23 | declare, |
---|
24 | arr, |
---|
25 | event, |
---|
26 | lang, |
---|
27 | has, |
---|
28 | fx, |
---|
29 | html, |
---|
30 | on, |
---|
31 | dom, |
---|
32 | domClass, |
---|
33 | domStyle, |
---|
34 | domGeometry, |
---|
35 | domConstruct, |
---|
36 | query, |
---|
37 | metrics, |
---|
38 | i18n, |
---|
39 | ViewBase, |
---|
40 | template, |
---|
41 | _TemplatedMixin){ |
---|
42 | |
---|
43 | /*===== |
---|
44 | var __HeaderClickEventArgs = { |
---|
45 | // summary: |
---|
46 | // A column click event. |
---|
47 | // index: Integer |
---|
48 | // The column index. |
---|
49 | // date: Date |
---|
50 | // The date displayed by the column. |
---|
51 | // triggerEvent: Event |
---|
52 | // The origin event. |
---|
53 | }; |
---|
54 | =====*/ |
---|
55 | |
---|
56 | /*===== |
---|
57 | var __ExpandRendererClickEventArgs = { |
---|
58 | // summary: |
---|
59 | // A expand renderer click event. |
---|
60 | // columnIndex: Integer |
---|
61 | // The column index of the cell. |
---|
62 | // rowIndex: Integer |
---|
63 | // The row index of the cell. |
---|
64 | // date: Date |
---|
65 | // The date displayed by the cell. |
---|
66 | // triggerEvent: Event |
---|
67 | // The origin event. |
---|
68 | }; |
---|
69 | =====*/ |
---|
70 | |
---|
71 | return declare("dojox.calendar.MatrixView", [ViewBase, _TemplatedMixin], { |
---|
72 | |
---|
73 | // summary: |
---|
74 | // The matrix view is a calendar view that displaying a matrix where each cell is a day. |
---|
75 | |
---|
76 | templateString: template, |
---|
77 | |
---|
78 | baseClass: "dojoxCalendarMatrixView", |
---|
79 | |
---|
80 | _setTabIndexAttr: "domNode", |
---|
81 | |
---|
82 | // viewKind: String |
---|
83 | // Type of the view. Used by the calendar widget to determine how to configure the view. |
---|
84 | // This view kind is "matrix". |
---|
85 | viewKind: "matrix", |
---|
86 | |
---|
87 | // renderData: Object |
---|
88 | // The render data object contains all the data needed to render the widget. |
---|
89 | renderData: null, |
---|
90 | |
---|
91 | // startDate: Date |
---|
92 | // The start date of the time interval displayed. |
---|
93 | // If not set at initialization time, will be set to current day. |
---|
94 | startDate: null, |
---|
95 | |
---|
96 | // refStartTime: Date? |
---|
97 | // (Optional) Start of the time interval of interest. |
---|
98 | // It is used to style differently the displayed rows out of the |
---|
99 | // time interval of interest. |
---|
100 | refStartTime: null, |
---|
101 | |
---|
102 | // refStartTime: Date? |
---|
103 | // (Optional) End of the time interval of interest. |
---|
104 | // It is used to style differently the displayed rows out of the |
---|
105 | // time interval of interest. |
---|
106 | refEndTime: null, |
---|
107 | |
---|
108 | // columnCount: Integer |
---|
109 | // The number of column to display (from the startDate). |
---|
110 | columnCount: 7, |
---|
111 | |
---|
112 | // rowCount: Integer |
---|
113 | // The number of rows to display (from the startDate). |
---|
114 | rowCount: 5, |
---|
115 | |
---|
116 | // horizontalRenderer: Class |
---|
117 | // The class use to create horizontal renderers. |
---|
118 | horizontalRenderer: null, |
---|
119 | |
---|
120 | // labelRenderer: Class |
---|
121 | // The class use to create label renderers. |
---|
122 | labelRenderer: null, |
---|
123 | |
---|
124 | // expandRenderer: Class |
---|
125 | // The class use to create drill down renderers. |
---|
126 | expandRenderer: null, |
---|
127 | |
---|
128 | // percentOverlap: Integer |
---|
129 | // The percentage of the renderer width used to superimpose one item renderers on another |
---|
130 | // when two events are overlapping. By default 0. |
---|
131 | percentOverlap: 0, |
---|
132 | |
---|
133 | // verticalGap: Integer |
---|
134 | // The number of pixels between two item renderers that are overlapping each other if the percentOverlap property is 0. |
---|
135 | verticalGap: 2, |
---|
136 | |
---|
137 | // horizontalRendererHeight: Integer |
---|
138 | // The height in pixels of the horizontal and label renderers that is applied by the layout. |
---|
139 | horizontalRendererHeight: 17, |
---|
140 | |
---|
141 | // horizontalRendererHeight: Integer |
---|
142 | // The height in pixels of the horizontal and label renderers that is applied by the layout. |
---|
143 | labelRendererHeight: 14, |
---|
144 | |
---|
145 | // expandRendererHeight: Integer |
---|
146 | // The height in pixels of the expand/collapse renderers that is applied by the layout. |
---|
147 | expandRendererHeight: 15, |
---|
148 | |
---|
149 | // cellPaddingTop: Integer |
---|
150 | // The top offset in pixels of each cell applied by the layout. |
---|
151 | cellPaddingTop: 16, |
---|
152 | |
---|
153 | // expandDuration: Integer |
---|
154 | // Duration of the animation when expanding or collapsing a row. |
---|
155 | expandDuration: 300, |
---|
156 | |
---|
157 | // expandEasing: Function |
---|
158 | // Easing function of the animation when expanding or collapsing a row (null by default). |
---|
159 | expandEasing: null, |
---|
160 | |
---|
161 | // layoutDuringResize: Boolean |
---|
162 | // Indicates if the item renderers' position and size is updated or if they are hidden during a resize of the widget. |
---|
163 | layoutDuringResize: false, |
---|
164 | |
---|
165 | // roundToDay: Boolean |
---|
166 | // For horizontal renderers that are not filling entire days, whether fill the day or not. |
---|
167 | roundToDay: true, |
---|
168 | |
---|
169 | // showCellLabel: Boolean |
---|
170 | // Whether display or not the grid cells label (usually the day of month). |
---|
171 | showCellLabel: true, |
---|
172 | |
---|
173 | // scrollable: [private] Boolean |
---|
174 | scrollable: false, |
---|
175 | |
---|
176 | // resizeCursor: [private] Boolean |
---|
177 | resizeCursor: "e-resize", |
---|
178 | |
---|
179 | constructor: function(){ |
---|
180 | this.invalidatingProperties = ["columnCount", "rowCount", "startDate", "horizontalRenderer", "labelRenderer", "expandRenderer", |
---|
181 | "rowHeaderDatePattern", "columnHeaderLabelLength", "cellHeaderShortPattern", "cellHeaderLongPattern", "percentOverlap", |
---|
182 | "verticalGap", "horizontalRendererHeight", "labelRendererHeight", "expandRendererHeight", "cellPaddingTop", |
---|
183 | "roundToDay", "itemToRendererKindFunc", "layoutPriorityFunction", "formatItemTimeFunc", "textDir", "items"]; |
---|
184 | |
---|
185 | this._ddRendererList = []; |
---|
186 | this._ddRendererPool = []; |
---|
187 | this._rowHeaderHandles = []; |
---|
188 | }, |
---|
189 | |
---|
190 | destroy: function(preserveDom){ |
---|
191 | this._cleanupRowHeader(); |
---|
192 | this.inherited(arguments); |
---|
193 | }, |
---|
194 | |
---|
195 | postCreate: function(){ |
---|
196 | this.inherited(arguments); |
---|
197 | this._initialized = true; |
---|
198 | if(!this.invalidRendering){ |
---|
199 | this.refreshRendering(); |
---|
200 | } |
---|
201 | }, |
---|
202 | |
---|
203 | _createRenderData: function(){ |
---|
204 | |
---|
205 | var rd = {}; |
---|
206 | |
---|
207 | rd.dateLocaleModule = this.dateLocaleModule; |
---|
208 | rd.dateClassObj = this.dateClassObj; |
---|
209 | rd.dateModule = this.dateModule; // arithmetics on Dates |
---|
210 | |
---|
211 | rd.dates = []; |
---|
212 | |
---|
213 | rd.columnCount = this.get("columnCount"); |
---|
214 | rd.rowCount = this.get("rowCount"); |
---|
215 | |
---|
216 | rd.sheetHeight = this.itemContainer.offsetHeight; |
---|
217 | |
---|
218 | this._computeRowsHeight(rd); |
---|
219 | |
---|
220 | var d = this.get("startDate"); |
---|
221 | |
---|
222 | if(d == null){ |
---|
223 | d = new rd.dateClassObj(); |
---|
224 | } |
---|
225 | |
---|
226 | d = this.floorToDay(d, false, rd); |
---|
227 | |
---|
228 | this.startDate = d; |
---|
229 | |
---|
230 | for(var row = 0; row < rd.rowCount ; row++){ |
---|
231 | rd.dates.push([]); |
---|
232 | for(var col = 0; col < rd.columnCount ; col++){ |
---|
233 | rd.dates[row].push(d); |
---|
234 | d = rd.dateModule.add(d, "day", 1); |
---|
235 | d = this.floorToDay(d, false, rd); |
---|
236 | } |
---|
237 | } |
---|
238 | |
---|
239 | rd.startTime = this.newDate(rd.dates[0][0], rd); |
---|
240 | rd.endTime = this.newDate(rd.dates[rd.rowCount-1][rd.columnCount-1], rd); |
---|
241 | rd.endTime = rd.dateModule.add(rd.endTime, "day", 1); |
---|
242 | rd.endTime = this.floorToDay(rd.endTime, true); |
---|
243 | |
---|
244 | if(this.displayedItemsInvalidated && !this._isEditing){ |
---|
245 | this.displayedItemsInvalidated = false; |
---|
246 | this._computeVisibleItems(rd); |
---|
247 | |
---|
248 | }else if(this.renderData){ |
---|
249 | rd.items = this.renderData.items; |
---|
250 | } |
---|
251 | |
---|
252 | rd.rtl = !this.isLeftToRight(); |
---|
253 | |
---|
254 | return rd; |
---|
255 | }, |
---|
256 | |
---|
257 | _validateProperties: function(){ |
---|
258 | |
---|
259 | this.inherited(arguments); |
---|
260 | |
---|
261 | if(this.columnCount<1 || isNaN(this.columnCount)){ |
---|
262 | this.columnCount = 1; |
---|
263 | } |
---|
264 | |
---|
265 | if(this.rowCount<1 || isNaN(this.rowCount)){ |
---|
266 | this.rowCount = 1; |
---|
267 | } |
---|
268 | |
---|
269 | if(isNaN(this.percentOverlap) || this.percentOverlap < 0 || this.percentOverlap > 100){ |
---|
270 | this.percentOverlap = 0; |
---|
271 | } |
---|
272 | |
---|
273 | if(isNaN(this.verticalGap) || this.verticalGap < 0){ |
---|
274 | this.verticalGap = 2; |
---|
275 | } |
---|
276 | |
---|
277 | if(isNaN(this.horizontalRendererHeight) || this.horizontalRendererHeight < 1){ |
---|
278 | this.horizontalRendererHeight = 17; |
---|
279 | } |
---|
280 | |
---|
281 | if(isNaN(this.labelRendererHeight) || this.labelRendererHeight < 1){ |
---|
282 | this.labelRendererHeight = 14; |
---|
283 | } |
---|
284 | |
---|
285 | if(isNaN(this.expandRendererHeight) || this.expandRendererHeight < 1){ |
---|
286 | this.expandRendererHeight = 15; |
---|
287 | } |
---|
288 | |
---|
289 | }, |
---|
290 | |
---|
291 | _setStartDateAttr: function(value){ |
---|
292 | this.displayedItemsInvalidated = true; |
---|
293 | this._set("startDate", value); |
---|
294 | }, |
---|
295 | |
---|
296 | _setColumnCountAttr: function(value){ |
---|
297 | this.displayedItemsInvalidated = true; |
---|
298 | this._set("columnCount", value); |
---|
299 | }, |
---|
300 | |
---|
301 | _setRowCountAttr: function(value){ |
---|
302 | this.displayedItemsInvalidated = true; |
---|
303 | this._set("rowCount", value); |
---|
304 | }, |
---|
305 | |
---|
306 | __fixEvt:function(e){ |
---|
307 | e.sheet = "primary"; |
---|
308 | e.source = this; |
---|
309 | return e; |
---|
310 | }, |
---|
311 | |
---|
312 | ////////////////////////////////////////// |
---|
313 | // |
---|
314 | // Formatting functions |
---|
315 | // |
---|
316 | ////////////////////////////////////////// |
---|
317 | |
---|
318 | _formatRowHeaderLabel: function(/*Date*/d){ |
---|
319 | // summary: |
---|
320 | // Computes the row header label for the specified time of day. |
---|
321 | // By default the getWeekNumberLabel() function is called. |
---|
322 | // The rowHeaderDatePattern property can be used to set a |
---|
323 | // custom date pattern to the formatter. |
---|
324 | // d: Date |
---|
325 | // The date to format |
---|
326 | // tags: |
---|
327 | // protected |
---|
328 | |
---|
329 | if(this.rowHeaderDatePattern){ |
---|
330 | return this.renderData.dateLocaleModule.format(d, { |
---|
331 | selector: 'date', |
---|
332 | datePattern: this.rowHeaderDatePattern |
---|
333 | }); |
---|
334 | }else{ |
---|
335 | return this.getWeekNumberLabel(d); |
---|
336 | } |
---|
337 | |
---|
338 | }, |
---|
339 | |
---|
340 | _formatColumnHeaderLabel: function(d){ |
---|
341 | // summary: |
---|
342 | // Computes the column header label for the specified date. |
---|
343 | // By default a formatter is used, optionally the <code>columnHeaderLabelLength</code> |
---|
344 | // property can be used to specify the length of the string. |
---|
345 | // d: Date |
---|
346 | // The date to format |
---|
347 | // tags: |
---|
348 | // protected |
---|
349 | |
---|
350 | return this.renderData.dateLocaleModule.getNames('days', this.columnHeaderLabelLength ? this.columnHeaderLabelLength : 'wide', 'standAlone')[d.getDay()]; |
---|
351 | }, |
---|
352 | |
---|
353 | _formatGridCellLabel: function(d, row, col){ |
---|
354 | // summary: |
---|
355 | // Computes the column header label for the specified date. |
---|
356 | // By default a formatter is used, optionally the <code>cellHeaderLongPattern</code> and <code>cellHeaderShortPattern</code> |
---|
357 | // properties can be used to set a custom date pattern to the formatter. |
---|
358 | // d: Date |
---|
359 | // The date to format. |
---|
360 | // row: Integer |
---|
361 | // The row that displays the current date. |
---|
362 | // col: Integer |
---|
363 | // The column that displays the current date. |
---|
364 | // tags: |
---|
365 | // protected |
---|
366 | |
---|
367 | |
---|
368 | var isFirstDayOfMonth = row == 0 && col == 0 || d.getDate() == 1; |
---|
369 | var format, rb; |
---|
370 | if(isFirstDayOfMonth){ |
---|
371 | if(this.cellHeaderLongPattern){ |
---|
372 | format = this.cellHeaderLongPattern; |
---|
373 | }else{ |
---|
374 | rb = i18n.getLocalization("dojo.cldr", this._calendar); |
---|
375 | format = rb["dateFormatItem-MMMd"]; |
---|
376 | } |
---|
377 | }else{ |
---|
378 | if(this.cellHeaderShortPattern){ |
---|
379 | format = this.cellHeaderShortPattern; |
---|
380 | }else{ |
---|
381 | rb = i18n.getLocalization("dojo.cldr", this._calendar); |
---|
382 | format = rb["dateFormatItem-d"]; |
---|
383 | } |
---|
384 | } |
---|
385 | return this.renderData.dateLocaleModule.format(d, { |
---|
386 | selector: 'date', |
---|
387 | datePattern: format |
---|
388 | }); |
---|
389 | }, |
---|
390 | |
---|
391 | //////////////////////////////////////////// |
---|
392 | // |
---|
393 | // HTML structure management |
---|
394 | // |
---|
395 | /////////////////////////////////////////// |
---|
396 | |
---|
397 | refreshRendering: function(){ |
---|
398 | this.inherited(arguments); |
---|
399 | |
---|
400 | if(!this.domNode){ |
---|
401 | return; |
---|
402 | } |
---|
403 | |
---|
404 | this._validateProperties(); |
---|
405 | |
---|
406 | var oldRd = this.renderData; |
---|
407 | this.renderData = this._createRenderData(); |
---|
408 | |
---|
409 | this._createRendering(this.renderData, oldRd); |
---|
410 | |
---|
411 | this._layoutRenderers(this.renderData); |
---|
412 | }, |
---|
413 | |
---|
414 | _createRendering: function(renderData, oldRenderData){ |
---|
415 | // summary: |
---|
416 | // Creates the HTML structure (grid, place holders, headers, etc) |
---|
417 | // renderData: Object |
---|
418 | // The new render data |
---|
419 | // oldRenderData: Object |
---|
420 | // The previous render data |
---|
421 | // tags: |
---|
422 | // private |
---|
423 | |
---|
424 | if(renderData.rowHeight <= 0){ |
---|
425 | renderData.columnCount = 1; |
---|
426 | renderData.rowCount = 1; |
---|
427 | renderData.invalidRowHeight = true; |
---|
428 | return; |
---|
429 | } |
---|
430 | |
---|
431 | if(oldRenderData){ |
---|
432 | // make sure to have correct rowCount |
---|
433 | if(this.itemContainerTable){ |
---|
434 | var rows = query(".dojoxCalendarItemContainerRow", this.itemContainerTable); |
---|
435 | oldRenderData.rowCount = rows.length; |
---|
436 | } |
---|
437 | } |
---|
438 | |
---|
439 | this._buildColumnHeader(renderData, oldRenderData); |
---|
440 | this._buildRowHeader(renderData, oldRenderData); |
---|
441 | this._buildGrid(renderData, oldRenderData); |
---|
442 | this._buildItemContainer(renderData, oldRenderData); |
---|
443 | |
---|
444 | if(this.buttonContainer && this.owner != null && this.owner.currentView == this){ |
---|
445 | domStyle.set(this.buttonContainer, {"right":0, "left":0}); |
---|
446 | } |
---|
447 | }, |
---|
448 | |
---|
449 | _buildColumnHeader: function(/*Object*/ renderData, /*Object*/oldRenderData){ |
---|
450 | // summary: |
---|
451 | // Creates incrementally the HTML structure of the column header and configures its content. |
---|
452 | // |
---|
453 | // renderData: |
---|
454 | // The render data to display. |
---|
455 | // |
---|
456 | // oldRenderData: |
---|
457 | // The previously render data displayed, if any. |
---|
458 | // tags: |
---|
459 | // private |
---|
460 | var table = this.columnHeaderTable; |
---|
461 | |
---|
462 | if(!table){ |
---|
463 | return; |
---|
464 | } |
---|
465 | |
---|
466 | var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0); |
---|
467 | |
---|
468 | if(has("ie") == 8){ |
---|
469 | // workaround Internet Explorer 8 bug. |
---|
470 | // if on the table, width: 100% and table-layout: fixed are set |
---|
471 | // and columns are removed, width of remaining columns is not |
---|
472 | // recomputed: must rebuild all. |
---|
473 | if(this._colTableSave == null){ |
---|
474 | this._colTableSave = lang.clone(table); |
---|
475 | }else if(count < 0){ |
---|
476 | this.columnHeader.removeChild(table); |
---|
477 | domConstruct.destroy(table); |
---|
478 | table = lang.clone(this._colTableSave); |
---|
479 | this.columnHeaderTable = table; |
---|
480 | this.columnHeader.appendChild(table); |
---|
481 | count = renderData.columnCount; |
---|
482 | } |
---|
483 | |
---|
484 | } // else incremental dom add/remove for real browsers. |
---|
485 | |
---|
486 | var tbodies = query("tbody", table); |
---|
487 | var trs = query("tr", table); |
---|
488 | var tbody, tr, td; |
---|
489 | |
---|
490 | if(tbodies.length == 1){ |
---|
491 | tbody = tbodies[0]; |
---|
492 | }else{ |
---|
493 | tbody = html.create("tbody", null, table); |
---|
494 | } |
---|
495 | |
---|
496 | if(trs.length == 1){ |
---|
497 | tr = trs[0]; |
---|
498 | }else{ |
---|
499 | tr = domConstruct.create("tr", null, tbody); |
---|
500 | } |
---|
501 | |
---|
502 | // Build HTML structure (incremental) |
---|
503 | if(count > 0){ // creation |
---|
504 | for(var i=0; i < count; i++){ |
---|
505 | td = domConstruct.create("td", null, tr); |
---|
506 | } |
---|
507 | }else{ // deletion |
---|
508 | count = -count; |
---|
509 | for(var i=0; i < count; i++){ |
---|
510 | tr.removeChild(tr.lastChild); |
---|
511 | } |
---|
512 | } |
---|
513 | |
---|
514 | // fill & configure |
---|
515 | query("td", table).forEach(function(td, i){ |
---|
516 | td.className = ""; |
---|
517 | var d = renderData.dates[0][i]; |
---|
518 | this._setText(td, this._formatColumnHeaderLabel(d)); |
---|
519 | if(i == 0){ |
---|
520 | domClass.add(td, "first-child"); |
---|
521 | }else if(i == this.renderData.columnCount-1){ |
---|
522 | domClass.add(td, "last-child"); |
---|
523 | } |
---|
524 | this.styleColumnHeaderCell(td, d, renderData); |
---|
525 | }, this); |
---|
526 | |
---|
527 | if(this.yearColumnHeaderContent){ |
---|
528 | var d = renderData.dates[0][0]; |
---|
529 | this._setText(this.yearColumnHeaderContent, renderData.dateLocaleModule.format(d, |
---|
530 | {selector: "date", datePattern:"yyyy"})); |
---|
531 | } |
---|
532 | }, |
---|
533 | |
---|
534 | styleColumnHeaderCell: function(node, date, renderData){ |
---|
535 | // summary: |
---|
536 | // Styles the CSS classes to the node that displays a column header cell. |
---|
537 | // By default this method is setting the "dojoxCalendarWeekend" if the day of week represents a weekend. |
---|
538 | // node: Node |
---|
539 | // The DOM node that displays the column in the grid. |
---|
540 | // date: Date |
---|
541 | // The date displayed by this column |
---|
542 | // renderData: Object |
---|
543 | // The render data. |
---|
544 | // tags: |
---|
545 | // protected |
---|
546 | |
---|
547 | domClass.add(node, this._cssDays[date.getDay()]); |
---|
548 | |
---|
549 | if(this.isWeekEnd(date)){ |
---|
550 | domClass.add(node, "dojoxCalendarWeekend"); |
---|
551 | } |
---|
552 | }, |
---|
553 | |
---|
554 | _rowHeaderHandles: null, |
---|
555 | |
---|
556 | _cleanupRowHeader: function(){ |
---|
557 | // tags: |
---|
558 | // private |
---|
559 | |
---|
560 | while(this._rowHeaderHandles.length > 0){ |
---|
561 | var list = this._rowHeaderHandles.pop(); |
---|
562 | while(list.length>0){ |
---|
563 | list.pop().remove(); |
---|
564 | } |
---|
565 | } |
---|
566 | }, |
---|
567 | |
---|
568 | |
---|
569 | _rowHeaderClick: function(e){ |
---|
570 | // tags: |
---|
571 | // private |
---|
572 | |
---|
573 | var index = query("td", this.rowHeaderTable).indexOf(e.currentTarget); |
---|
574 | this._onRowHeaderClick({ |
---|
575 | index: index, |
---|
576 | date: this.renderData.dates[index][0], |
---|
577 | triggerEvent: e |
---|
578 | }); |
---|
579 | }, |
---|
580 | |
---|
581 | _buildRowHeader: function(renderData, oldRenderData){ |
---|
582 | |
---|
583 | // summary: |
---|
584 | // Creates incrementally the HTML structure of the row header and configures its content. |
---|
585 | // |
---|
586 | // renderData: |
---|
587 | // The render data to display. |
---|
588 | // |
---|
589 | // oldRenderData: |
---|
590 | // The previously render data displayed, if any. |
---|
591 | // tags: |
---|
592 | // private |
---|
593 | |
---|
594 | var rowHeaderTable = this.rowHeaderTable; |
---|
595 | |
---|
596 | if(!rowHeaderTable){ |
---|
597 | return; |
---|
598 | } |
---|
599 | |
---|
600 | var tbodies = query("tbody", rowHeaderTable); |
---|
601 | var tbody, tr, td; |
---|
602 | |
---|
603 | if(tbodies.length == 1){ |
---|
604 | tbody = tbodies[0]; |
---|
605 | }else{ |
---|
606 | tbody = domConstruct.create("tbody", null, rowHeaderTable); |
---|
607 | } |
---|
608 | |
---|
609 | var count = renderData.rowCount - (oldRenderData ? oldRenderData.rowCount : 0); |
---|
610 | |
---|
611 | // Build HTML structure |
---|
612 | if(count>0){ // creation |
---|
613 | for(var i=0; i < count; i++){ |
---|
614 | tr = domConstruct.create("tr", null, tbody); |
---|
615 | td = domConstruct.create("td", null, tr); |
---|
616 | |
---|
617 | var h = []; |
---|
618 | |
---|
619 | h.push(on(td, "click", lang.hitch(this, this._rowHeaderClick))); |
---|
620 | |
---|
621 | if(!has("touch")){ |
---|
622 | h.push(on(td, "mousedown", function(e){ |
---|
623 | domClass.add(e.currentTarget, "Active"); |
---|
624 | })); |
---|
625 | |
---|
626 | h.push(on(td, "mouseup", function(e){ |
---|
627 | domClass.remove(e.currentTarget, "Active"); |
---|
628 | })); |
---|
629 | |
---|
630 | h.push(on(td, "mouseover", function(e){ |
---|
631 | domClass.add(e.currentTarget, "Hover"); |
---|
632 | })); |
---|
633 | |
---|
634 | h.push(on(td, "mouseout", function(e){ |
---|
635 | domClass.remove(e.currentTarget, "Hover"); |
---|
636 | })); |
---|
637 | } |
---|
638 | this._rowHeaderHandles.push(h); |
---|
639 | } |
---|
640 | }else{ |
---|
641 | count = -count; |
---|
642 | // deletion of existing nodes |
---|
643 | for(var i=0; i < count; i++){ |
---|
644 | tbody.removeChild(tbody.lastChild); |
---|
645 | var list = this._rowHeaderHandles.pop(); |
---|
646 | while(list.length>0){ |
---|
647 | list.pop().remove(); |
---|
648 | } |
---|
649 | } |
---|
650 | } |
---|
651 | |
---|
652 | // fill labels |
---|
653 | |
---|
654 | query("tr", rowHeaderTable).forEach(function(tr, i){ |
---|
655 | |
---|
656 | domStyle.set(tr, "height", this._getRowHeight(i) + "px"); |
---|
657 | |
---|
658 | var d = renderData.dates[i][0]; |
---|
659 | |
---|
660 | var td = query("td", tr)[0]; |
---|
661 | td.className = ""; |
---|
662 | if(i == 0){ |
---|
663 | domClass.add(td, "first-child"); |
---|
664 | } |
---|
665 | if(i == this.renderData.rowCount-1){ |
---|
666 | domClass.add(td, "last-child"); |
---|
667 | } |
---|
668 | |
---|
669 | this.styleRowHeaderCell(td, d, renderData); |
---|
670 | |
---|
671 | this._setText(td, this._formatRowHeaderLabel(d)); |
---|
672 | }, this); |
---|
673 | |
---|
674 | }, |
---|
675 | |
---|
676 | styleRowHeaderCell: function(node, date, renderData){ |
---|
677 | // summary: |
---|
678 | // Styles the CSS classes to the node that displays a row header cell. |
---|
679 | // By default this method is doing nothing. |
---|
680 | // node: Node |
---|
681 | // The DOM node that displays the column in the grid. |
---|
682 | // date: Date |
---|
683 | // The date in the week. |
---|
684 | // renderData: Object |
---|
685 | // The render data. |
---|
686 | // tags: |
---|
687 | // protected |
---|
688 | |
---|
689 | |
---|
690 | }, |
---|
691 | |
---|
692 | _buildGrid: function (renderData, oldRenderData){ |
---|
693 | // summary: |
---|
694 | // Creates incrementally the HTML structure of the grid and configures its content. |
---|
695 | // |
---|
696 | // renderData: |
---|
697 | // The render data to display. |
---|
698 | // |
---|
699 | // oldRenderData: |
---|
700 | // The previously render data displayed, if any. |
---|
701 | // tags: |
---|
702 | // private |
---|
703 | |
---|
704 | var table = this.gridTable; |
---|
705 | |
---|
706 | if(!table){ |
---|
707 | return; |
---|
708 | } |
---|
709 | |
---|
710 | var currentTR = query("tr", table); |
---|
711 | |
---|
712 | var rowDiff = renderData.rowCount - currentTR.length; |
---|
713 | var addRows = rowDiff > 0; |
---|
714 | |
---|
715 | var colDiff = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0); |
---|
716 | |
---|
717 | if(has("ie") == 8){ |
---|
718 | // workaround Internet Explorer 8 bug. |
---|
719 | // if on the table, width: 100% and table-layout: fixed are set |
---|
720 | // and columns are removed, width of remaining columns is not |
---|
721 | // recomputed: must rebuild all. |
---|
722 | if(this._gridTableSave == null){ |
---|
723 | this._gridTableSave = lang.clone(table); |
---|
724 | }else if(colDiff < 0){ |
---|
725 | this.grid.removeChild(table); |
---|
726 | domConstruct.destroy(table); |
---|
727 | table = lang.clone(this._gridTableSave); |
---|
728 | this.gridTable = table; |
---|
729 | this.grid.appendChild(table); |
---|
730 | colDiff = renderData.columnCount; |
---|
731 | rowDiff = renderData.rowCount; |
---|
732 | addRows = true; |
---|
733 | } |
---|
734 | } |
---|
735 | |
---|
736 | var tbodies = query("tbody", table); |
---|
737 | var tbody; |
---|
738 | |
---|
739 | if(tbodies.length == 1){ |
---|
740 | tbody = tbodies[0]; |
---|
741 | }else{ |
---|
742 | tbody = domConstruct.create("tbody", null, table); |
---|
743 | } |
---|
744 | |
---|
745 | // Build rows HTML structure (incremental) |
---|
746 | if(addRows){ // creation |
---|
747 | for(var i=0; i<rowDiff; i++){ |
---|
748 | domConstruct.create("tr", null, tbody); |
---|
749 | } |
---|
750 | }else{ // deletion |
---|
751 | rowDiff = -rowDiff; |
---|
752 | for(var i=0; i<rowDiff; i++){ |
---|
753 | tbody.removeChild(tbody.lastChild); |
---|
754 | } |
---|
755 | } |
---|
756 | |
---|
757 | var rowIndex = renderData.rowCount - rowDiff; |
---|
758 | |
---|
759 | var addCols = addRows || colDiff >0; |
---|
760 | colDiff = addCols ? colDiff : -colDiff; |
---|
761 | |
---|
762 | query("tr", table).forEach(function(tr, i){ |
---|
763 | |
---|
764 | if(addCols){ // creation |
---|
765 | var len = i >= rowIndex ? renderData.columnCount : colDiff; |
---|
766 | for(var i=0; i<len; i++){ |
---|
767 | var td = domConstruct.create("td", null, tr); |
---|
768 | domConstruct.create("span", null, td); |
---|
769 | } |
---|
770 | }else{ // deletion |
---|
771 | for(var i=0; i<colDiff; i++){ |
---|
772 | tr.removeChild(tr.lastChild); |
---|
773 | } |
---|
774 | } |
---|
775 | }); |
---|
776 | |
---|
777 | // Set the CSS classes |
---|
778 | |
---|
779 | query("tr", table).forEach(function (tr, row){ |
---|
780 | |
---|
781 | domStyle.set(tr, "height", this._getRowHeight(row) + "px"); |
---|
782 | |
---|
783 | tr.className = ""; |
---|
784 | // compatibility layer for IE7 & 8 that does not support :first-child and :last-child pseudo selectors |
---|
785 | if(row == 0){ |
---|
786 | domClass.add(tr, "first-child"); |
---|
787 | } |
---|
788 | if(row == renderData.rowCount-1){ |
---|
789 | domClass.add(tr, "last-child"); |
---|
790 | } |
---|
791 | |
---|
792 | query("td", tr).forEach(function (td, col){ |
---|
793 | |
---|
794 | td.className = ""; |
---|
795 | |
---|
796 | if(col == 0){ |
---|
797 | domClass.add(td, "first-child"); |
---|
798 | } |
---|
799 | |
---|
800 | if(col == renderData.columnCount-1){ |
---|
801 | domClass.add(td, "last-child"); |
---|
802 | } |
---|
803 | |
---|
804 | var d = renderData.dates[row][col]; |
---|
805 | |
---|
806 | var span = query("span", td)[0]; |
---|
807 | this._setText(span, this.showCellLabel ? this._formatGridCellLabel(d, row, col): null); |
---|
808 | |
---|
809 | this.styleGridCell(td, d, renderData); |
---|
810 | }, this); |
---|
811 | }, this); |
---|
812 | |
---|
813 | }, |
---|
814 | |
---|
815 | // styleGridCellFunc: Function |
---|
816 | // Custom function to customize the appearance of a grid cell by installing custom CSS class on the node. |
---|
817 | // The signature of the function must be the same then the styleGridCell one. |
---|
818 | // By default the defaultStyleGridCell function is used. |
---|
819 | styleGridCellFunc: null, |
---|
820 | |
---|
821 | defaultStyleGridCell: function(node, date, renderData){ |
---|
822 | // summary: |
---|
823 | // Styles the CSS classes to the node that displays a cell. |
---|
824 | // By default this method is setting the following CSS classes: |
---|
825 | // - "dojoxCalendarToday" class name if the date displayed is the current date, |
---|
826 | // - "dojoxCalendarWeekend" if the date represents a weekend or |
---|
827 | // - "dojoxCalendarDayDisabled" if the date is out of the [refStartTime, refEndTime] interval. |
---|
828 | // - the CSS class corresponding of the displayed day of week ("Sun", "Mon" and so on). |
---|
829 | // node: Node |
---|
830 | // The DOM node that displays the cell in the grid. |
---|
831 | // date: Date |
---|
832 | // The date displayed by this cell. |
---|
833 | // renderData: Object |
---|
834 | // The render data. |
---|
835 | // tags: |
---|
836 | // protected |
---|
837 | |
---|
838 | domClass.add(node, this._cssDays[date.getDay()]); |
---|
839 | |
---|
840 | var cal = this.dateModule; |
---|
841 | if(this.isToday(date)){ |
---|
842 | domClass.add(node, "dojoxCalendarToday"); |
---|
843 | }else if(this.refStartTime != null && this.refEndTime != null && |
---|
844 | (cal.compare(date, this.refEndTime) >= 0 || |
---|
845 | cal.compare(cal.add(date, "day", 1), this.refStartTime) <= 0)){ |
---|
846 | domClass.add(node, "dojoxCalendarDayDisabled"); |
---|
847 | }else if(this.isWeekEnd(date)){ |
---|
848 | domClass.add(node, "dojoxCalendarWeekend"); |
---|
849 | } |
---|
850 | }, |
---|
851 | |
---|
852 | styleGridCell: function(node, date, renderData){ |
---|
853 | // summary: |
---|
854 | // Styles the CSS classes to the node that displays a cell. |
---|
855 | // Delegates to styleGridCellFunc if defined or defaultStyleGridCell otherwise. |
---|
856 | // node: Node |
---|
857 | // The DOM node that displays the cell in the grid. |
---|
858 | // date: Date |
---|
859 | // The date displayed by this cell. |
---|
860 | // renderData: Object |
---|
861 | // The render data. |
---|
862 | // tags: |
---|
863 | // protected |
---|
864 | if(this.styleGridCellFunc){ |
---|
865 | this.styleGridCellFunc(node, date, renderData); |
---|
866 | }else{ |
---|
867 | this.defaultStyleGridCell(node, date, renderData); |
---|
868 | } |
---|
869 | }, |
---|
870 | |
---|
871 | _buildItemContainer: function(renderData, oldRenderData){ |
---|
872 | // summary: |
---|
873 | // Creates the HTML structure of the item container and configures its content. |
---|
874 | // |
---|
875 | // renderData: |
---|
876 | // The render data to display. |
---|
877 | // |
---|
878 | // oldRenderData: |
---|
879 | // The previously render data displayed, if any. |
---|
880 | // tags: |
---|
881 | // private |
---|
882 | |
---|
883 | var table = this.itemContainerTable; |
---|
884 | |
---|
885 | if(!table){ |
---|
886 | return; |
---|
887 | } |
---|
888 | |
---|
889 | var rows = []; |
---|
890 | |
---|
891 | var count = renderData.rowCount - (oldRenderData ? oldRenderData.rowCount : 0) |
---|
892 | |
---|
893 | if(has("ie") == 8){ |
---|
894 | // workaround Internet Explorer 8 bug. |
---|
895 | // if on the table, width: 100% and table-layout: fixed are set |
---|
896 | // and columns are removed, width of remaining columns is not |
---|
897 | // recomputed: must rebuild all. |
---|
898 | if(this._itemTableSave == null){ |
---|
899 | this._itemTableSave = lang.clone(table); |
---|
900 | }else if(count < 0){ |
---|
901 | this.itemContainer.removeChild(table); |
---|
902 | this._recycleItemRenderers(true); |
---|
903 | this._recycleExpandRenderers(true); |
---|
904 | domConstruct.destroy(table); |
---|
905 | table = lang.clone(this._itemTableSave); |
---|
906 | this.itemContainerTable = table; |
---|
907 | this.itemContainer.appendChild(table); |
---|
908 | count = renderData.columnCount; |
---|
909 | } |
---|
910 | |
---|
911 | } // else incremental dom add/remove for real browsers. |
---|
912 | |
---|
913 | var tbodies = query("tbody", table); |
---|
914 | var tbody, tr, td, div; |
---|
915 | |
---|
916 | if(tbodies.length == 1){ |
---|
917 | tbody = tbodies[0]; |
---|
918 | }else{ |
---|
919 | tbody = domConstruct.create("tbody", null, table); |
---|
920 | } |
---|
921 | |
---|
922 | // Build HTML structure (incremental) |
---|
923 | if(count>0){ // creation |
---|
924 | for(var i=0; i < count; i++){ |
---|
925 | tr = domConstruct.create("tr", null, tbody); |
---|
926 | domClass.add(tr, "dojoxCalendarItemContainerRow"); |
---|
927 | td = domConstruct.create("td", null, tr); |
---|
928 | div = domConstruct.create("div", null, td); |
---|
929 | domClass.add(div, "dojoxCalendarContainerRow"); |
---|
930 | } |
---|
931 | }else{ // deletion |
---|
932 | count = -count; |
---|
933 | for(var i=0; i < count; i++){ |
---|
934 | tbody.removeChild(tbody.lastChild); |
---|
935 | } |
---|
936 | } |
---|
937 | |
---|
938 | query(".dojoxCalendarItemContainerRow", table).forEach(function(tr, i){ |
---|
939 | domStyle.set(tr, "height", this._getRowHeight(i) + "px"); |
---|
940 | rows.push(tr.childNodes[0].childNodes[0]); |
---|
941 | }, this); |
---|
942 | |
---|
943 | renderData.cells = rows; |
---|
944 | }, |
---|
945 | |
---|
946 | resize: function(changeSize){ |
---|
947 | this.inherited(arguments); |
---|
948 | this._resizeHandler(null, false); |
---|
949 | }, |
---|
950 | |
---|
951 | _resizeHandler: function(e, apply){ |
---|
952 | // summary: |
---|
953 | // Refreshes and apply the row height according to the widget height. |
---|
954 | // e: Event |
---|
955 | // The resize event (optional) |
---|
956 | // apply: Boolean |
---|
957 | // Whether take into account the layoutDuringResize flag to relayout item while resizing or not. |
---|
958 | // tags: |
---|
959 | // private |
---|
960 | |
---|
961 | var rd = this.renderData; |
---|
962 | |
---|
963 | if(rd == null){ |
---|
964 | this.refreshRendering(); |
---|
965 | return; |
---|
966 | } |
---|
967 | |
---|
968 | if(rd.sheetHeight != this.itemContainer.offsetHeight){ |
---|
969 | // refresh values |
---|
970 | rd.sheetHeight = this.itemContainer.offsetHeight; |
---|
971 | var expRow = this.getExpandedRowIndex(); |
---|
972 | if(expRow == -1){ |
---|
973 | this._computeRowsHeight(); |
---|
974 | this._resizeRows(); |
---|
975 | }else{ |
---|
976 | this.expandRow(rd.expandedRow, rd.expandedRowCol, 0, null, true); |
---|
977 | } |
---|
978 | if(rd.invalidRowHeight){ |
---|
979 | // complete recompute |
---|
980 | delete rd.invalidRowHeight; |
---|
981 | this.renderData = null; |
---|
982 | this.displayedItemsInvalidated = true; |
---|
983 | this.refreshRendering(); |
---|
984 | return; |
---|
985 | } |
---|
986 | } |
---|
987 | |
---|
988 | if(this.layoutDuringResize || apply){ |
---|
989 | // Use a time for FF (at least). In FF the cell size and position info are not ready yet. |
---|
990 | setTimeout(lang.hitch(this, function(){ |
---|
991 | this._layoutRenderers(this.renderData); |
---|
992 | }), 20); |
---|
993 | |
---|
994 | }else{ |
---|
995 | domStyle.set(this.itemContainer, "opacity", 0); |
---|
996 | this._recycleItemRenderers(); |
---|
997 | this._recycleExpandRenderers(); |
---|
998 | if(this._resizeTimer != undefined){ |
---|
999 | clearTimeout(this._resizeTimer); |
---|
1000 | } |
---|
1001 | this._resizeTimer = setTimeout(lang.hitch(this, function(){ |
---|
1002 | delete this._resizeTimer; |
---|
1003 | this._resizeRowsImpl(this.itemContainer, "tr"); |
---|
1004 | this._layoutRenderers(this.renderData); |
---|
1005 | if(this.resizeAnimationDuration == 0){ |
---|
1006 | domStyle.set(this.itemContainer, "opacity", 1); |
---|
1007 | }else{ |
---|
1008 | fx.fadeIn({node:this.itemContainer, curve:[0, 1]}).play(this.resizeAnimationDuration); |
---|
1009 | } |
---|
1010 | }), 200); |
---|
1011 | } |
---|
1012 | |
---|
1013 | }, |
---|
1014 | |
---|
1015 | // resizeAnimationDuration: Integer |
---|
1016 | // Duration, in milliseconds, of the fade animation showing the item renderers after a widget resize. |
---|
1017 | resizeAnimationDuration: 0, |
---|
1018 | |
---|
1019 | ///////////////////////////////////////////// |
---|
1020 | // |
---|
1021 | // Row height management |
---|
1022 | // |
---|
1023 | ////////////////////////////////////////////// |
---|
1024 | |
---|
1025 | getExpandedRowIndex: function(){ |
---|
1026 | // summary: |
---|
1027 | // Returns the index of the expanded row or -1 if there's no row expanded. |
---|
1028 | return this.renderData.expandedRow == null ? -1 : this.renderData.expandedRow; |
---|
1029 | }, |
---|
1030 | |
---|
1031 | collapseRow: function(duration, easing, apply){ |
---|
1032 | // summary: |
---|
1033 | // Collapses the expanded row, if any. |
---|
1034 | // duration: Integer |
---|
1035 | // Duration in milliseconds of the optional animation. |
---|
1036 | // easing: Function |
---|
1037 | // Easing function of the optional animation. |
---|
1038 | |
---|
1039 | var rd = this.renderData; |
---|
1040 | |
---|
1041 | if(apply == undefined){ |
---|
1042 | apply = true; |
---|
1043 | } |
---|
1044 | if(duration == undefined){ |
---|
1045 | duration = this.expandDuration; |
---|
1046 | } |
---|
1047 | |
---|
1048 | if(rd && rd.expandedRow != null && rd.expandedRow != -1){ |
---|
1049 | if(apply && duration){ |
---|
1050 | var index = rd.expandedRow; |
---|
1051 | var oldSize = rd.expandedRowHeight; |
---|
1052 | delete rd.expandedRow; |
---|
1053 | this._computeRowsHeight(rd); |
---|
1054 | var size = this._getRowHeight(index); |
---|
1055 | rd.expandedRow = index; |
---|
1056 | |
---|
1057 | this._recycleExpandRenderers(); |
---|
1058 | this._recycleItemRenderers(); |
---|
1059 | domStyle.set(this.itemContainer, "display", "none"); |
---|
1060 | |
---|
1061 | this._expandAnimation = new fx.Animation({ |
---|
1062 | curve: [oldSize, size], |
---|
1063 | duration: duration, |
---|
1064 | easing: easing, |
---|
1065 | onAnimate: lang.hitch(this, function(size) { |
---|
1066 | this._expandRowImpl(Math.floor(size)); |
---|
1067 | }), |
---|
1068 | onEnd: lang.hitch(this, function(size) { |
---|
1069 | this._expandAnimation = null; |
---|
1070 | this._collapseRowImpl(false); |
---|
1071 | this._resizeRows(); |
---|
1072 | domStyle.set(this.itemContainer, "display", "block"); |
---|
1073 | setTimeout(lang.hitch(this, function(){ |
---|
1074 | this._layoutRenderers(rd); |
---|
1075 | }), 100); |
---|
1076 | this.onExpandAnimationEnd(false); |
---|
1077 | }) |
---|
1078 | }); |
---|
1079 | |
---|
1080 | this._expandAnimation.play(); |
---|
1081 | }else{ |
---|
1082 | this._collapseRowImpl(apply); |
---|
1083 | } |
---|
1084 | } |
---|
1085 | }, |
---|
1086 | |
---|
1087 | _collapseRowImpl: function(apply){ |
---|
1088 | // tags: |
---|
1089 | // private |
---|
1090 | |
---|
1091 | var rd = this.renderData; |
---|
1092 | delete rd.expandedRow; |
---|
1093 | delete rd.expandedRowHeight; |
---|
1094 | this._computeRowsHeight(rd); |
---|
1095 | if(apply == undefined || apply){ |
---|
1096 | this._resizeRows(); |
---|
1097 | this._layoutRenderers(rd); |
---|
1098 | } |
---|
1099 | }, |
---|
1100 | |
---|
1101 | expandRow: function(rowIndex, colIndex, duration, easing, apply){ |
---|
1102 | // summary: |
---|
1103 | // Expands the specified row. |
---|
1104 | // rowIndex: Integer |
---|
1105 | // The index of the row to expand. |
---|
1106 | // colIndex: Integer? |
---|
1107 | // The column index of the expand renderer that triggers the action, optional. |
---|
1108 | // duration: Integer? |
---|
1109 | // Duration in milliseconds of the optional animation. |
---|
1110 | // easing: Function? |
---|
1111 | // Easing function of the optional animation. |
---|
1112 | |
---|
1113 | var rd = this.renderData; |
---|
1114 | if(!rd || rowIndex < 0 || rowIndex >= rd.rowCount){ |
---|
1115 | return -1; |
---|
1116 | } |
---|
1117 | if(colIndex == undefined || colIndex < 0 || colIndex >= rd.columnCount){ |
---|
1118 | colIndex = -1; // ignore invalid values |
---|
1119 | } |
---|
1120 | if(apply == undefined){ |
---|
1121 | apply = true; |
---|
1122 | } |
---|
1123 | if(duration == undefined){ |
---|
1124 | duration = this.expandDuration; |
---|
1125 | } |
---|
1126 | if(easing == undefined){ |
---|
1127 | easing = this.expandEasing; |
---|
1128 | } |
---|
1129 | |
---|
1130 | var oldSize = this._getRowHeight(rowIndex); |
---|
1131 | var size = rd.sheetHeight - Math.ceil(this.cellPaddingTop * (rd.rowCount-1)); |
---|
1132 | |
---|
1133 | rd.expandedRow = rowIndex; |
---|
1134 | rd.expandedRowCol = colIndex; |
---|
1135 | rd.expandedRowHeight = size; |
---|
1136 | |
---|
1137 | if(apply){ |
---|
1138 | if(duration){ |
---|
1139 | //debugger; |
---|
1140 | this._recycleExpandRenderers(); |
---|
1141 | this._recycleItemRenderers(); |
---|
1142 | domStyle.set(this.itemContainer, "display", "none"); |
---|
1143 | |
---|
1144 | this._expandAnimation = new fx.Animation({ |
---|
1145 | curve: [oldSize, size], |
---|
1146 | duration: duration, |
---|
1147 | delay:50, |
---|
1148 | easing: easing, |
---|
1149 | onAnimate: lang.hitch(this, function(size) { |
---|
1150 | this._expandRowImpl(Math.floor(size)); |
---|
1151 | }), |
---|
1152 | onEnd: lang.hitch(this, function(){ |
---|
1153 | this._expandAnimation = null; |
---|
1154 | domStyle.set(this.itemContainer, "display", "block"); |
---|
1155 | setTimeout(lang.hitch(this, function(){ |
---|
1156 | this._expandRowImpl(size, true); |
---|
1157 | }), 100); |
---|
1158 | this.onExpandAnimationEnd(true); |
---|
1159 | }) |
---|
1160 | }); |
---|
1161 | this._expandAnimation.play(); |
---|
1162 | }else{ |
---|
1163 | this._expandRowImpl(size, true); |
---|
1164 | } |
---|
1165 | } |
---|
1166 | }, |
---|
1167 | |
---|
1168 | _expandRowImpl: function(size, layout){ |
---|
1169 | // tags: |
---|
1170 | // private |
---|
1171 | |
---|
1172 | var rd = this.renderData; |
---|
1173 | rd.expandedRowHeight = size; |
---|
1174 | this._computeRowsHeight(rd, rd.sheetHeight-size); |
---|
1175 | this._resizeRows(); |
---|
1176 | if(layout){ |
---|
1177 | this._layoutRenderers(rd); |
---|
1178 | } |
---|
1179 | }, |
---|
1180 | |
---|
1181 | onExpandAnimationEnd: function(expand){ |
---|
1182 | // summary: |
---|
1183 | // Event dispatched at the end of an expand or collapse animation. |
---|
1184 | // expand: Boolean |
---|
1185 | // Whether the finished animation was an expand or a collapse animation. |
---|
1186 | // tags: |
---|
1187 | // callback |
---|
1188 | |
---|
1189 | }, |
---|
1190 | |
---|
1191 | _resizeRows: function(){ |
---|
1192 | // summary: |
---|
1193 | // Refreshes the height of the underlying HTML objects. |
---|
1194 | // tags: |
---|
1195 | // private |
---|
1196 | |
---|
1197 | if(this._getRowHeight(0) <= 0){ |
---|
1198 | return; |
---|
1199 | } |
---|
1200 | |
---|
1201 | if(this.rowHeaderTable){ |
---|
1202 | this._resizeRowsImpl(this.rowHeaderTable, "tr"); |
---|
1203 | } |
---|
1204 | if(this.gridTable){ |
---|
1205 | this._resizeRowsImpl(this.gridTable, "tr"); |
---|
1206 | } |
---|
1207 | if(this.itemContainerTable){ |
---|
1208 | this._resizeRowsImpl(this.itemContainerTable, "tr"); |
---|
1209 | } |
---|
1210 | }, |
---|
1211 | |
---|
1212 | _computeRowsHeight:function(renderData, max){ |
---|
1213 | // summary: |
---|
1214 | // 1. Determine if it's better to add or remove pixels |
---|
1215 | // 2. distribute added/removed pixels on first and last rows. |
---|
1216 | // if rows are not too small, it is not noticeable. |
---|
1217 | // tags: |
---|
1218 | // private |
---|
1219 | |
---|
1220 | var rd = renderData == null ? this.renderData : renderData; |
---|
1221 | |
---|
1222 | max = max || rd.sheetHeight; |
---|
1223 | |
---|
1224 | max--; |
---|
1225 | |
---|
1226 | if(has("ie") == 7){ |
---|
1227 | max -= rd.rowCount; |
---|
1228 | } |
---|
1229 | |
---|
1230 | if(rd.rowCount == 1){ |
---|
1231 | rd.rowHeight = max; |
---|
1232 | rd.rowHeightFirst = max; |
---|
1233 | rd.rowHeightLast = max; |
---|
1234 | return; |
---|
1235 | } |
---|
1236 | |
---|
1237 | var count = rd.expandedRow == null ? rd.rowCount : rd.rowCount-1; |
---|
1238 | var rhx = max / count; |
---|
1239 | var rhf, rhl, rh; |
---|
1240 | |
---|
1241 | var diffMin = max - (Math.floor(rhx) * count); |
---|
1242 | var diffMax = Math.abs(max - (Math.ceil(rhx) * count)); |
---|
1243 | var diff; |
---|
1244 | |
---|
1245 | var sign = 1; |
---|
1246 | if(diffMin < diffMax){ |
---|
1247 | rh = Math.floor(rhx); |
---|
1248 | diff = diffMin; |
---|
1249 | }else{ |
---|
1250 | sign = -1; |
---|
1251 | rh = Math.ceil(rhx); |
---|
1252 | diff = diffMax; |
---|
1253 | } |
---|
1254 | rhf = rh + sign * Math.floor(diff/2); |
---|
1255 | rhl = rhf + sign * (diff%2); |
---|
1256 | |
---|
1257 | rd.rowHeight = rh; |
---|
1258 | rd.rowHeightFirst = rhf; |
---|
1259 | rd.rowHeightLast = rhl; |
---|
1260 | }, |
---|
1261 | |
---|
1262 | _getRowHeight: function(index){ |
---|
1263 | // tags: |
---|
1264 | // private |
---|
1265 | |
---|
1266 | var rd = this.renderData; |
---|
1267 | if(index == rd.expandedRow){ |
---|
1268 | return rd.expandedRowHeight; |
---|
1269 | } else if(rd.expandedRow == 0 && index == 1 || index == 0){ |
---|
1270 | return rd.rowHeightFirst; |
---|
1271 | } else if(rd.expandedRow == this.renderData.rowCount-1 && |
---|
1272 | index == this.renderData.rowCount-2 || |
---|
1273 | index == this.renderData.rowCount-1){ |
---|
1274 | return rd.rowHeightLast; |
---|
1275 | }else{ |
---|
1276 | return rd.rowHeight; |
---|
1277 | } |
---|
1278 | }, |
---|
1279 | |
---|
1280 | _resizeRowsImpl: function(tableNode, query){ |
---|
1281 | // tags: |
---|
1282 | // private |
---|
1283 | dojo.query(query, tableNode).forEach(function(tr, i){ |
---|
1284 | domStyle.set(tr, "height", this._getRowHeight(i)+"px"); |
---|
1285 | }, this); |
---|
1286 | }, |
---|
1287 | |
---|
1288 | //////////////////////////////////////////// |
---|
1289 | // |
---|
1290 | // Item renderers |
---|
1291 | // |
---|
1292 | /////////////////////////////////////////// |
---|
1293 | |
---|
1294 | _setHorizontalRendererAttr: function(value){ |
---|
1295 | this._destroyRenderersByKind("horizontal"); |
---|
1296 | this._set("horizontalRenderer", value); |
---|
1297 | }, |
---|
1298 | |
---|
1299 | _setLabelRendererAttr: function(value){ |
---|
1300 | this._destroyRenderersByKind("label"); |
---|
1301 | this._set("labelRenderer", value); |
---|
1302 | }, |
---|
1303 | |
---|
1304 | _destroyExpandRenderer: function(renderer){ |
---|
1305 | // summary: |
---|
1306 | // Destroys the expand renderer. |
---|
1307 | // renderer: dojox/calendar/_RendererMixin |
---|
1308 | // The item renderer to destroy. |
---|
1309 | // tags: |
---|
1310 | // protected |
---|
1311 | |
---|
1312 | if(renderer["destroyRecursive"]){ |
---|
1313 | renderer.destroyRecursive(); |
---|
1314 | } |
---|
1315 | |
---|
1316 | html.destroy(renderer.domNode); |
---|
1317 | }, |
---|
1318 | |
---|
1319 | _setExpandRendererAttr: function(value){ |
---|
1320 | while(this._ddRendererList.length>0){ |
---|
1321 | this._destroyExpandRenderer(this._ddRendererList.pop()); |
---|
1322 | } |
---|
1323 | |
---|
1324 | var pool = this._ddRendererPool; |
---|
1325 | if(pool){ |
---|
1326 | while(pool.length > 0){ |
---|
1327 | this._destroyExpandRenderer(pool.pop()); |
---|
1328 | } |
---|
1329 | } |
---|
1330 | this._set("expandRenderer", value); |
---|
1331 | }, |
---|
1332 | |
---|
1333 | _ddRendererList: null, |
---|
1334 | _ddRendererPool: null, |
---|
1335 | |
---|
1336 | _getExpandRenderer: function(date, items, rowIndex, colIndex, expanded){ |
---|
1337 | // tags: |
---|
1338 | // private |
---|
1339 | |
---|
1340 | if(this.expandRenderer == null){ |
---|
1341 | return null; |
---|
1342 | } |
---|
1343 | |
---|
1344 | var ir = this._ddRendererPool.pop(); |
---|
1345 | if(ir == null){ |
---|
1346 | ir = new this.expandRenderer(); |
---|
1347 | } |
---|
1348 | |
---|
1349 | this._ddRendererList.push(ir); |
---|
1350 | |
---|
1351 | ir.set("owner", this); |
---|
1352 | ir.set("date", date); |
---|
1353 | ir.set("items", items); |
---|
1354 | ir.set("rowIndex", rowIndex); |
---|
1355 | ir.set("columnIndex", colIndex); |
---|
1356 | ir.set("expanded", expanded); |
---|
1357 | return ir; |
---|
1358 | }, |
---|
1359 | |
---|
1360 | _recycleExpandRenderers: function(remove){ |
---|
1361 | // tags: |
---|
1362 | // private |
---|
1363 | |
---|
1364 | for(var i=0; i<this._ddRendererList.length; i++){ |
---|
1365 | var ir = this._ddRendererList[i]; |
---|
1366 | ir.set("Up", false); |
---|
1367 | ir.set("Down", false); |
---|
1368 | if(remove){ |
---|
1369 | ir.domNode.parentNode.removeChild(ir.domNode); |
---|
1370 | } |
---|
1371 | domStyle.set(ir.domNode, "display", "none"); |
---|
1372 | } |
---|
1373 | this._ddRendererPool = this._ddRendererPool.concat(this._ddRendererList); |
---|
1374 | this._ddRendererList = []; |
---|
1375 | }, |
---|
1376 | |
---|
1377 | _defaultItemToRendererKindFunc:function(item){ |
---|
1378 | // tags: |
---|
1379 | // private |
---|
1380 | var dur = Math.abs(this.renderData.dateModule.difference(item.startTime, item.endTime, "minute")); |
---|
1381 | return dur >= 1440 ? "horizontal" : "label"; |
---|
1382 | }, |
---|
1383 | |
---|
1384 | //////////////////////////////////////////// |
---|
1385 | // |
---|
1386 | // Layout |
---|
1387 | // |
---|
1388 | /////////////////////////////////////////// |
---|
1389 | |
---|
1390 | // naturalRowHeight: Integer[] |
---|
1391 | // After an item layout has been done, contains for each row the natural height of the row. |
---|
1392 | // Ie. the height, in pixels, needed to display all the item renderers. |
---|
1393 | naturalRowsHeight: null, |
---|
1394 | |
---|
1395 | _roundItemToDay: function(item){ |
---|
1396 | // tags: |
---|
1397 | // private |
---|
1398 | |
---|
1399 | var s = item.startTime, e = item.endTime; |
---|
1400 | |
---|
1401 | if(!this.isStartOfDay(s)){ |
---|
1402 | s = this.floorToDay(s, false, this.renderData); |
---|
1403 | } |
---|
1404 | if(!this.isStartOfDay(e)){ |
---|
1405 | e = this.renderData.dateModule.add(e, "day", 1); |
---|
1406 | e = this.floorToDay(e, true); |
---|
1407 | } |
---|
1408 | return {startTime:s, endTime:e}; |
---|
1409 | }, |
---|
1410 | |
---|
1411 | _sortItemsFunction: function(a, b){ |
---|
1412 | // tags: |
---|
1413 | // private |
---|
1414 | |
---|
1415 | if(this.roundToDay){ |
---|
1416 | a = this._roundItemToDay(a); |
---|
1417 | b = this._roundItemToDay(b); |
---|
1418 | } |
---|
1419 | var res = this.dateModule.compare(a.startTime, b.startTime); |
---|
1420 | if(res == 0){ |
---|
1421 | res = -1 * this.dateModule.compare(a.endTime, b.endTime); |
---|
1422 | } |
---|
1423 | return res; |
---|
1424 | }, |
---|
1425 | |
---|
1426 | _overlapLayoutPass3: function(lanes){ |
---|
1427 | // summary: |
---|
1428 | // Third pass of the overlap layout (optional). Compute the number of lanes used by sub interval. |
---|
1429 | // lanes: Object[] |
---|
1430 | // The array of lanes. |
---|
1431 | // tags: |
---|
1432 | // private |
---|
1433 | |
---|
1434 | var pos=0, posEnd=0; |
---|
1435 | var res = []; |
---|
1436 | |
---|
1437 | var refPos = domGeometry.position(this.gridTable).x; |
---|
1438 | |
---|
1439 | for(var col=0; col<this.renderData.columnCount; col++){ |
---|
1440 | |
---|
1441 | var stop = false; |
---|
1442 | var colPos = domGeometry.position(this._getCellAt(0, col)); |
---|
1443 | pos = colPos.x - refPos; |
---|
1444 | posEnd = pos + colPos.w; |
---|
1445 | |
---|
1446 | for(var lane=lanes.length-1; lane>=0 && !stop; lane--){ |
---|
1447 | for (var i=0; i<lanes[lane].length; i++){ |
---|
1448 | var item = lanes[lane][i]; |
---|
1449 | stop = item.start < posEnd && pos < item.end; |
---|
1450 | if(stop){ |
---|
1451 | res[col] = lane + 1; |
---|
1452 | break; |
---|
1453 | } |
---|
1454 | } |
---|
1455 | } |
---|
1456 | |
---|
1457 | if(!stop){ |
---|
1458 | res[col] = 0; |
---|
1459 | } |
---|
1460 | } |
---|
1461 | |
---|
1462 | return res; |
---|
1463 | }, |
---|
1464 | |
---|
1465 | applyRendererZIndex: function(item, renderer, hovered, selected, edited, focused){ |
---|
1466 | // summary: |
---|
1467 | // Applies the z-index to the renderer based on the state of the item. |
---|
1468 | // This methods is setting a z-index of 20 is the item is selected or edited |
---|
1469 | // and the current lane value computed by the overlap layout (i.e. the renderers |
---|
1470 | // are stacked according to their lane). |
---|
1471 | // item: Object |
---|
1472 | // The render item. |
---|
1473 | // renderer: Object |
---|
1474 | // A renderer associated with the render item. |
---|
1475 | // hovered: Boolean |
---|
1476 | // Whether the item is hovered or not. |
---|
1477 | // selected: Boolean |
---|
1478 | // Whether the item is selected or not. |
---|
1479 | // edited: Boolean |
---|
1480 | // Whether the item is being edited not not. |
---|
1481 | // focused: Boolean |
---|
1482 | // Whether the item is focused not not. |
---|
1483 | // tags: |
---|
1484 | // private |
---|
1485 | |
---|
1486 | domStyle.set(renderer.container, {"zIndex": edited || selected ? renderer.renderer.mobile ? 100 : 0: item.lane == undefined ? 1 : item.lane+1}); |
---|
1487 | }, |
---|
1488 | |
---|
1489 | _layoutRenderers: function(renderData){ |
---|
1490 | // tags: |
---|
1491 | // private |
---|
1492 | if(renderData == null || renderData.items == null || renderData.rowHeight <= 0){ |
---|
1493 | return; |
---|
1494 | } |
---|
1495 | |
---|
1496 | if(!this.gridTable || this._expandAnimation != null || |
---|
1497 | (this.horizontalRenderer == null && this.labelRenderer == null)){ |
---|
1498 | this._recycleItemRenderers(); |
---|
1499 | return; |
---|
1500 | } |
---|
1501 | |
---|
1502 | this.renderData.gridTablePosX = domGeometry.position(this.gridTable).x; |
---|
1503 | this._layoutStep = renderData.columnCount; |
---|
1504 | this._recycleExpandRenderers(); |
---|
1505 | this._hiddenItems = []; |
---|
1506 | this._offsets = []; |
---|
1507 | this.naturalRowsHeight = []; |
---|
1508 | |
---|
1509 | this.inherited(arguments); |
---|
1510 | }, |
---|
1511 | |
---|
1512 | _offsets: null, |
---|
1513 | |
---|
1514 | _layoutInterval: function(/*Object*/renderData, /*Integer*/index, /*Date*/start, /*Date*/end, /*Object[]*/items){ |
---|
1515 | // tags: |
---|
1516 | // private |
---|
1517 | |
---|
1518 | if(this.renderData.cells == null){ |
---|
1519 | return; |
---|
1520 | } |
---|
1521 | var horizontalItems = []; |
---|
1522 | var labelItems = []; |
---|
1523 | |
---|
1524 | for(var i=0; i<items.length; i++){ |
---|
1525 | var item = items[i]; |
---|
1526 | var kind = this._itemToRendererKind(item); |
---|
1527 | if(kind == "horizontal"){ |
---|
1528 | horizontalItems.push(item); |
---|
1529 | }else if(kind == "label"){ |
---|
1530 | labelItems.push(item); |
---|
1531 | } |
---|
1532 | } |
---|
1533 | |
---|
1534 | var expIndex = this.getExpandedRowIndex(); |
---|
1535 | |
---|
1536 | if(expIndex != -1 && expIndex != index){ |
---|
1537 | return; // when row is expanded, layout only expanded row |
---|
1538 | } |
---|
1539 | |
---|
1540 | var offsets; |
---|
1541 | |
---|
1542 | var hiddenItems = []; |
---|
1543 | |
---|
1544 | var hItems = null; |
---|
1545 | var hOffsets = []; |
---|
1546 | if(horizontalItems.length > 0 && this.horizontalRenderer){ |
---|
1547 | var hItems = this._createHorizontalLayoutItems(index, start, end, horizontalItems); |
---|
1548 | var hOverlapLayout = this._computeHorizontalOverlapLayout(hItems, hOffsets); |
---|
1549 | } |
---|
1550 | |
---|
1551 | var lItems; |
---|
1552 | var lOffsets = []; |
---|
1553 | if(labelItems.length > 0 && this.labelRenderer){ |
---|
1554 | lItems = this._createLabelLayoutItems(index, start, end, labelItems); |
---|
1555 | this._computeLabelOffsets(lItems, lOffsets); |
---|
1556 | } |
---|
1557 | |
---|
1558 | var hasHiddenItems = this._computeColHasHiddenItems(index, hOffsets, lOffsets); |
---|
1559 | |
---|
1560 | if(hItems != null){ |
---|
1561 | this._layoutHorizontalItemsImpl(index, hItems, hOverlapLayout, hasHiddenItems, hiddenItems); |
---|
1562 | } |
---|
1563 | |
---|
1564 | if(lItems != null){ |
---|
1565 | this._layoutLabelItemsImpl(index, lItems, hasHiddenItems, hiddenItems, hOffsets); |
---|
1566 | } |
---|
1567 | |
---|
1568 | this._layoutExpandRenderers(index, hasHiddenItems, hiddenItems); |
---|
1569 | |
---|
1570 | this._hiddenItems[index] = hiddenItems; |
---|
1571 | }, |
---|
1572 | |
---|
1573 | _createHorizontalLayoutItems: function(/*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){ |
---|
1574 | // tags: |
---|
1575 | // private |
---|
1576 | |
---|
1577 | if(this.horizontalRenderer == null){ |
---|
1578 | return; |
---|
1579 | } |
---|
1580 | |
---|
1581 | var rd = this.renderData; |
---|
1582 | var cal = rd.dateModule; |
---|
1583 | var sign = rd.rtl ? -1 : 1; |
---|
1584 | var layoutItems = []; |
---|
1585 | |
---|
1586 | // step 1: compute projected position and size |
---|
1587 | for(var i = 0; i < items.length; i++){ |
---|
1588 | |
---|
1589 | var item = items[i]; |
---|
1590 | var overlap = this.computeRangeOverlap(rd, item.startTime, item.endTime, startTime, endTime); |
---|
1591 | |
---|
1592 | var startOffset = cal.difference(startTime, this.floorToDay(overlap[0], false, rd), "day"); |
---|
1593 | var dayStart = rd.dates[index][startOffset]; |
---|
1594 | |
---|
1595 | var celPos = domGeometry.position(this._getCellAt(index, startOffset, false)); |
---|
1596 | var start = celPos.x - rd.gridTablePosX; |
---|
1597 | if(rd.rtl){ |
---|
1598 | start += celPos.w; |
---|
1599 | } |
---|
1600 | |
---|
1601 | if(!this.roundToDay && !item.allDay){ |
---|
1602 | start += sign * this.computeProjectionOnDate(rd, dayStart, overlap[0], celPos.w); |
---|
1603 | } |
---|
1604 | |
---|
1605 | start = Math.ceil(start); |
---|
1606 | |
---|
1607 | var endOffset = cal.difference(startTime, this.floorToDay(overlap[1], false, rd), "day"); |
---|
1608 | |
---|
1609 | var end; |
---|
1610 | if(endOffset > rd.columnCount-1){ |
---|
1611 | celPos = domGeometry.position(this._getCellAt(index, rd.columnCount-1, false)); |
---|
1612 | if(rd.rtl){ |
---|
1613 | end = celPos.x - rd.gridTablePosX; |
---|
1614 | }else{ |
---|
1615 | end = celPos.x - rd.gridTablePosX + celPos.w; |
---|
1616 | } |
---|
1617 | }else{ |
---|
1618 | dayStart = rd.dates[index][endOffset]; |
---|
1619 | celPos = domGeometry.position(this._getCellAt(index, endOffset, false)); |
---|
1620 | end = celPos.x - rd.gridTablePosX; |
---|
1621 | |
---|
1622 | if(rd.rtl){ |
---|
1623 | end += celPos.w; |
---|
1624 | } |
---|
1625 | |
---|
1626 | if(this.roundToDay){ |
---|
1627 | if(!this.isStartOfDay(overlap[1])){ |
---|
1628 | end += sign * celPos.w; |
---|
1629 | } |
---|
1630 | }else{ |
---|
1631 | end += sign * this.computeProjectionOnDate(rd, dayStart, overlap[1], celPos.w); |
---|
1632 | } |
---|
1633 | } |
---|
1634 | |
---|
1635 | end = Math.floor(end); |
---|
1636 | |
---|
1637 | if(rd.rtl){ |
---|
1638 | var t = end; |
---|
1639 | end = start; |
---|
1640 | start = t; |
---|
1641 | } |
---|
1642 | |
---|
1643 | if(end > start){ // invalid items are not displayed |
---|
1644 | var litem = lang.mixin({ |
---|
1645 | start: start, |
---|
1646 | end: end, |
---|
1647 | range: overlap, |
---|
1648 | item: item, |
---|
1649 | startOffset: startOffset, |
---|
1650 | endOffset: endOffset |
---|
1651 | }, item); |
---|
1652 | layoutItems.push(litem); |
---|
1653 | } |
---|
1654 | } |
---|
1655 | return layoutItems; |
---|
1656 | }, |
---|
1657 | |
---|
1658 | _computeHorizontalOverlapLayout: function(layoutItems, offsets){ |
---|
1659 | // tags: |
---|
1660 | // private |
---|
1661 | |
---|
1662 | var rd = this.renderData; |
---|
1663 | var irHeight = this.horizontalRendererHeight; |
---|
1664 | var overlapLayoutRes = this.computeOverlapping(layoutItems, this._overlapLayoutPass3); |
---|
1665 | var vOverlap = this.percentOverlap / 100; |
---|
1666 | |
---|
1667 | for(var i=0; i<rd.columnCount; i++){ |
---|
1668 | var numLanes = overlapLayoutRes.addedPassRes[i]; |
---|
1669 | var index = rd.rtl ? rd.columnCount - i - 1 : i; |
---|
1670 | if(vOverlap == 0){ |
---|
1671 | offsets[index] = numLanes == 0 ? 0 : numLanes == 1 ? irHeight : irHeight + (numLanes-1) * (irHeight + this.verticalGap); |
---|
1672 | }else{ |
---|
1673 | offsets[index] = numLanes == 0 ? 0 : numLanes * irHeight - (numLanes-1) * (vOverlap * irHeight) + this.verticalGap; |
---|
1674 | } |
---|
1675 | offsets[index] += this.cellPaddingTop; |
---|
1676 | } |
---|
1677 | return overlapLayoutRes; |
---|
1678 | }, |
---|
1679 | |
---|
1680 | _createLabelLayoutItems: function(/*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){ |
---|
1681 | // tags: |
---|
1682 | // private |
---|
1683 | |
---|
1684 | if(this.labelRenderer == null){ |
---|
1685 | return; |
---|
1686 | } |
---|
1687 | |
---|
1688 | var d; |
---|
1689 | var rd = this.renderData; |
---|
1690 | var cal = rd.dateModule; |
---|
1691 | |
---|
1692 | var layoutItems = []; |
---|
1693 | |
---|
1694 | for(var i = 0; i < items.length; i++){ |
---|
1695 | var item = items[i]; |
---|
1696 | |
---|
1697 | d = this.floorToDay(item.startTime, false, rd); |
---|
1698 | |
---|
1699 | var comp = this.dateModule.compare; |
---|
1700 | |
---|
1701 | // iterate on columns overlapped by this item to create one item per column |
---|
1702 | //while(d < item.endTime && d < rd.endTime){ |
---|
1703 | while(comp(d, item.endTime) == -1 && comp(d, endTime) == -1){ |
---|
1704 | |
---|
1705 | var dayEnd = cal.add(d, "day", 1); |
---|
1706 | dayEnd = this.floorToDay(dayEnd, true); |
---|
1707 | |
---|
1708 | var overlap = this.computeRangeOverlap(rd, item.startTime, item.endTime, d, dayEnd); |
---|
1709 | var startOffset = cal.difference(startTime, this.floorToDay(overlap[0], false, rd), "day"); |
---|
1710 | |
---|
1711 | if(startOffset >= this.columnCount){ |
---|
1712 | // If the offset is greater than the column count |
---|
1713 | // the item will be processed in another row. |
---|
1714 | break; |
---|
1715 | } |
---|
1716 | |
---|
1717 | if(startOffset >= 0){ |
---|
1718 | var list = layoutItems[startOffset]; |
---|
1719 | if(list == null){ |
---|
1720 | list = []; |
---|
1721 | layoutItems[startOffset] = list; |
---|
1722 | } |
---|
1723 | |
---|
1724 | list.push(lang.mixin( |
---|
1725 | { startOffset: startOffset, |
---|
1726 | range: overlap, |
---|
1727 | item: item |
---|
1728 | }, item)); |
---|
1729 | } |
---|
1730 | |
---|
1731 | d = cal.add(d, "day", 1); |
---|
1732 | this.floorToDay(d, true); |
---|
1733 | } |
---|
1734 | } |
---|
1735 | return layoutItems; |
---|
1736 | }, |
---|
1737 | |
---|
1738 | _computeLabelOffsets: function(layoutItems, offsets){ |
---|
1739 | // tags: |
---|
1740 | // private |
---|
1741 | |
---|
1742 | for(var i=0; i<this.renderData.columnCount; i++){ |
---|
1743 | offsets[i] = layoutItems[i] == null ? 0 : layoutItems[i].length * (this.labelRendererHeight + this.verticalGap); |
---|
1744 | } |
---|
1745 | }, |
---|
1746 | |
---|
1747 | _computeColHasHiddenItems: function(index, hOffsets, lOffsets){ |
---|
1748 | // tags: |
---|
1749 | // private |
---|
1750 | |
---|
1751 | var res = []; |
---|
1752 | var cellH = this._getRowHeight(index); |
---|
1753 | var h; |
---|
1754 | var maxH = 0; |
---|
1755 | for(var i=0; i<this.renderData.columnCount; i++){ |
---|
1756 | h = hOffsets == null || hOffsets[i] == null ? this.cellPaddingTop : hOffsets[i]; |
---|
1757 | h += lOffsets == null || lOffsets[i] == null ? 0 : lOffsets[i]; |
---|
1758 | if(h > maxH){ |
---|
1759 | maxH = h; |
---|
1760 | } |
---|
1761 | res[i] = h > cellH; |
---|
1762 | } |
---|
1763 | |
---|
1764 | this.naturalRowsHeight[index] = maxH; |
---|
1765 | return res; |
---|
1766 | }, |
---|
1767 | |
---|
1768 | _layoutHorizontalItemsImpl: function(index, layoutItems, hOverlapLayout, hasHiddenItems, hiddenItems){ |
---|
1769 | |
---|
1770 | // tags: |
---|
1771 | // private |
---|
1772 | |
---|
1773 | var rd = this.renderData; |
---|
1774 | var cell = rd.cells[index]; |
---|
1775 | var cellH = this._getRowHeight(index); |
---|
1776 | var irHeight = this.horizontalRendererHeight; |
---|
1777 | var vOverlap = this.percentOverlap / 100; |
---|
1778 | |
---|
1779 | for(var i=0; i<layoutItems.length; i++){ |
---|
1780 | |
---|
1781 | var item = layoutItems[i]; |
---|
1782 | var lane = item.lane; |
---|
1783 | |
---|
1784 | var posY = this.cellPaddingTop; |
---|
1785 | |
---|
1786 | if(vOverlap == 0) { |
---|
1787 | //no overlap and a padding between each event |
---|
1788 | posY += lane * (irHeight + this.verticalGap); |
---|
1789 | } else { |
---|
1790 | // an overlap |
---|
1791 | posY += lane * (irHeight - vOverlap * irHeight); |
---|
1792 | } |
---|
1793 | |
---|
1794 | var exp = false; |
---|
1795 | var maxH = cellH; |
---|
1796 | if(this.expandRenderer){ |
---|
1797 | for(var off=item.startOffset; off<=item.endOffset; off++){ |
---|
1798 | if(hasHiddenItems[off]){ |
---|
1799 | exp = true; |
---|
1800 | break; |
---|
1801 | } |
---|
1802 | } |
---|
1803 | maxH = exp ? cellH - this.expandRendererHeight : cellH; |
---|
1804 | } |
---|
1805 | |
---|
1806 | if(posY + irHeight <= maxH){ |
---|
1807 | |
---|
1808 | var ir = this._createRenderer(item, "horizontal", this.horizontalRenderer, "dojoxCalendarHorizontal"); |
---|
1809 | |
---|
1810 | var fullHeight = this.isItemBeingEdited(item) && !this.liveLayout && this._isEditing; |
---|
1811 | var h = fullHeight ? cellH - this.cellPaddingTop : irHeight; |
---|
1812 | var w = item.end - item.start; |
---|
1813 | if (has("ie") >= 9 && item.start + w < this.itemContainer.offsetWidth) { |
---|
1814 | w++; |
---|
1815 | } |
---|
1816 | |
---|
1817 | domStyle.set(ir.container, { |
---|
1818 | "top": (fullHeight ? this.cellPaddingTop : posY) + "px", |
---|
1819 | "left": item.start + "px", |
---|
1820 | "width": w + "px", |
---|
1821 | "height": h + "px" |
---|
1822 | }); |
---|
1823 | |
---|
1824 | this._applyRendererLayout(item, ir, cell, w, h, "horizontal"); |
---|
1825 | |
---|
1826 | }else{ |
---|
1827 | // The items does not fit in view, fill hidden items per column |
---|
1828 | for(var d=item.startOffset;d<item.endOffset;d++){ |
---|
1829 | if(hiddenItems[d] == null){ |
---|
1830 | hiddenItems[d] = [item.item]; |
---|
1831 | }else{ |
---|
1832 | hiddenItems[d].push(item.item); |
---|
1833 | } |
---|
1834 | } |
---|
1835 | } |
---|
1836 | } |
---|
1837 | }, |
---|
1838 | |
---|
1839 | _layoutLabelItemsImpl: function(index, layoutItems, hasHiddenItems, hiddenItems, hOffsets){ |
---|
1840 | // tags: |
---|
1841 | // private |
---|
1842 | var list, posY; |
---|
1843 | var rd = this.renderData; |
---|
1844 | var cell = rd.cells[index]; |
---|
1845 | var cellH = this._getRowHeight(index); |
---|
1846 | var irHeight = this.labelRendererHeight; |
---|
1847 | var maxW = domGeometry.getMarginBox(this.itemContainer).w; |
---|
1848 | |
---|
1849 | for(var i=0; i<layoutItems.length; i++){ |
---|
1850 | list = layoutItems[i]; |
---|
1851 | |
---|
1852 | if(list != null){ |
---|
1853 | |
---|
1854 | var maxH = this.expandRenderer ? (hasHiddenItems[i] ? cellH - this.expandRendererHeight: cellH) : cellH; |
---|
1855 | posY = hOffsets == null || hOffsets[i] == null ? this.cellPaddingTop : hOffsets[i] + this.verticalGap; |
---|
1856 | var celPos = domGeometry.position(this._getCellAt(index, i)); |
---|
1857 | var left = celPos.x - rd.gridTablePosX; |
---|
1858 | |
---|
1859 | for(var j=0; j<list.length; j++){ |
---|
1860 | |
---|
1861 | if(posY + irHeight + this.verticalGap <= maxH){ |
---|
1862 | var item = list[j]; |
---|
1863 | |
---|
1864 | lang.mixin(item, { |
---|
1865 | start: left, |
---|
1866 | end: left + celPos.w |
---|
1867 | }); |
---|
1868 | |
---|
1869 | var ir = this._createRenderer(item, "label", this.labelRenderer, "dojoxCalendarLabel"); |
---|
1870 | |
---|
1871 | var fullHeight = this.isItemBeingEdited(item) && !this.liveLayout && this._isEditing; |
---|
1872 | var h = fullHeight ? this._getRowHeight(index) - this.cellPaddingTop : irHeight; |
---|
1873 | |
---|
1874 | if(rd.rtl){ |
---|
1875 | item.start = maxW - item.end; |
---|
1876 | item.end = item.start + celPos.w; |
---|
1877 | } |
---|
1878 | |
---|
1879 | domStyle.set(ir.container, { |
---|
1880 | "top": (fullHeight ? this.cellPaddingTop : posY) + "px", |
---|
1881 | "left": item.start + "px", |
---|
1882 | "width": celPos.w + "px", |
---|
1883 | "height": h + "px" |
---|
1884 | }); |
---|
1885 | |
---|
1886 | this._applyRendererLayout(item, ir, cell, celPos.w, h, "label"); |
---|
1887 | |
---|
1888 | }else{ |
---|
1889 | break; |
---|
1890 | } |
---|
1891 | posY += irHeight + this.verticalGap; |
---|
1892 | } |
---|
1893 | |
---|
1894 | for(var j; j<list.length; j++){ |
---|
1895 | if(hiddenItems[i] == null){ |
---|
1896 | hiddenItems[i] = [list[j]]; |
---|
1897 | }else{ |
---|
1898 | hiddenItems[i].push(list[j]); |
---|
1899 | } |
---|
1900 | } |
---|
1901 | } |
---|
1902 | } |
---|
1903 | }, |
---|
1904 | |
---|
1905 | _applyRendererLayout: function(item, ir, cell, w, h, kind){ |
---|
1906 | // tags: |
---|
1907 | // private |
---|
1908 | |
---|
1909 | var edited = this.isItemBeingEdited(item); |
---|
1910 | var selected = this.isItemSelected(item); |
---|
1911 | var hovered = this.isItemHovered(item); |
---|
1912 | var focused = this.isItemFocused(item); |
---|
1913 | |
---|
1914 | var renderer = ir.renderer; |
---|
1915 | |
---|
1916 | renderer.set("hovered", hovered); |
---|
1917 | renderer.set("selected", selected); |
---|
1918 | renderer.set("edited", edited); |
---|
1919 | renderer.set("focused", this.showFocus ? focused : false); |
---|
1920 | renderer.set("moveEnabled", this.isItemMoveEnabled(item._item, kind)); |
---|
1921 | renderer.set("storeState", this.getItemStoreState(item)); |
---|
1922 | |
---|
1923 | if(kind != "label"){ |
---|
1924 | renderer.set("resizeEnabled", this.isItemResizeEnabled(item, kind)); |
---|
1925 | } |
---|
1926 | |
---|
1927 | this.applyRendererZIndex(item, ir, hovered, selected, edited, focused); |
---|
1928 | |
---|
1929 | if(renderer.updateRendering){ |
---|
1930 | renderer.updateRendering(w, h); |
---|
1931 | } |
---|
1932 | |
---|
1933 | domConstruct.place(ir.container, cell); |
---|
1934 | domStyle.set(ir.container, "display", "block"); |
---|
1935 | }, |
---|
1936 | |
---|
1937 | _getCellAt: function(rowIndex, columnIndex, rtl){ |
---|
1938 | // tags: |
---|
1939 | // private |
---|
1940 | |
---|
1941 | if((rtl == undefined || rtl == true) && !this.isLeftToRight()){ |
---|
1942 | columnIndex = this.renderData.columnCount -1 - columnIndex; |
---|
1943 | } |
---|
1944 | return this.gridTable.childNodes[0].childNodes[rowIndex].childNodes[columnIndex]; |
---|
1945 | }, |
---|
1946 | |
---|
1947 | _layoutExpandRenderers: function(index, hasHiddenItems, hiddenItems){ |
---|
1948 | // tags: |
---|
1949 | // private |
---|
1950 | |
---|
1951 | if(!this.expandRenderer){ |
---|
1952 | return; |
---|
1953 | } |
---|
1954 | var rd = this.renderData; |
---|
1955 | if(rd.expandedRow == index){ |
---|
1956 | if(rd.expandedRowCol != null && rd.expandedRowCol != -1){ |
---|
1957 | this._layoutExpandRendererImpl(rd.expandedRow, rd.expandedRowCol, null, true); |
---|
1958 | } |
---|
1959 | }else{ |
---|
1960 | if(rd.expandedRow == null){ |
---|
1961 | for(var i=0; i<rd.columnCount; i++){ |
---|
1962 | if(hasHiddenItems[i]){ |
---|
1963 | this._layoutExpandRendererImpl(index, rd.rtl ? rd.columnCount -1 -i: i, hiddenItems[i], false); |
---|
1964 | } |
---|
1965 | } |
---|
1966 | } |
---|
1967 | } |
---|
1968 | }, |
---|
1969 | |
---|
1970 | _layoutExpandRendererImpl: function(rowIndex, colIndex, items, expanded){ |
---|
1971 | // tags: |
---|
1972 | // private |
---|
1973 | |
---|
1974 | var rd = this.renderData; |
---|
1975 | var d = lang.clone(rd.dates[rowIndex][colIndex]); |
---|
1976 | var ir = null; |
---|
1977 | var cell = rd.cells[rowIndex]; |
---|
1978 | |
---|
1979 | ir = this._getExpandRenderer(d, items, rowIndex, colIndex, expanded); |
---|
1980 | |
---|
1981 | var dim = domGeometry.position(this._getCellAt(rowIndex, colIndex)); |
---|
1982 | dim.x -= rd.gridTablePosX; |
---|
1983 | this.layoutExpandRenderer(ir, d, items, dim, this.expandRendererHeight); |
---|
1984 | domConstruct.place(ir.domNode, cell); |
---|
1985 | domStyle.set(ir.domNode, "display", "block"); |
---|
1986 | }, |
---|
1987 | |
---|
1988 | layoutExpandRenderer: function(renderer, date, items, cellPosition, height){ |
---|
1989 | // summary: |
---|
1990 | // Computes and sets the position of the expand/collapse renderers. |
---|
1991 | // By default the renderer is set to take the width of the cell and is placed at the bottom of the cell. |
---|
1992 | // The renderer DOM node is in a row that takes all the grid width. |
---|
1993 | // renderer: Object |
---|
1994 | // The renderer used in specified cell that indicates that some items cannot be displayed. |
---|
1995 | // date: Date |
---|
1996 | // The date displayed by the cell. |
---|
1997 | // items: Object[] |
---|
1998 | // The list of non visible items. |
---|
1999 | // cellPosition: Object |
---|
2000 | // An object that contains the position (x and y properties) and size of the cell (w and h properties). |
---|
2001 | // tags: |
---|
2002 | // private |
---|
2003 | domStyle.set(renderer.domNode, { |
---|
2004 | "left": cellPosition.x + "px", |
---|
2005 | "width": cellPosition.w + "px", |
---|
2006 | "height": height + "px", |
---|
2007 | "top": (cellPosition.h - height -1) + "px" |
---|
2008 | }); |
---|
2009 | }, |
---|
2010 | |
---|
2011 | ///////////////////////////////////////////// |
---|
2012 | // |
---|
2013 | // Editing |
---|
2014 | // |
---|
2015 | ////////////////////////////////////////////// |
---|
2016 | |
---|
2017 | _onItemEditBeginGesture: function(e){ |
---|
2018 | // tags: |
---|
2019 | // private |
---|
2020 | var p = this._edProps; |
---|
2021 | |
---|
2022 | var item = p.editedItem; |
---|
2023 | var dates = e.dates; |
---|
2024 | |
---|
2025 | var refTime = this.newDate(p.editKind == "resizeEnd" ? item.endTime : item.startTime); |
---|
2026 | |
---|
2027 | if(p.rendererKind == "label"){ |
---|
2028 | // noop |
---|
2029 | }else if(e.editKind == "move" && (item.allDay || this.roundToDay)){ |
---|
2030 | var cal = this.renderData.dateModule; |
---|
2031 | p.dayOffset = cal.difference( |
---|
2032 | this.floorToDay(dates[0], false, this.renderData), |
---|
2033 | refTime, "day"); |
---|
2034 | } // else managed in super |
---|
2035 | |
---|
2036 | this.inherited(arguments); |
---|
2037 | }, |
---|
2038 | |
---|
2039 | _computeItemEditingTimes: function(item, editKind, rendererKind, times, eventSource){ |
---|
2040 | // tags: |
---|
2041 | // private |
---|
2042 | var cal = this.renderData.dateModule; |
---|
2043 | var p = this._edProps; |
---|
2044 | |
---|
2045 | if(rendererKind == "label"){ // noop |
---|
2046 | }else if(item.allDay || this.roundToDay){ |
---|
2047 | var isStartOfDay = this.isStartOfDay(times[0]); |
---|
2048 | switch(editKind){ |
---|
2049 | case "resizeEnd": |
---|
2050 | if(!isStartOfDay && item.allDay){ |
---|
2051 | times[0] = cal.add(times[0], "day", 1); // no break; |
---|
2052 | } |
---|
2053 | case "resizeStart": |
---|
2054 | if(!isStartOfDay){ |
---|
2055 | times[0] = this.floorToDay(times[0], true); |
---|
2056 | } |
---|
2057 | break; |
---|
2058 | case "move": |
---|
2059 | times[0] = cal.add(times[0], "day", p.dayOffset); |
---|
2060 | break; |
---|
2061 | case "resizeBoth": |
---|
2062 | if(!isStartOfDay){ |
---|
2063 | times[0] = this.floorToDay(times[0], true); |
---|
2064 | } |
---|
2065 | if(!this.isStartOfDay(times[1])){ |
---|
2066 | times[1] = this.floorToDay(cal.add(times[1], "day", 1), true); |
---|
2067 | } |
---|
2068 | break; |
---|
2069 | } |
---|
2070 | |
---|
2071 | }else{ |
---|
2072 | times = this.inherited(arguments); |
---|
2073 | } |
---|
2074 | |
---|
2075 | return times; |
---|
2076 | }, |
---|
2077 | |
---|
2078 | |
---|
2079 | ///////////////////////////////////////////// |
---|
2080 | // |
---|
2081 | // Pixel to Time projection |
---|
2082 | // |
---|
2083 | ////////////////////////////////////////////// |
---|
2084 | |
---|
2085 | getTime: function(e, x, y, touchIndex){ |
---|
2086 | // summary: |
---|
2087 | // Returns the time displayed at the specified point by this component. |
---|
2088 | // e: Event |
---|
2089 | // Optional mouse event. |
---|
2090 | // x: Number |
---|
2091 | // Position along the x-axis with respect to the sheet container used if event is not defined. |
---|
2092 | // y: Number |
---|
2093 | // Position along the y-axis with respect to the sheet container (scroll included) used if event is not defined. |
---|
2094 | // touchIndex: Integer |
---|
2095 | // If parameter 'e' is not null and a touch event, the index of the touch to use. |
---|
2096 | // returns: Date |
---|
2097 | |
---|
2098 | var rd = this.renderData; |
---|
2099 | |
---|
2100 | if(e != null){ |
---|
2101 | var refPos = domGeometry.position(this.itemContainer, true); |
---|
2102 | |
---|
2103 | if(e.touches){ |
---|
2104 | |
---|
2105 | touchIndex = touchIndex==undefined ? 0 : touchIndex; |
---|
2106 | |
---|
2107 | x = e.touches[touchIndex].pageX - refPos.x; |
---|
2108 | y = e.touches[touchIndex].pageY - refPos.y; |
---|
2109 | |
---|
2110 | }else{ |
---|
2111 | |
---|
2112 | x = e.pageX - refPos.x; |
---|
2113 | y = e.pageY - refPos.y; |
---|
2114 | } |
---|
2115 | } |
---|
2116 | |
---|
2117 | var r = domGeometry.getContentBox(this.itemContainer); |
---|
2118 | |
---|
2119 | if(x < 0){ |
---|
2120 | x = 0; |
---|
2121 | }else if(x > r.w){ |
---|
2122 | x = r.w-1; |
---|
2123 | } |
---|
2124 | |
---|
2125 | if(y < 0){ |
---|
2126 | y = 0; |
---|
2127 | }else if(y > r.h){ |
---|
2128 | y = r.h-1; |
---|
2129 | } |
---|
2130 | |
---|
2131 | // compute the date from column the time in day instead of time from start date of row to prevent DST hour offset. |
---|
2132 | |
---|
2133 | var w = domGeometry.getMarginBox(this.itemContainer).w; |
---|
2134 | var colW = w / rd.columnCount; |
---|
2135 | |
---|
2136 | var row; |
---|
2137 | if(rd.expandedRow == null){ |
---|
2138 | row = Math.floor(y / (domGeometry.getMarginBox(this.itemContainer).h / rd.rowCount)); |
---|
2139 | }else{ |
---|
2140 | row = rd.expandedRow; //other rows are not usable |
---|
2141 | } |
---|
2142 | |
---|
2143 | var r = domGeometry.getContentBox(this.itemContainer); |
---|
2144 | |
---|
2145 | if(rd.rtl){ |
---|
2146 | x = r.w - x; |
---|
2147 | } |
---|
2148 | |
---|
2149 | var col = Math.floor(x / colW); |
---|
2150 | |
---|
2151 | var tm = Math.floor((x-(col*colW)) * 1440 / colW); |
---|
2152 | |
---|
2153 | var date = null; |
---|
2154 | if(row < rd.dates.length && col < this.renderData.dates[row].length){ |
---|
2155 | date = this.newDate(this.renderData.dates[row][col]); |
---|
2156 | date = this.renderData.dateModule.add(date, "minute", tm); |
---|
2157 | } |
---|
2158 | |
---|
2159 | return date; |
---|
2160 | }, |
---|
2161 | |
---|
2162 | ///////////////////////////////////////////// |
---|
2163 | // |
---|
2164 | // Event management |
---|
2165 | // |
---|
2166 | ////////////////////////////////////////////// |
---|
2167 | |
---|
2168 | _onGridMouseUp: function(e){ |
---|
2169 | // tags: |
---|
2170 | // private |
---|
2171 | |
---|
2172 | this.inherited(arguments); |
---|
2173 | |
---|
2174 | if(this._gridMouseDown){ |
---|
2175 | this._gridMouseDown = false; |
---|
2176 | |
---|
2177 | this._onGridClick({ |
---|
2178 | date: this.getTime(e), |
---|
2179 | triggerEvent: e |
---|
2180 | }); |
---|
2181 | } |
---|
2182 | }, |
---|
2183 | |
---|
2184 | _onGridTouchEnd: function(e){ |
---|
2185 | // tags: |
---|
2186 | // private |
---|
2187 | this.inherited(arguments); |
---|
2188 | |
---|
2189 | var g = this._gridProps; |
---|
2190 | |
---|
2191 | if(g){ |
---|
2192 | |
---|
2193 | if(!this._isEditing){ |
---|
2194 | |
---|
2195 | // touched on grid and on touch start editing was ongoing. |
---|
2196 | if(!g.fromItem && !g.editingOnStart){ |
---|
2197 | this.selectFromEvent(e, null, null, true); |
---|
2198 | } |
---|
2199 | |
---|
2200 | if(!g.fromItem){ |
---|
2201 | |
---|
2202 | if(this._pendingDoubleTap && this._pendingDoubleTap.grid){ |
---|
2203 | |
---|
2204 | this._onGridDoubleClick({ |
---|
2205 | date: this.getTime(this._gridProps.event), |
---|
2206 | triggerEvent: this._gridProps.event |
---|
2207 | }); |
---|
2208 | |
---|
2209 | clearTimeout(this._pendingDoubleTap.timer); |
---|
2210 | |
---|
2211 | delete this._pendingDoubleTap; |
---|
2212 | |
---|
2213 | }else{ |
---|
2214 | |
---|
2215 | this._onGridClick({ |
---|
2216 | date: this.getTime(this._gridProps.event), |
---|
2217 | triggerEvent: this._gridProps.event |
---|
2218 | }); |
---|
2219 | |
---|
2220 | this._pendingDoubleTap = { |
---|
2221 | grid: true, |
---|
2222 | timer: setTimeout(lang.hitch(this, function(){ |
---|
2223 | delete this._pendingDoubleTap; |
---|
2224 | }), this.doubleTapDelay) |
---|
2225 | }; |
---|
2226 | } |
---|
2227 | } |
---|
2228 | } |
---|
2229 | |
---|
2230 | this._gridProps = null; |
---|
2231 | } |
---|
2232 | }, |
---|
2233 | |
---|
2234 | |
---|
2235 | ///////////////////////////////////////////// |
---|
2236 | // |
---|
2237 | // Events |
---|
2238 | // |
---|
2239 | ////////////////////////////////////////////// |
---|
2240 | |
---|
2241 | _onRowHeaderClick: function(e){ |
---|
2242 | this._dispatchCalendarEvt(e, "onRowHeaderClick"); |
---|
2243 | // tags: |
---|
2244 | // private |
---|
2245 | }, |
---|
2246 | |
---|
2247 | onRowHeaderClick: function(e){ |
---|
2248 | // summary: |
---|
2249 | // Event dispatched when a row header cell is clicked. |
---|
2250 | // e: __HeaderClickEventArgs |
---|
2251 | // Header click event. |
---|
2252 | // tags: |
---|
2253 | // callback |
---|
2254 | }, |
---|
2255 | |
---|
2256 | expandRendererClickHandler: function(e, renderer){ |
---|
2257 | // summary: |
---|
2258 | // Default action when an expand renderer is clicked. |
---|
2259 | // e: Event |
---|
2260 | // The mouse event. |
---|
2261 | // renderer: Object |
---|
2262 | // The expand renderer. |
---|
2263 | // tags: |
---|
2264 | // protected |
---|
2265 | |
---|
2266 | event.stop(e); |
---|
2267 | |
---|
2268 | var ri = renderer.get("rowIndex"); |
---|
2269 | var ci = renderer.get("columnIndex"); |
---|
2270 | |
---|
2271 | this._onExpandRendererClick(lang.mixin(this._createItemEditEvent(), { |
---|
2272 | rowIndex: ri, |
---|
2273 | columnIndex: ci, |
---|
2274 | renderer: renderer, |
---|
2275 | triggerEvent: e, |
---|
2276 | date: this.renderData.dates[ri][ci] |
---|
2277 | })); |
---|
2278 | }, |
---|
2279 | |
---|
2280 | onExpandRendererClick: function(e){ |
---|
2281 | // summary: |
---|
2282 | // Event dispatched when an expand renderer is clicked. |
---|
2283 | // e: __ExpandRendererClickEventArgs |
---|
2284 | // Expand renderer click event. |
---|
2285 | // tags: |
---|
2286 | // callback |
---|
2287 | }, |
---|
2288 | |
---|
2289 | _onExpandRendererClick: function(e){ |
---|
2290 | |
---|
2291 | this._dispatchCalendarEvt(e, "onExpandRendererClick"); |
---|
2292 | |
---|
2293 | if(!e.isDefaultPrevented()){ |
---|
2294 | |
---|
2295 | if(this.getExpandedRowIndex() != -1){ |
---|
2296 | this.collapseRow(); |
---|
2297 | }else{ |
---|
2298 | this.expandRow(e.rowIndex, e.columnIndex); |
---|
2299 | } |
---|
2300 | } |
---|
2301 | }, |
---|
2302 | |
---|
2303 | |
---|
2304 | //////////////////////////////////////////// |
---|
2305 | // |
---|
2306 | // Editing |
---|
2307 | // |
---|
2308 | /////////////////////////////////////////// |
---|
2309 | |
---|
2310 | snapUnit: "minute", |
---|
2311 | snapSteps: 15, |
---|
2312 | minDurationUnit: "minute", |
---|
2313 | minDurationSteps: 15, |
---|
2314 | triggerExtent: 3, |
---|
2315 | liveLayout: false, |
---|
2316 | stayInView: true, |
---|
2317 | allowStartEndSwap: true, |
---|
2318 | allowResizeLessThan24H: false |
---|
2319 | |
---|
2320 | }); |
---|
2321 | }); |
---|