wice_grid 3.0.4 → 3.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/CHANGELOG +24 -2
  2. data/README.rdoc +282 -316
  3. data/RELEASE_NOTES_3.2.pre1.rdoc +82 -0
  4. data/Rakefile +4 -2
  5. data/SAVED_QUERIES_HOWTO.rdoc +18 -31
  6. data/VERSION +1 -1
  7. data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +22 -0
  8. data/lib/generators/wice_grid/install_generator.rb +20 -0
  9. data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +13 -0
  10. data/lib/generators/wice_grid/templates/wice_grid.css.scss +139 -0
  11. data/lib/generators/wice_grid/templates/wice_grid.yml +113 -19
  12. data/lib/generators/wice_grid/templates/wice_grid_config.rb +17 -41
  13. data/lib/grid_output_buffer.rb +3 -2
  14. data/lib/grid_renderer.rb +63 -102
  15. data/lib/helpers/js_calendar_helpers.rb +27 -157
  16. data/lib/helpers/wice_grid_misc_view_helpers.rb +1 -66
  17. data/lib/helpers/wice_grid_serialized_queries_view_helpers.rb +41 -32
  18. data/lib/helpers/wice_grid_view_helpers.rb +138 -274
  19. data/lib/table_column_matrix.rb +11 -11
  20. data/lib/view_columns.rb +41 -350
  21. data/lib/view_columns/action_view_column.rb +45 -0
  22. data/lib/view_columns/column_processor_index.rb +16 -0
  23. data/lib/view_columns/view_column_boolean.rb +23 -0
  24. data/lib/view_columns/view_column_custom_dropdown.rb +81 -0
  25. data/lib/view_columns/view_column_date.rb +17 -0
  26. data/lib/view_columns/view_column_datetime.rb +85 -0
  27. data/lib/view_columns/view_column_float.rb +7 -0
  28. data/lib/view_columns/view_column_integer.rb +38 -0
  29. data/lib/view_columns/view_column_string.rb +63 -0
  30. data/lib/wice_grid.rb +23 -26
  31. data/lib/wice_grid_controller.rb +14 -15
  32. data/lib/wice_grid_misc.rb +3 -3
  33. data/lib/wice_grid_serialized_queries_controller.rb +15 -18
  34. data/lib/wice_grid_spreadsheet.rb +2 -2
  35. data/lib/will_paginate_paginator.rb +31 -0
  36. data/test/readme.txt +1 -0
  37. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/arrow_down.gif +0 -0
  38. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/arrow_up.gif +0 -0
  39. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/calendar_view_month.png +0 -0
  40. data/vendor/assets/images/icons/grid/collapse.gif +0 -0
  41. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/delete.png +0 -0
  42. data/vendor/assets/images/icons/grid/expand.gif +0 -0
  43. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/page_white_excel.png +0 -0
  44. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/page_white_find.png +0 -0
  45. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/table.png +0 -0
  46. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/table_refresh.png +0 -0
  47. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/tick_all.png +0 -0
  48. data/{lib/generators/wice_grid/templates/icons → vendor/assets/images/icons/grid}/untick_all.png +0 -0
  49. data/vendor/assets/javascripts/wice_grid.js +3 -0
  50. data/vendor/assets/javascripts/wice_grid_init.js.coffee +247 -0
  51. data/vendor/assets/javascripts/wice_grid_processor.js.coffee +128 -0
  52. data/vendor/assets/javascripts/wice_grid_saved_queries_init.js.coffee +103 -0
  53. data/wice_grid.gemspec +44 -50
  54. metadata +68 -94
  55. data/lib/generators/wice_grid/templates/calendarview.css +0 -107
  56. data/lib/generators/wice_grid/templates/calendarview.js +0 -1168
  57. data/lib/generators/wice_grid/templates/icons/expand.png +0 -0
  58. data/lib/generators/wice_grid/templates/wice_grid.css +0 -173
  59. data/lib/generators/wice_grid/templates/wice_grid_jquery.js +0 -162
  60. data/lib/generators/wice_grid/templates/wice_grid_prototype.js +0 -154
  61. data/lib/generators/wice_grid/wice_grid_assets_jquery_generator.rb +0 -32
  62. data/lib/generators/wice_grid/wice_grid_assets_prototype_generator.rb +0 -34
  63. data/lib/js_adaptors/jquery_adaptor.rb +0 -157
  64. data/lib/js_adaptors/js_adaptor.rb +0 -12
  65. data/lib/js_adaptors/prototype_adaptor.rb +0 -179
  66. data/lib/tasks/wice_grid_tasks.rake +0 -28
  67. data/lib/views/create.rjs +0 -13
  68. data/lib/views/create_jq.rjs +0 -31
  69. data/lib/views/delete.rjs +0 -12
  70. data/lib/views/delete_jq.rjs +0 -26
  71. data/test/.gitignore +0 -2
  72. data/test/database.yml +0 -21
  73. data/test/schema.rb +0 -33
  74. data/test/test_helper.rb +0 -89
  75. data/test/views/projects_and_people_grid.html.erb +0 -12
  76. data/test/views/projects_and_people_grid_invalid.html.erb +0 -12
  77. data/test/views/simple_projects_grid.html.erb +0 -9
  78. data/test/wice_grid_core_ext_test.rb +0 -183
  79. data/test/wice_grid_functional_test.rb +0 -68
  80. data/test/wice_grid_misc_test.rb +0 -41
  81. data/test/wice_grid_test.rb +0 -42
  82. data/test/wice_grid_view_helper_test.rb +0 -12
@@ -1,107 +0,0 @@
1
-
2
- div.calendar
3
- {
4
- font-size: smaller;
5
- color: #000;
6
- z-index: 5;
7
- }
8
-
9
- div.calendar.popup
10
- {
11
- margin-left: -40px;
12
- margin-top: -100px;
13
- }
14
-
15
- div.calendar table
16
- {
17
- background-color: #eee;
18
- border: 1px solid #aaa;
19
- border-collapse: collapse;
20
- }
21
-
22
- div.calendar thead {
23
- background-color: white;
24
- }
25
-
26
- div.calendar td,
27
- div.calendar th
28
- {
29
- padding: 3px;
30
- text-align: center;
31
- }
32
-
33
- div.calendar td.title
34
- {
35
- font-weight: bold;
36
- }
37
-
38
- div.calendar th
39
- {
40
- background: #ddd;
41
- border-bottom: 1px solid #ccc;
42
- border-top: 1px solid #ccc;
43
- font-weight: bold;
44
- color: #555;
45
- }
46
-
47
- div.calendar tr.days td {
48
- width: 2em;
49
- color: #555;
50
- text-align: center;
51
- cursor: pointer;
52
- }
53
-
54
- div.calendar tr.days td:hover,
55
- div.calendar td.cvbutton:hover
56
- {
57
- background-color: #34ABFA;
58
- cursor: pointer;
59
- }
60
-
61
-
62
- div.calendar tr td.closeButton:hover
63
- {
64
- background-color: #34ABFA;
65
- cursor: pointer;
66
- }
67
-
68
-
69
- div.calendar tr.days td:active
70
- div.calendar td.cvbutton:active
71
- {
72
- background-color: #cde;
73
- }
74
-
75
- div.calendar tr.days td.selected
76
- {
77
- font-weight: bold;
78
- background-color: #fff;
79
- color: #000;
80
- }
81
-
82
- div.calendar tr.days td.today
83
- {
84
- font-weight: bold;
85
- color: #D50000;
86
- }
87
-
88
- div.calendar tr.days td.otherDay
89
- {
90
- color: #bbb;
91
- }
92
-
93
- div.calendar .draggableHandler{
94
- cursor: move;
95
- }
96
-
97
- /* styles for the date_picker Rails plugin */
98
- span.date_picker a.date_label{
99
- margin-left: 5px;
100
- margin-right: 5px;
101
- text-decoration: none;
102
- }
103
- span.date_picker a.date_label:hover{text-decoration: line-through;}
104
-
105
- span.date_picker span.trigger:hover{
106
- cursor: pointer;
107
- }
@@ -1,1168 +0,0 @@
1
- //
2
- // CalendarView (for Prototype)
3
- // calendarview.org
4
- //
5
- // Maintained by Justin Mecham <justin@aspect.net>
6
- //
7
- // Portions Copyright 2002-2005 Mihai Bazon
8
- //
9
- // This calendar is based very loosely on the Dynarch Calendar in that it was
10
- // used as a base, but completely gutted and more or less rewritten in place
11
- // to use the Prototype JavaScript library.
12
- //
13
- // As such, CalendarView is licensed under the terms of the GNU Lesser General
14
- // Public License (LGPL). More information on the Dynarch Calendar can be
15
- // found at:
16
- //
17
- // www.dynarch.com/projects/calendar
18
- //
19
-
20
-
21
- /* This fork by Yuri Leikind ( git://github.com/leikind/calendarview.git ) adds a number of features.
22
-
23
- The differences from the original are
24
-
25
- * Support for time in the form of two dropdowns for hours and minutes. Can be turned off/on.
26
- * Draggable popup calendars (which introduces new dependancies: script.aculo.us effects.js and dragdrop.js)
27
- * Close button
28
- * Ability to unset the date by clicking on the active date
29
- * Simple I18n support
30
- * Removed all ambiguity in the API
31
- * Two strategies in positioning of popup calendars: relative to the popup trigger element (original behavior),
32
- and is relative to the mouse pointer (can be configured)
33
- * Popup calendars are not created every time they pop up, on the contrary, they are created once just like
34
- embedded calendars, and then shown or hidden.
35
- * Possible to have many popup calendars on page. The behavior of the original calendarview when a popup
36
- calendar is hidden when the user clicks elsewhere on the page is an option now.
37
- * Refactoring and changes to the OO design like getting rid of Calendar.prototype in favor of class based
38
- OO provided by OO, and getting rid of Calendar.setup({}) in favor of a simple object constructor new Calendar({}).
39
-
40
- */
41
-
42
- var Calendar = Class.create({
43
-
44
- container: null,
45
-
46
- minYear: 1900,
47
- maxYear: 2100,
48
-
49
- date: new Date(),
50
- currentDateElement: null,
51
-
52
- shouldClose: false,
53
- isPopup: true,
54
-
55
- initialize: function(params){
56
-
57
- if (! Calendar.init_done){
58
- Calendar.init();
59
- }
60
-
61
- embedAt = params.embedAt || null;
62
- withTime = params.withTime || null;
63
- dateFormat = params.dateFormat || null;
64
- initialDate = params.initialDate || null;
65
- popupTriggerElement = params.popupTriggerElement || null;
66
- this.onHideCallback = params.onHideCallback || function(date, calendar){};
67
- this.onDateChangedCallback = params.onDateChangedCallback || function(date, calendar){};
68
- this.minuteStep = params.minuteStep || 5;
69
- this.hideOnClickOnDay = params.hideOnClickOnDay || false;
70
- this.hideOnClickElsewhere = params.hideOnClickElsewhere || false;
71
- this.outputFields = params.outputFields || $A();
72
- this.popupPositioningStrategy = params.popupPositioningStrategy || 'trigger'; // or 'pointer'
73
- this.x = params.x || 0;
74
- this.y = params.y || 0.6;
75
-
76
- this.outputFields = $A(this.outputFields).collect(function(f){
77
- return $(f);
78
- });
79
-
80
- if (embedAt){
81
- this.embedAt = $(embedAt);
82
- this.embedAt._calendar = this;
83
- }else{
84
- this.embedAt = null;
85
- }
86
-
87
- this.withTime = withTime;
88
-
89
- if (dateFormat){
90
- this.dateFormat = dateFormat;
91
- }else{
92
- if(this.withTime){
93
- this.dateFormat = Calendar.defaultDateTimeFormat;
94
- }else{
95
- this.dateFormat = Calendar.defaultDateFormat;
96
- }
97
- }
98
-
99
- this.dateFormatForHiddenField = params.dateFormatForHiddenField || this.dateFormat;
100
-
101
-
102
- if (initialDate) {
103
- this.date = this.parseDate(initialDate);
104
- }
105
-
106
- this.build();
107
-
108
- if (this.isPopup) { //Popup Calendars
109
- var popupTriggerElement = $(popupTriggerElement);
110
- popupTriggerElement._calendar = this;
111
-
112
- popupTriggerElement.observe('click', function(event){
113
- this.showAtElement(event, popupTriggerElement);
114
- }.bind(this) );
115
-
116
- } else{ // In-Page Calendar
117
- this.show();
118
- }
119
-
120
- if (params.updateOuterFieldsOnInit){
121
- this.updateOuterFieldWithoutCallback(); // Just for the sake of localization and DatePicker
122
- }
123
- },
124
-
125
- build: function(){
126
- if (this.embedAt) {
127
- var parentForCalendarTable = this.embedAt;
128
- this.isPopup = false;
129
- } else {
130
- var parentForCalendarTable = document.getElementsByTagName('body')[0];
131
- this.isPopup = true;
132
- }
133
-
134
-
135
- var table = new Element('table');
136
-
137
- var thead = new Element('thead');
138
- table.appendChild(thead);
139
-
140
- var firstRow = new Element('tr');
141
-
142
- if (this.isPopup){
143
- var cell = new Element('td');
144
- cell.addClassName('draggableHandler');
145
- firstRow.appendChild(cell);
146
-
147
- cell = new Element('td', { colSpan: 5 });
148
- cell.addClassName('title' );
149
- cell.addClassName('draggableHandler');
150
- firstRow.appendChild(cell);
151
-
152
- cell = new Element('td');
153
- cell.addClassName('closeButton');
154
- firstRow.appendChild(cell);
155
- cell.update('x');
156
-
157
- cell.observe('mousedown', function(){
158
- this.hide();
159
- }.bind(this));
160
-
161
-
162
- }else{
163
- var cell = new Element('td', { colSpan: 7 } );
164
- firstRow.appendChild(cell);
165
- }
166
-
167
- cell.addClassName('title');
168
-
169
- thead.appendChild(firstRow);
170
-
171
- var row = new Element('tr')
172
- this._drawButtonCell(row, '&#x00ab;', 1, Calendar.NAV_PREVIOUS_YEAR);
173
- this._drawButtonCell(row, '&#x2039;', 1, Calendar.NAV_PREVIOUS_MONTH);
174
- this._drawButtonCell(row, Calendar.getMessageFor('today'), 3, Calendar.NAV_TODAY);
175
- this._drawButtonCell(row, '&#x203a;', 1, Calendar.NAV_NEXT_MONTH);
176
- this._drawButtonCell(row, '&#x00bb;', 1, Calendar.NAV_NEXT_YEAR);
177
- thead.appendChild(row)
178
-
179
- // Day Names
180
- row = new Element('tr');
181
- for (var i = 0; i < 7; ++i) {
182
- cell = new Element('th').update(Calendar.SHORT_DAY_NAMES[i]);
183
- if (i == 0 || i == 6){
184
- cell.addClassName('weekend');
185
- }
186
- row.appendChild(cell);
187
- }
188
- thead.appendChild(row);
189
-
190
- // Calendar Days
191
- var tbody = table.appendChild(new Element('tbody'));
192
- for (i = 6; i > 0; --i) {
193
- row = tbody.appendChild(new Element('tr'));
194
- row.addClassName('days');
195
- for (var j = 7; j > 0; --j) {
196
- cell = row.appendChild(new Element('td'));
197
- cell.calendar = this;
198
- }
199
- }
200
-
201
- // Time Placeholder
202
- if (this.withTime){
203
- var tfoot = table.appendChild(new Element('tfoot'));
204
- row = tfoot.appendChild(new Element('tr'));
205
- cell = row.appendChild(new Element('td', { colSpan: 7 }));
206
- cell.addClassName('time');
207
- var hourSelect = cell.appendChild(new Element('select', { name : 'hourSelect'}));
208
- for (var i = 0; i < 24; i++) {
209
- hourSelect.appendChild(new Element('option', {value : i}).update(i));
210
- }
211
- this.hourSelect = hourSelect;
212
-
213
- cell.appendChild(new Element('span')).update(' : ');
214
-
215
- var minuteSelect = cell.appendChild(new Element('select', { name : 'minuteSelect'}));
216
- for (var i = 0; i < 60; i += this.minuteStep) {
217
- minuteSelect.appendChild(new Element('option', {value : i}).update(i));
218
- }
219
- this.minuteSelect = minuteSelect;
220
-
221
- hourSelect.observe('change', function(event){
222
- if (! this.date) return;
223
- var elem = event.element();
224
- var selectedIndex = elem.selectedIndex;
225
- if ((typeof selectedIndex != 'undefined') && selectedIndex != null){
226
- this.date.setHours(elem.options[selectedIndex].value);
227
- this.updateOuterField();
228
- }
229
- }.bind(this));
230
-
231
- minuteSelect.observe('change', function(event){
232
- if (! this.date) return;
233
- var elem = event.element();
234
- var selectedIndex = elem.selectedIndex;
235
- if ((typeof selectedIndex != 'undefined') && selectedIndex != null){
236
- this.date.setMinutes(elem.options[selectedIndex].value);
237
- this.updateOuterField();
238
- }
239
- }.bind(this))
240
- }
241
-
242
- // Calendar Container (div)
243
- this.container = new Element('div');
244
- this.container.addClassName('calendar');
245
- if (this.isPopup) {
246
- this.container.setStyle({ position: 'absolute', display: 'none' });
247
- this.container.addClassName('popup');
248
- }
249
- this.container.appendChild(table);
250
-
251
- this.update(this.date);
252
-
253
- Event.observe(this.container, 'mousedown', Calendar.handleMouseDownEvent);
254
-
255
- parentForCalendarTable.appendChild(this.container);
256
-
257
- if (this.isPopup){
258
- new Draggable(table, {handle : firstRow });
259
- }
260
- },
261
-
262
- updateOuterFieldReal: function(element){
263
- if (element.tagName == 'DIV' || element.tagName == 'SPAN') {
264
- formatted = this.date ? this.date.print(this.dateFormat) : '';
265
- element.update(formatted);
266
- } else if (element.tagName == 'INPUT') {
267
- formatted = this.date ? this.date.print(this.dateFormatForHiddenField) : '';
268
- element.value = formatted;
269
- }
270
- },
271
-
272
- updateOuterFieldWithoutCallback: function(){
273
- this.outputFields.each(function(field){
274
- this.updateOuterFieldReal(field);
275
- }.bind(this));
276
- },
277
-
278
- updateOuterField: function(){
279
- this.updateOuterFieldWithoutCallback();
280
- this.onDateChangedCallback(this.date, this);
281
- },
282
-
283
- viewOutputFields: function(){
284
- return this.outputFields.findAll(function(element){
285
- if (element.tagName == 'DIV' || element.tagName == 'SPAN'){
286
- return true;
287
- }else{
288
- return false;
289
- }
290
- });
291
- },
292
-
293
-
294
- //----------------------------------------------------------------------------
295
- // Update Calendar
296
- //----------------------------------------------------------------------------
297
-
298
- update: function(date) {
299
-
300
- var today = new Date();
301
- var thisYear = today.getFullYear();
302
- var thisMonth = today.getMonth();
303
- var thisDay = today.getDate();
304
- var month = date.getMonth();
305
- var dayOfMonth = date.getDate();
306
- var hour = date.getHours();
307
- var minute = date.getMinutes();
308
-
309
- // Ensure date is within the defined range
310
- if (date.getFullYear() < this.minYear)
311
- date.__setFullYear(this.minYear);
312
- else if (date.getFullYear() > this.maxYear)
313
- date.__setFullYear(this.maxYear);
314
-
315
- if (this.isBackedUp()){
316
- this.dateBackedUp = new Date(date);
317
- }else{
318
- this.date = new Date(date);
319
- }
320
-
321
- // Calculate the first day to display (including the previous month)
322
- date.setDate(1)
323
- date.setDate(-(date.getDay()) + 1)
324
-
325
- // Fill in the days of the month
326
- Element.getElementsBySelector(this.container, 'tbody tr').each(
327
- function(row, i) {
328
- var rowHasDays = false;
329
- row.immediateDescendants().each(
330
- function(cell, j) {
331
- var day = date.getDate();
332
- var dayOfWeek = date.getDay();
333
- var isCurrentMonth = (date.getMonth() == month);
334
-
335
- // Reset classes on the cell
336
- cell.className = '';
337
- cell.date = new Date(date);
338
- cell.update(day);
339
-
340
- // Account for days of the month other than the current month
341
- if (!isCurrentMonth)
342
- cell.addClassName('otherDay');
343
- else
344
- rowHasDays = true;
345
-
346
- // Ensure the current day is selected
347
- if ((! this.isBackedUp()) && isCurrentMonth && day == dayOfMonth) {
348
- cell.addClassName('selected');
349
- this.currentDateElement = cell;
350
- }
351
-
352
- // Today
353
- if (date.getFullYear() == thisYear && date.getMonth() == thisMonth && day == thisDay)
354
- cell.addClassName('today');
355
-
356
- // Weekend
357
- if ([0, 6].indexOf(dayOfWeek) != -1)
358
- cell.addClassName('weekend');
359
-
360
- // Set the date to tommorrow
361
- date.setDate(day + 1);
362
- }.bind(this)
363
- )
364
- // Hide the extra row if it contains only days from another month
365
- !rowHasDays ? row.hide() : row.show();
366
- }.bind(this)
367
- )
368
-
369
- Element.getElementsBySelector(this.container, 'tfoot tr td select').each(
370
- function(sel){
371
- if(sel.name == 'hourSelect'){
372
- sel.selectedIndex = hour;
373
- }else if(sel.name == 'minuteSelect'){
374
- if (this.minuteStep == 1){
375
- sel.selectedIndex = minute;
376
- }else{
377
- sel.selectedIndex = this.findClosestMinute(minute);
378
- }
379
- }
380
- }.bind(this)
381
- )
382
-
383
- this.container.getElementsBySelector('td.title')[0].update(
384
- Calendar.MONTH_NAMES[month] + ' ' + this.dateOrDateBackedUp().getFullYear()
385
- )
386
-
387
- },
388
-
389
-
390
- findClosestMinute: function(val){
391
- if (val == 0){
392
- return 0;
393
- }
394
- var lowest = ((val / this.minuteStep).floor() * this.minuteStep);
395
- var distance = val % this.minuteStep;
396
- var minuteValueToShow;
397
-
398
- if (distance <= (this.minuteStep / 2)){
399
- minuteValueToShow = lowest;
400
- }else{
401
- minuteValueToShow = lowest + this.minuteStep;
402
- }
403
-
404
- if (minuteValueToShow == 0){
405
- return minuteValueToShow;
406
- }else if(minuteValueToShow >= 60){
407
- return (minuteValueToShow / this.minuteStep).floor() - 1;
408
- }else{
409
- return minuteValueToShow / this.minuteStep;
410
- }
411
- },
412
-
413
- _drawButtonCell: function(parentForCell, text, colSpan, navAction) {
414
- var cell = new Element('td');
415
- if (colSpan > 1) cell.colSpan = colSpan;
416
- cell.className = 'cvbutton';
417
- cell.calendar = this;
418
- cell.navAction = navAction;
419
- cell.innerHTML = text;
420
- cell.unselectable = 'on'; // IE
421
- parentForCell.appendChild(cell);
422
- return cell;
423
- },
424
-
425
-
426
- //------------------------------------------------------------------------------
427
- // Calendar Display Functions
428
- //------------------------------------------------------------------------------
429
-
430
- show: function(){
431
- this.container.show();
432
- if (this.isPopup) {
433
- if (this.hideOnClickElsewhere){
434
- window._popupCalendar = this;
435
- document.observe('mousedown', Calendar._checkCalendar);
436
- }
437
- }
438
- },
439
-
440
- showAt: function (x, y) {
441
- this.container.setStyle({ left: x + 'px', top: y + 'px' });
442
- this.show();
443
- },
444
-
445
-
446
- showAtElement: function(event, element) {
447
- this.container.show();
448
- var x, y;
449
- if (this.popupPositioningStrategy == 'pointer'){ // follow the mouse pointer
450
- var pos = Event.pointer(event);
451
- var containerWidth = this.container.getWidth();
452
- x = containerWidth * this.x + pos.x;
453
- y = containerWidth * this.y + pos.y;
454
- }else{ // 'container' - container of the trigger elements
455
- var pos = Position.cumulativeOffset(element);
456
- x = pos[0];
457
- y = this.container.offsetHeight * 0.75 + pos[1];
458
- }
459
- this.showAt(x, y);
460
- },
461
-
462
- hide: function() {
463
- if (this.isPopup){
464
- Event.stopObserving(document, 'mousedown', Calendar._checkCalendar);
465
- }
466
- this.container.hide();
467
- this.onHideCallback(this.date, this);
468
- },
469
-
470
-
471
- // Tries to identify the date represented in a string. If successful it also
472
- // calls this.updateIfDateDifferent which moves the calendar to the given date.
473
- parseDate: function(str, format){
474
- if (!format){
475
- format = this.dateFormat;
476
- }
477
- var res = Date.parseDate(str, format);
478
- return res;
479
- },
480
-
481
-
482
- dateOrDateBackedUp: function(){
483
- return this.date || this.dateBackedUp;
484
- },
485
-
486
- updateIfDateDifferent: function(date) {
487
- if (!date.equalsTo(this.dateOrDateBackedUp())){
488
- this.update(date);
489
- }
490
- },
491
-
492
- backupDateAndCurrentElement: function(){
493
- if (this.minuteSelect){
494
- this.minuteSelect.disable();
495
- }
496
- if (this.hourSelect){
497
- this.hourSelect.disable();
498
- }
499
-
500
- this.currentDateElementBackedUp = this.currentDateElement;
501
- this.currentDateElement = null;
502
-
503
- this.dateBackedUp = this.date;
504
- this.date = null;
505
- },
506
-
507
- restoreDateAndCurrentElement: function(){
508
- if (this.minuteSelect){
509
- this.minuteSelect.enable();
510
- }
511
- if (this.hourSelect){
512
- this.hourSelect.enable();
513
- }
514
-
515
- this.currentDateElement = this.currentDateElementBackedUp;
516
- this.currentDateElementBackedUp = null;
517
-
518
- this.date = this.dateBackedUp;
519
- this.dateBackedUp = null;
520
- },
521
-
522
- isBackedUp: function(){
523
- return ((this.date == null) && this.dateBackedUp);
524
- },
525
-
526
- dumpDates: function(){
527
- console.log('date: ' + this.date);
528
- console.log('dateBackedUp: ' + this.dateBackedUp);
529
- },
530
-
531
-
532
- setRange: function(minYear, maxYear) {
533
- this.minYear = minYear;
534
- this.maxYear = maxYear;
535
- }
536
- })
537
-
538
- // Delete or add new locales from I18n.js according to your needs
539
- Calendar.messagebundle = $H({'en' :
540
- $H({
541
- 'monday' : 'Monday',
542
- 'tuesday' : 'Tuesday',
543
- 'wednesday' : 'Wednesday',
544
- 'thursday' : 'Thursday',
545
- 'friday' : 'Friday',
546
- 'saturday' : 'Saturday',
547
- 'sunday' : 'Sunday',
548
-
549
- 'monday_short' : 'M',
550
- 'tuesday_short' : 'T',
551
- 'wednesday_short' : 'W',
552
- 'thursday_short' : 'T',
553
- 'friday_short' : 'F',
554
- 'saturday_short' : 'S',
555
- 'sunday_short' : 'S',
556
-
557
- 'january' : 'January',
558
- 'february' : 'February',
559
- 'march' : 'March',
560
- 'april' : 'April',
561
- 'may' : 'May',
562
- 'june' : 'June',
563
- 'july' : 'July',
564
- 'august' : 'August',
565
- 'september' : 'September',
566
- 'october' : 'October',
567
- 'november' : 'November',
568
- 'december' : 'December',
569
-
570
- 'january_short' : 'Jan',
571
- 'february_short' : 'Feb',
572
- 'march_short' : 'Mar',
573
- 'april_short' : 'Apr',
574
- 'may_short' : 'May',
575
- 'june_short' : 'Jun',
576
- 'july_short' : 'Jul',
577
- 'august_short' : 'Aug',
578
- 'september_short' : 'Sep',
579
- 'october_short' : 'Oct',
580
- 'november_short' : 'Nov',
581
- 'december_short' : 'Dec',
582
-
583
- 'today' : 'Today'
584
- }),
585
- 'fr' :
586
- $H({
587
- 'monday' : 'Lundi',
588
- 'tuesday' : 'Mardi',
589
- 'wednesday' : 'Mercredi',
590
- 'thursday' : 'Jeudi',
591
- 'friday' : 'Vendredi',
592
- 'saturday' : 'Samedi',
593
- 'sunday' : 'Dimanche',
594
-
595
- 'monday_short' : 'Lu',
596
- 'tuesday_short' : 'Ma',
597
- 'wednesday_short' : 'Me',
598
- 'thursday_short' : 'Je',
599
- 'friday_short' : 'Ve',
600
- 'saturday_short' : 'Sa',
601
- 'sunday_short' : 'Di',
602
-
603
- 'january' : 'janvier',
604
- 'february' : 'février',
605
- 'march' : 'mars',
606
- 'april' : 'avril',
607
- 'may' : 'mai',
608
- 'june' : 'juin',
609
- 'july' : 'juillet',
610
- 'august' : 'août',
611
- 'september' : 'septembre',
612
- 'october' : 'octobre',
613
- 'november' : 'novembre',
614
- 'december' : 'décembre',
615
-
616
- 'january_short' : 'jan',
617
- 'february_short' : 'fév',
618
- 'march_short' : 'mar',
619
- 'april_short' : 'avr',
620
- 'may_short' : 'mai',
621
- 'june_short' : 'jun',
622
- 'july_short' : 'jul',
623
- 'august_short' : 'aoû',
624
- 'september_short' : 'sep',
625
- 'october_short' : 'oct',
626
- 'november_short' : 'nov',
627
- 'december_short' : 'dec',
628
-
629
- 'today' : 'aujourd\'hui'
630
- }),
631
- 'nl' :
632
- $H({
633
- 'monday' : 'maandag',
634
- 'tuesday' : 'dinsdag',
635
- 'wednesday' : 'woensdag',
636
- 'thursday' : 'donderdag',
637
- 'friday' : 'vrijdag',
638
- 'saturday' : 'zaterdag',
639
- 'sunday' : 'zondag',
640
-
641
- 'monday_short' : 'Ma',
642
- 'tuesday_short' : 'Di',
643
- 'wednesday_short' : 'Wo',
644
- 'thursday_short' : 'Do',
645
- 'friday_short' : 'Vr',
646
- 'saturday_short' : 'Za',
647
- 'sunday_short' : 'Zo',
648
-
649
- 'january' : 'januari',
650
- 'february' : 'februari',
651
- 'march' : 'maart',
652
- 'april' : 'april',
653
- 'may' : 'mei',
654
- 'june' : 'juni',
655
- 'july' : 'juli',
656
- 'august' : 'augustus',
657
- 'september' : 'september',
658
- 'october' : 'oktober',
659
- 'november' : 'november',
660
- 'december' : 'december',
661
-
662
- 'january_short' : 'jan',
663
- 'february_short' : 'feb',
664
- 'march_short' : 'mrt',
665
- 'april_short' : 'apr',
666
- 'may_short' : 'mei',
667
- 'june_short' : 'jun',
668
- 'july_short' : 'jul',
669
- 'august_short' : 'aug',
670
- 'september_short' : 'sep',
671
- 'october_short' : 'okt',
672
- 'november_short' : 'nov',
673
- 'december_short' : 'dec',
674
-
675
- 'today' : 'vandaag'
676
- })
677
- });
678
-
679
-
680
- Calendar.getMessageFor = function(key){
681
-
682
- var lang = Calendar.language || 'en';
683
- if (! Calendar.messagebundle.get(lang)){
684
- lang = 'en';
685
- }
686
- return Calendar.messagebundle.get(lang).get(key);
687
- };
688
-
689
- Calendar.VERSION = '1.4';
690
-
691
- Calendar.defaultDateFormat = '%Y-%m-%d';
692
- Calendar.defaultDateTimeFormat = '%Y-%m-%d %H:%M';
693
-
694
- // we need to postpone the initialization of these structures to let the page define the language of the page
695
- Calendar.init = function(){
696
-
697
- Calendar.DAY_NAMES = new Array(
698
- Calendar.getMessageFor('sunday'),
699
- Calendar.getMessageFor('monday'),
700
- Calendar.getMessageFor('tuesday'),
701
- Calendar.getMessageFor('wednesday'),
702
- Calendar.getMessageFor('thursday'),
703
- Calendar.getMessageFor('friday'),
704
- Calendar.getMessageFor('saturday')
705
- );
706
-
707
- Calendar.SHORT_DAY_NAMES = new Array(
708
- Calendar.getMessageFor('sunday_short'),
709
- Calendar.getMessageFor('monday_short'),
710
- Calendar.getMessageFor('tuesday_short'),
711
- Calendar.getMessageFor('wednesday_short'),
712
- Calendar.getMessageFor('thursday_short'),
713
- Calendar.getMessageFor('friday_short'),
714
- Calendar.getMessageFor('saturday_short')
715
- );
716
-
717
- Calendar.MONTH_NAMES = new Array(
718
- Calendar.getMessageFor('january'),
719
- Calendar.getMessageFor('february'),
720
- Calendar.getMessageFor('march'),
721
- Calendar.getMessageFor('april'),
722
- Calendar.getMessageFor('may'),
723
- Calendar.getMessageFor('june'),
724
- Calendar.getMessageFor('july'),
725
- Calendar.getMessageFor('august'),
726
- Calendar.getMessageFor('september'),
727
- Calendar.getMessageFor('october'),
728
- Calendar.getMessageFor('november'),
729
- Calendar.getMessageFor('december')
730
- );
731
-
732
- Calendar.SHORT_MONTH_NAMES = new Array(
733
- Calendar.getMessageFor('january_short'),
734
- Calendar.getMessageFor('february_short'),
735
- Calendar.getMessageFor('march_short'),
736
- Calendar.getMessageFor('april_short'),
737
- Calendar.getMessageFor('may_short'),
738
- Calendar.getMessageFor('june_short'),
739
- Calendar.getMessageFor('july_short'),
740
- Calendar.getMessageFor('august_short'),
741
- Calendar.getMessageFor('september_short'),
742
- Calendar.getMessageFor('october_short'),
743
- Calendar.getMessageFor('november_short'),
744
- Calendar.getMessageFor('december_short')
745
- );
746
- Calendar.init_done = true;
747
- };
748
-
749
- Calendar.NAV_PREVIOUS_YEAR = -2;
750
- Calendar.NAV_PREVIOUS_MONTH = -1;
751
- Calendar.NAV_TODAY = 0;
752
- Calendar.NAV_NEXT_MONTH = 1;
753
- Calendar.NAV_NEXT_YEAR = 2;
754
-
755
- //------------------------------------------------------------------------------
756
- // Static Methods
757
- //------------------------------------------------------------------------------
758
-
759
- // This gets called when the user presses a mouse button anywhere in the
760
- // document, if the calendar is shown. If the click was outside the open
761
- // calendar this function closes it.
762
- Calendar._checkCalendar = function(event) {
763
- if (!window._popupCalendar){
764
- return false;
765
- }
766
- if (Element.descendantOf(Event.element(event), window._popupCalendar.container)){
767
- return;
768
- }
769
- Calendar.closeHandler(window._popupCalendar);
770
- return Event.stop(event);
771
- }
772
-
773
- //------------------------------------------------------------------------------
774
- // Event Handlers
775
- //------------------------------------------------------------------------------
776
-
777
- Calendar.handleMouseDownEvent = function(event){
778
- if (event.element().type == 'select-one'){ // ignore select elements - not escaping this in Safari leaves select boxes non-functional
779
- return true;
780
- }
781
- Event.observe(document, 'mouseup', Calendar.handleMouseUpEvent);
782
- Event.stop(event)
783
- }
784
-
785
- Calendar.handleMouseUpEvent = function(event){
786
- var el = Event.element(event);
787
- var calendar = el.calendar;
788
- var isNewDate = false;
789
-
790
-
791
- // If the element that was clicked on does not have an associated Calendar
792
- // object, return as we have nothing to do.
793
- if (!calendar) return false;
794
-
795
- // Clicked on a day
796
- if (typeof el.navAction == 'undefined') {
797
-
798
- var dateWasDefined = true;
799
- if (calendar.date == null){
800
- dateWasDefined = false;
801
- calendar.restoreDateAndCurrentElement();
802
- }
803
-
804
-
805
- if (calendar.currentDateElement) {
806
- Element.removeClassName(calendar.currentDateElement, 'selected');
807
-
808
- if (dateWasDefined && el == calendar.currentDateElement){
809
- calendar.backupDateAndCurrentElement();
810
-
811
- calendar.updateOuterField();
812
-
813
- Event.stopObserving(document, 'mouseup', Calendar.handleMouseUpEvent);
814
- return Event.stop(event);
815
- }
816
-
817
- Element.addClassName(el, 'selected');
818
-
819
- calendar.shouldClose = (calendar.currentDateElement == el);
820
-
821
- if (!calendar.shouldClose) {
822
-
823
- calendar.currentDateElement = el;
824
- }
825
- }
826
- calendar.date.setDateOnly(el.date);
827
- isNewDate = true;
828
-
829
- calendar.shouldClose = !el.hasClassName('otherDay');
830
-
831
-
832
- var isOtherMonth = !calendar.shouldClose;
833
- if (isOtherMonth) {
834
- calendar.update(calendar.date);
835
- }
836
-
837
- if (! calendar.hideOnClickOnDay){ // override closing if calendar.hideOnClickOnDay is false
838
- calendar.shouldClose = false;
839
- }
840
-
841
- } else { // Clicked on an action button
842
-
843
- var date = new Date(calendar.dateOrDateBackedUp());
844
-
845
- if (el.navAction == Calendar.NAV_TODAY){
846
- date.setDateOnly(new Date());
847
- }
848
-
849
- var year = date.getFullYear();
850
- var mon = date.getMonth();
851
-
852
- function setMonth(m) {
853
- var day = date.getDate();
854
- var max = date.getMonthDays(m);
855
- if (day > max) date.setDate(max);
856
- date.setMonth(m);
857
- }
858
-
859
- switch (el.navAction) {
860
-
861
- // Previous Year
862
- case Calendar.NAV_PREVIOUS_YEAR:
863
- if (year > calendar.minYear)
864
- date.__setFullYear(year - 1);
865
- break;
866
-
867
- // Previous Month
868
- case Calendar.NAV_PREVIOUS_MONTH:
869
- if (mon > 0) {
870
- setMonth(mon - 1);
871
- }
872
- else if (year-- > calendar.minYear) {
873
- date.__setFullYear(year);
874
- setMonth(11);
875
- }
876
- break;
877
-
878
- // Today
879
- case Calendar.NAV_TODAY:
880
- break;
881
-
882
- // Next Month
883
- case Calendar.NAV_NEXT_MONTH:
884
- if (mon < 11) {
885
- setMonth(mon + 1);
886
- }else if (year < calendar.maxYear) {
887
- date.__setFullYear(year + 1);
888
- setMonth(0);
889
- }
890
- break;
891
-
892
- // Next Year
893
- case Calendar.NAV_NEXT_YEAR:
894
- if (year < calendar.maxYear){
895
- date.__setFullYear(year + 1);
896
- }
897
- break;
898
- }
899
-
900
- if (!date.equalsTo(calendar.dateOrDateBackedUp())) {
901
- calendar.updateIfDateDifferent(date);
902
- isNewDate = true;
903
- } // else if (el.navAction == 0) {
904
- // isNewDate = (calendar.shouldClose = true);
905
- // } // Hm, what did I mean with this code?
906
- }
907
-
908
- if (isNewDate && event) {
909
- Calendar.selectHandler(calendar);
910
- }
911
-
912
- if (calendar.shouldClose && event) {
913
- Calendar.closeHandler(calendar);
914
- }
915
-
916
- Event.stopObserving(document, 'mouseup', Calendar.handleMouseUpEvent);
917
- return Event.stop(event);
918
- }
919
-
920
- Calendar.selectHandler = function(calendar){
921
-
922
- // Update dateField value
923
- calendar.updateOuterField();
924
-
925
-
926
- // Call the close handler, if necessary
927
- if (calendar.shouldClose) {
928
- Calendar.closeHandler(calendar);
929
- }
930
- }
931
-
932
- Calendar.closeHandler = function(calendar){
933
- calendar.hide();
934
- calendar.shouldClose = false;
935
- }
936
-
937
-
938
-
939
- // global object that remembers the calendar
940
- window._popupCalendar = null;
941
-
942
-
943
- //==============================================================================
944
- //
945
- // Date Object Patches
946
- //
947
- // This is pretty much untouched from the original. I really would like to get
948
- // rid of these patches if at all possible and find a cleaner way of
949
- // accomplishing the same things. It's a shame Prototype doesn't extend Date at
950
- // all.
951
- //
952
- //==============================================================================
953
-
954
- Date.DAYS_IN_MONTH = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
955
- Date.SECOND = 1000 /* milliseconds */
956
- Date.MINUTE = 60 * Date.SECOND
957
- Date.HOUR = 60 * Date.MINUTE
958
- Date.DAY = 24 * Date.HOUR
959
- Date.WEEK = 7 * Date.DAY
960
-
961
- // Parses Date
962
- Date.parseDate = function(str, fmt) {
963
- if (str){
964
- str = new String(str);
965
- }else{
966
- str = new String('');
967
- }
968
- str = str.strip();
969
-
970
- var today = new Date();
971
- var y = 0;
972
- var m = -1;
973
- var d = 0;
974
- var a = str.split(/\W+/);
975
- var b = fmt.match(/%./g);
976
- var i = 0, j = 0;
977
- var hr = 0;
978
- var min = 0;
979
-
980
- for (i = 0; i < a.length; ++i) {
981
- if (!a[i]) continue;
982
- switch (b[i]) {
983
- case "%d":
984
- case "%e":
985
- d = parseInt(a[i], 10);
986
- break;
987
- case "%m":
988
- m = parseInt(a[i], 10) - 1;
989
- break;
990
- case "%Y":
991
- case "%y":
992
- y = parseInt(a[i], 10);
993
- (y < 100) && (y += (y > 29) ? 1900 : 2000);
994
- break;
995
- case "%b":
996
- case "%B":
997
- for (j = 0; j < 12; ++j) {
998
- if (Calendar.MONTH_NAMES[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) {
999
- m = j;
1000
- break;
1001
- }
1002
- }
1003
- break;
1004
- case "%H":
1005
- case "%I":
1006
- case "%k":
1007
- case "%l":
1008
- hr = parseInt(a[i], 10);
1009
- break;
1010
- case "%P":
1011
- case "%p":
1012
- if (/pm/i.test(a[i]) && hr < 12)
1013
- hr += 12;
1014
- else if (/am/i.test(a[i]) && hr >= 12)
1015
- hr -= 12;
1016
- break;
1017
- case "%M":
1018
- min = parseInt(a[i], 10);
1019
- break;
1020
- }
1021
- }
1022
- if (isNaN(y)) y = today.getFullYear();
1023
- if (isNaN(m)) m = today.getMonth();
1024
- if (isNaN(d)) d = today.getDate();
1025
- if (isNaN(hr)) hr = today.getHours();
1026
- if (isNaN(min)) min = today.getMinutes();
1027
- if (y != 0 && m != -1 && d != 0)
1028
- return new Date(y, m, d, hr, min, 0);
1029
- y = 0; m = -1; d = 0;
1030
- for (i = 0; i < a.length; ++i) {
1031
- if (a[i].search(/[a-zA-Z]+/) != -1) {
1032
- var t = -1;
1033
- for (j = 0; j < 12; ++j) {
1034
- if (Calendar.MONTH_NAMES[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
1035
- }
1036
- if (t != -1) {
1037
- if (m != -1) {
1038
- d = m+1;
1039
- }
1040
- m = t;
1041
- }
1042
- } else if (parseInt(a[i], 10) <= 12 && m == -1) {
1043
- m = a[i]-1;
1044
- } else if (parseInt(a[i], 10) > 31 && y == 0) {
1045
- y = parseInt(a[i], 10);
1046
- (y < 100) && (y += (y > 29) ? 1900 : 2000);
1047
- } else if (d == 0) {
1048
- d = a[i];
1049
- }
1050
- }
1051
- if (y == 0)
1052
- y = today.getFullYear();
1053
- if (m != -1 && d != 0)
1054
- return new Date(y, m, d, hr, min, 0);
1055
- return today;
1056
- };
1057
-
1058
- // Returns the number of days in the current month
1059
- Date.prototype.getMonthDays = function(month) {
1060
- var year = this.getFullYear()
1061
- if (typeof month == "undefined")
1062
- month = this.getMonth()
1063
- if (((0 == (year % 4)) && ( (0 != (year % 100)) || (0 == (year % 400)))) && month == 1)
1064
- return 29
1065
- else
1066
- return Date.DAYS_IN_MONTH[month]
1067
- };
1068
-
1069
- // Returns the number of day in the year
1070
- Date.prototype.getDayOfYear = function() {
1071
- var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1072
- var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
1073
- var time = now - then;
1074
- return Math.floor(time / Date.DAY);
1075
- };
1076
-
1077
- /** Returns the number of the week in year, as defined in ISO 8601. */
1078
- Date.prototype.getWeekNumber = function() {
1079
- var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1080
- var DoW = d.getDay();
1081
- d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
1082
- var ms = d.valueOf(); // GMT
1083
- d.setMonth(0);
1084
- d.setDate(4); // Thu in Week 1
1085
- return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
1086
- };
1087
-
1088
- /** Checks date and time equality */
1089
- Date.prototype.equalsTo = function(date) {
1090
- return ((this.getFullYear() == date.getFullYear()) &&
1091
- (this.getMonth() == date.getMonth()) &&
1092
- (this.getDate() == date.getDate()) &&
1093
- (this.getHours() == date.getHours()) &&
1094
- (this.getMinutes() == date.getMinutes()));
1095
- };
1096
-
1097
- /** Set only the year, month, date parts (keep existing time) */
1098
- Date.prototype.setDateOnly = function(date) {
1099
- var tmp = new Date(date);
1100
- this.setDate(1);
1101
- this.__setFullYear(tmp.getFullYear());
1102
- this.setMonth(tmp.getMonth());
1103
- this.setDate(tmp.getDate());
1104
- };
1105
-
1106
- /** Prints the date in a string according to the given format. */
1107
- Date.prototype.print = function (str) {
1108
- var m = this.getMonth();
1109
- var d = this.getDate();
1110
- var y = this.getFullYear();
1111
- var wn = this.getWeekNumber();
1112
- var w = this.getDay();
1113
- var s = {};
1114
- var hr = this.getHours();
1115
- var pm = (hr >= 12);
1116
- var ir = (pm) ? (hr - 12) : hr;
1117
- var dy = this.getDayOfYear();
1118
- if (ir == 0)
1119
- ir = 12;
1120
- var min = this.getMinutes();
1121
- var sec = this.getSeconds();
1122
- s["%a"] = Calendar.SHORT_DAY_NAMES[w]; // abbreviated weekday name [FIXME: I18N]
1123
- s["%A"] = Calendar.DAY_NAMES[w]; // full weekday name
1124
- s["%b"] = Calendar.SHORT_MONTH_NAMES[m]; // abbreviated month name [FIXME: I18N]
1125
- s["%B"] = Calendar.MONTH_NAMES[m]; // full month name
1126
- // FIXME: %c : preferred date and time representation for the current locale
1127
- s["%C"] = 1 + Math.floor(y / 100); // the century number
1128
- s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
1129
- s["%e"] = d; // the day of the month (range 1 to 31)
1130
- // FIXME: %D : american date style: %m/%d/%y
1131
- // FIXME: %E, %F, %G, %g, %h (man strftime)
1132
- s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
1133
- s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
1134
- s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
1135
- s["%k"] = hr; // hour, range 0 to 23 (24h format)
1136
- s["%l"] = ir; // hour, range 1 to 12 (12h format)
1137
- s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
1138
- s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
1139
- s["%n"] = "\n"; // a newline character
1140
- s["%p"] = pm ? "PM" : "AM";
1141
- s["%P"] = pm ? "pm" : "am";
1142
- // FIXME: %r : the time in am/pm notation %I:%M:%S %p
1143
- // FIXME: %R : the time in 24-hour notation %H:%M
1144
- s["%s"] = Math.floor(this.getTime() / 1000);
1145
- s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
1146
- s["%t"] = "\t"; // a tab character
1147
- // FIXME: %T : the time in 24-hour notation (%H:%M:%S)
1148
- s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
1149
- s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
1150
- s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
1151
- // FIXME: %x : preferred date representation for the current locale without the time
1152
- // FIXME: %X : preferred time representation for the current locale without the date
1153
- s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
1154
- s["%Y"] = y; // year with the century
1155
- s["%%"] = "%"; // a literal '%' character
1156
-
1157
- return str.gsub(/%./, function(match) { return s[match] || match });
1158
- };
1159
-
1160
-
1161
- Date.prototype.__setFullYear = function(y) {
1162
- var d = new Date(this);
1163
- d.setFullYear(y);
1164
- if (d.getMonth() != this.getMonth())
1165
- this.setDate(28);
1166
- this.setFullYear(y);
1167
- };
1168
-