puffer 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +11 -8
  3. data/Gemfile.lock +117 -103
  4. data/Guardfile +20 -0
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/puffer/application.js +5 -0
  7. data/{lib/generators/puffer/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/puffer.js +0 -0
  8. data/{lib/generators/puffer/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/rails.js +0 -0
  9. data/{lib/generators/puffer/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/right-autocompleter.js +0 -0
  10. data/{lib/generators/puffer/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/right-calendar.js +0 -0
  11. data/{lib/generators/puffer/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/right.js +0 -0
  12. data/app/assets/stylesheets/puffer/application.css +4 -0
  13. data/{lib/generators/puffer/install/templates/puffer/stylesheets → app/assets/stylesheets/puffer}/puffer.css +2 -1
  14. data/{lib/generators/puffer/install/templates/puffer/stylesheets → app/assets/stylesheets/puffer}/reset.css +0 -0
  15. data/app/controllers/puffer/dashboard.rb +12 -0
  16. data/app/controllers/puffer/{sessions_base.rb → sessions.rb} +1 -2
  17. data/app/helpers/puffer_helper.rb +2 -10
  18. data/app/views/layouts/puffer.html.erb +24 -5
  19. data/app/views/layouts/puffer_dashboard.html.erb +3 -3
  20. data/app/views/layouts/puffer_sessions.html.erb +3 -3
  21. data/app/views/puffer/{_form.html.erb → base/_form.html.erb} +2 -2
  22. data/app/views/puffer/{associated → base/associated}/_many.html.erb +1 -1
  23. data/app/views/puffer/{associated → base/associated}/many.rjs +0 -0
  24. data/app/views/puffer/{associated → base/associated}/one.js.erb +1 -1
  25. data/app/views/puffer/{association → base/association}/_many.html.erb +0 -0
  26. data/app/views/puffer/{edit.html.erb → base/edit.html.erb} +1 -1
  27. data/app/views/puffer/{index.html.erb → base/index.html.erb} +2 -2
  28. data/app/views/puffer/{new.html.erb → base/new.html.erb} +1 -1
  29. data/app/views/puffer/{show.html.erb → base/show.html.erb} +1 -1
  30. data/app/views/{puffer_dashboard → puffer/dashboard}/index.html.erb +0 -0
  31. data/app/views/{puffer_sessions → puffer/sessions}/new.html.erb +0 -0
  32. data/config/locales/puffer.yml +5 -0
  33. data/lib/generators/puffer/install/install_generator.rb +0 -8
  34. data/lib/generators/puffer/install/templates/dashboard_controller.rb +1 -1
  35. data/lib/generators/puffer/install/templates/sessions_controller.rb +1 -1
  36. data/lib/puffer.rb +0 -16
  37. data/lib/puffer/base.rb +8 -3
  38. data/lib/puffer/controller/config.rb +2 -0
  39. data/lib/puffer/controller/dsl.rb +2 -2
  40. data/lib/puffer/controller/generated.rb +4 -4
  41. data/lib/puffer/controller/helpers.rb +1 -1
  42. data/lib/puffer/controller/mutate.rb +0 -14
  43. data/lib/puffer/customs.rb +1 -0
  44. data/lib/puffer/engine.rb +0 -4
  45. data/lib/puffer/extensions/mapper.rb +5 -1
  46. data/lib/puffer/fields.rb +2 -2
  47. data/lib/puffer/fields/field.rb +16 -17
  48. data/lib/puffer/inputs/association.rb +3 -2
  49. data/lib/puffer/resource.rb +13 -12
  50. data/lib/puffer/resource/routing.rb +1 -1
  51. data/lib/puffer/resource/scoping.rb +2 -2
  52. data/puffer.gemspec +63 -126
  53. data/spec/dummy/.rvmrc +1 -0
  54. data/spec/dummy/Rakefile +1 -1
  55. data/spec/dummy/app/assets/images/rails.png +0 -0
  56. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  57. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  58. data/spec/dummy/app/controllers/admin/posts_controller.rb +3 -1
  59. data/spec/dummy/app/controllers/admin/profiles_controller.rb +4 -1
  60. data/spec/dummy/app/controllers/puffer/dashboard_controller.rb +1 -1
  61. data/spec/dummy/app/controllers/puffer/sessions_controller.rb +1 -1
  62. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  63. data/spec/dummy/config/application.rb +5 -9
  64. data/spec/dummy/config/boot.rb +5 -7
  65. data/spec/dummy/config/database.yml +4 -1
  66. data/spec/dummy/config/environments/development.rb +4 -3
  67. data/spec/dummy/config/environments/production.rb +17 -12
  68. data/spec/dummy/config/environments/test.rb +5 -1
  69. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  70. data/spec/dummy/config/initializers/session_store.rb +1 -1
  71. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  72. data/spec/dummy/config/locales/en.yml +1 -1
  73. data/spec/dummy/db/seeds.rb +7 -0
  74. data/spec/dummy/public/robots.txt +5 -0
  75. data/spec/fabricators/posts_fabricator.rb +1 -1
  76. data/spec/fabricators/profiles_fabricator.rb +1 -1
  77. data/spec/fabricators/users_fabricator.rb +1 -1
  78. data/spec/lib/resource/routing_spec.rb +5 -5
  79. data/spec/lib/resource_spec.rb +37 -88
  80. data/spec/spec_helper.rb +15 -0
  81. metadata +171 -272
  82. data/app/cells/puffer/base/additional.html.erb +0 -25
  83. data/app/cells/puffer/base_cell.rb +0 -25
  84. data/app/controllers/puffer/dashboard_base.rb +0 -13
  85. data/autotest/discover.rb +0 -2
  86. data/lib/generators/puffer/install/templates/puffer.rb +0 -12
  87. data/lib/puffer/path_set.rb +0 -24
  88. data/spec/dummy/app/views/admin/users/index.html.erb +0 -3
  89. data/spec/dummy/config/initializers/puffer.rb +0 -12
  90. data/spec/dummy/db/schema.rb +0 -83
  91. data/spec/dummy/public/javascripts/application.js +0 -2
  92. data/spec/dummy/public/javascripts/controls.js +0 -965
  93. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  94. data/spec/dummy/public/javascripts/effects.js +0 -1123
  95. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  96. data/spec/dummy/public/javascripts/rails.js +0 -175
  97. data/spec/dummy/public/puffer/javascripts/puffer.js +0 -10
  98. data/spec/dummy/public/puffer/javascripts/rails.js +0 -57
  99. data/spec/dummy/public/puffer/javascripts/right-autocompleter.js +0 -621
  100. data/spec/dummy/public/puffer/javascripts/right-calendar.js +0 -1461
  101. data/spec/dummy/public/puffer/javascripts/right.js +0 -5892
  102. data/spec/dummy/public/puffer/stylesheets/puffer.css +0 -469
  103. data/spec/dummy/public/puffer/stylesheets/reset.css +0 -60
  104. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  105. data/spec/lib/render_fallback_spec.rb +0 -17
@@ -1,1461 +0,0 @@
1
- /**
2
- * The calendar widget implemented with RightJS
3
- *
4
- * Home page: http://rightjs.org/ui/calendar
5
- *
6
- * @copyright (C) 2009-2010 Nikolay Nemshilov
7
- */
8
- var Calendar = RightJS.Calendar = (function(document, parseInt, RightJS) {
9
- /**
10
- * This module defines the basic widgets constructor
11
- * it creates an abstract proxy with the common functionality
12
- * which then we reuse and override in the actual widgets
13
- *
14
- * Copyright (C) 2010-2011 Nikolay Nemshilov
15
- */
16
-
17
- /**
18
- * The filenames to include
19
- *
20
- * Copyright (C) 2010-2011 Nikolay Nemshilov
21
- */
22
-
23
- var R = RightJS,
24
- $ = RightJS.$,
25
- $$ = RightJS.$$,
26
- $w = RightJS.$w,
27
- $ext = RightJS.$ext,
28
- $uid = RightJS.$uid,
29
- isString = RightJS.isString,
30
- isArray = RightJS.isArray,
31
- isFunction = RightJS.isFunction,
32
- Class = RightJS.Class,
33
- Element = RightJS.Element,
34
- Input = RightJS.Input,
35
- RegExp = RightJS.RegExp,
36
- Browser = RightJS.Browser;
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- /**
47
- * The widget units constructor
48
- *
49
- * @param String tag-name or Object methods
50
- * @param Object methods
51
- * @return Widget wrapper
52
- */
53
- function Widget(tag_name, methods) {
54
- if (!methods) {
55
- methods = tag_name;
56
- tag_name = 'DIV';
57
- }
58
-
59
- /**
60
- * An Abstract Widget Unit
61
- *
62
- * Copyright (C) 2010 Nikolay Nemshilov
63
- */
64
- var AbstractWidget = new RightJS.Class(RightJS.Element.Wrappers[tag_name] || RightJS.Element, {
65
- /**
66
- * The common constructor
67
- *
68
- * @param Object options
69
- * @param String optional tag name
70
- * @return void
71
- */
72
- initialize: function(key, options) {
73
- this.key = key;
74
- var args = [{'class': 'rui-' + key}];
75
-
76
- // those two have different constructors
77
- if (!(this instanceof RightJS.Input || this instanceof RightJS.Form)) {
78
- args.unshift(tag_name);
79
- }
80
- this.$super.apply(this, args);
81
-
82
- if (RightJS.isString(options)) {
83
- options = RightJS.$(options);
84
- }
85
-
86
- // if the options is another element then
87
- // try to dynamically rewrap it with our widget
88
- if (options instanceof RightJS.Element) {
89
- this._ = options._;
90
- if ('$listeners' in options) {
91
- options.$listeners = options.$listeners;
92
- }
93
- options = {};
94
- }
95
- this.setOptions(options, this);
96
-
97
- return (RightJS.Wrapper.Cache[RightJS.$uid(this._)] = this);
98
- },
99
-
100
- // protected
101
-
102
- /**
103
- * Catches the options
104
- *
105
- * @param Object user-options
106
- * @param Element element with contextual options
107
- * @return void
108
- */
109
- setOptions: function(options, element) {
110
- element = element || this;
111
- RightJS.Options.setOptions.call(this,
112
- RightJS.Object.merge(options, eval("("+(
113
- element.get('data-'+ this.key) || '{}'
114
- )+")"))
115
- );
116
- return this;
117
- }
118
- });
119
-
120
- /**
121
- * Creating the actual widget class
122
- *
123
- */
124
- var Klass = new RightJS.Class(AbstractWidget, methods);
125
-
126
- // creating the widget related shortcuts
127
- RightJS.Observer.createShortcuts(Klass.prototype, Klass.EVENTS || []);
128
-
129
- return Klass;
130
- }
131
-
132
-
133
- /**
134
- * A shared button unit.
135
- * NOTE: we use the DIV units instead of INPUTS
136
- * so those buttons didn't interfere with
137
- * the user's tab-index on his page
138
- *
139
- * Copyright (C) 2010-2011 Nikolay Nemshilov
140
- */
141
- var Button = new RightJS.Class(RightJS.Element, {
142
- /**
143
- * Constructor
144
- *
145
- * @param String caption
146
- * @param Object options
147
- * @return void
148
- */
149
- initialize: function(caption, options) {
150
- this.$super('div', options);
151
- this._.innerHTML = caption;
152
- this.addClass('rui-button');
153
- this.on('selectstart', 'stopEvent');
154
- },
155
-
156
- /**
157
- * Disasbles the button
158
- *
159
- * @return Button this
160
- */
161
- disable: function() {
162
- return this.addClass('rui-button-disabled');
163
- },
164
-
165
- /**
166
- * Enables the button
167
- *
168
- * @return Button this
169
- */
170
- enable: function() {
171
- return this.removeClass('rui-button-disabled');
172
- },
173
-
174
- /**
175
- * Checks if the button is disabled
176
- *
177
- * @return Button this
178
- */
179
- disabled: function() {
180
- return this.hasClass('rui-button-disabled');
181
- },
182
-
183
- /**
184
- * Checks if the button is enabled
185
- *
186
- * @return Button this
187
- */
188
- enabled: function() {
189
- return !this.disabled();
190
- },
191
-
192
- /**
193
- * Overloading the method, so it fired the events
194
- * only when the button is active
195
- *
196
- * @return Button this
197
- */
198
- fire: function() {
199
- if (this.enabled()) {
200
- this.$super.apply(this, arguments);
201
- }
202
- return this;
203
- }
204
- });
205
-
206
-
207
- /**
208
- * A shared module that toggles a widget visibility status
209
- * in a uniformed way according to the options settings
210
- *
211
- * Copyright (C) 2010-2011 Nikolay Nemshilov
212
- */
213
- var Toggler = {
214
- /**
215
- * Shows the element
216
- *
217
- * @param String fx-name
218
- * @param Object fx-options
219
- * @return Element this
220
- */
221
- show: function(fx_name, fx_options) {
222
- this.constructor.current = this;
223
- return Toggler_toggle(this, 'show', fx_name, fx_options);
224
- },
225
-
226
- /**
227
- * Hides the element
228
- *
229
- * @param String fx-name
230
- * @param Object fx-options
231
- * @return Element this
232
- */
233
- hide: function(fx_name, fx_options) {
234
- this.constructor.current = null;
235
- return Toggler_toggle(this, 'show', fx_name, fx_options);
236
- },
237
-
238
- /**
239
- * Toggles the widget at the given element
240
- *
241
- * @param Element the related element
242
- * @param String position right/bottom (bottom is the default)
243
- * @param Boolean marker if the element should be resized to the element size
244
- * @return Widget this
245
- */
246
- showAt: function(element, where, resize) {
247
- this.hide(null).shownAt = element = RightJS.$(element);
248
-
249
- // moves this element at the given one
250
- Toggler_re_position.call(this, element, where, resize);
251
-
252
- return this.show();
253
- },
254
-
255
- /**
256
- * Toggles the widget at the given element
257
- *
258
- * @param Element the related element
259
- * @param String position top/left/right/bottom (bottom is the default)
260
- * @param Boolean marker if the element should be resized to the element size
261
- * @return Widget this
262
- */
263
- toggleAt: function(element, where, resize) {
264
- return this.hidden() ? this.showAt(element, where, resize) : this.hide();
265
- }
266
- };
267
-
268
-
269
- /**
270
- * toggles the element's state according to the current settings
271
- *
272
- * @param event String 'show' or 'hide' the event name
273
- * @param String an optional fx-name
274
- * @param Object an optional fx-options hash
275
- * @return void
276
- */
277
- function Toggler_toggle(element, event, fx_name, fx_options) {
278
- if (RightJS.Fx) {
279
- if (fx_name === undefined) {
280
- fx_name = element.options.fxName;
281
-
282
- if (fx_options === undefined) {
283
- fx_options = {
284
- duration: element.options.fxDuration,
285
- onFinish: RightJS(element.fire).bind(element, event)
286
- };
287
-
288
- // hide on double time
289
- if (event === 'hide') {
290
- fx_options.duration = (RightJS.Fx.Durations[fx_options.duration] ||
291
- fx_options.duration) / 2;
292
- }
293
- }
294
- }
295
- }
296
-
297
- // manually trigger the event if no fx were specified
298
- if (!RightJS.Fx || !fx_name) { element.fire(event); }
299
-
300
- return element.$super(fx_name, fx_options);
301
- }
302
-
303
- /**
304
- * Relatively positions the current element
305
- * against the specified one
306
- *
307
- * NOTE: this function is called in a context
308
- * of another element
309
- *
310
- * @param Element the target element
311
- * @param String position 'right' or 'bottom'
312
- * @param Boolean if `true` then the element size will be adjusted
313
- * @return void
314
- */
315
- function Toggler_re_position(element, where, resize) {
316
- var anchor = this.reAnchor || (this.reAnchor =
317
- new RightJS.Element('div', {'class': 'rui-re-anchor'}))
318
- .insert(this),
319
-
320
- pos = anchor.insertTo(element, 'after').position(),
321
- dims = element.dimensions(), target = this,
322
-
323
- border_top = parseInt(element.getStyle('borderTopWidth')),
324
- border_left = parseInt(element.getStyle('borderLeftWidth')),
325
- border_right = parseInt(element.getStyle('borderRightWidth')),
326
- border_bottom = parseInt(element.getStyle('borderBottomWidth')),
327
-
328
- top = dims.top - pos.y + border_top,
329
- left = dims.left - pos.x + border_left,
330
- width = dims.width - border_left - border_right,
331
- height = dims.height - border_top - border_bottom;
332
-
333
- // making the element to appear so we could read it's sizes
334
- target.setStyle('visibility:hidden').show(null);
335
-
336
- if (where === 'right') {
337
- left += width - target.size().x;
338
- } else { // bottom
339
- top += height;
340
- }
341
-
342
- target.moveTo(left, top);
343
-
344
- if (resize) {
345
- if (where === 'left' || where === 'right') {
346
- target.setHeight(height);
347
- } else {
348
- target.setWidth(width);
349
- }
350
- }
351
-
352
- // rolling the invisibility back
353
- target.setStyle('visibility:visible').hide(null);
354
- }
355
-
356
- /**
357
- * A shared module that provides for the widgets an ability
358
- * to be assigned to an input element and work in pair with it
359
- *
360
- * NOTE: this module works in pair with the 'RePosition' module!
361
- *
362
- * Copyright (C) 2010 Nikolay Nemshilov
363
- */
364
- var Assignable = {
365
- /**
366
- * Assigns the widget to serve the given input element
367
- *
368
- * Basically it puts the references of the current widget
369
- * to the input and trigger objects so they could be recognized
370
- * later, and it also synchronizes the changes between the input
371
- * element and the widget
372
- *
373
- * @param {Element} input field
374
- * @param {Element} optional trigger
375
- * @return Widget this
376
- */
377
- assignTo: function(input, trigger) {
378
- input = RightJS.$(input);
379
- trigger = RightJS.$(trigger);
380
-
381
- if (trigger) {
382
- trigger[this.key] = this;
383
- trigger.assignedInput = input;
384
- } else {
385
- input[this.key] = this;
386
- }
387
-
388
- var on_change = RightJS(function() {
389
- if (this.visible() && (!this.showAt || this.shownAt === input)) {
390
- this.setValue(input.value());
391
- }
392
- }).bind(this);
393
-
394
- input.on({
395
- keyup: on_change,
396
- change: on_change
397
- });
398
-
399
- this.onChange(function() {
400
- if (!this.showAt || this.shownAt === input) {
401
- input.setValue(this.getValue());
402
- }
403
- });
404
-
405
- return this;
406
- }
407
- };
408
-
409
-
410
- /**
411
- * Converts a number into a string with leading zeros
412
- *
413
- * @param Number number
414
- * @return String with zeros
415
- */
416
- function zerofy(number) {
417
- return (number < 10 ? '0' : '') + number;
418
- }
419
-
420
-
421
- /**
422
- * The calendar widget for RightJS
423
- *
424
- * Copyright (C) 2009-2011 Nikolay Nemshilov
425
- */
426
- var Calendar = new Widget({
427
- include: [Toggler, Assignable],
428
-
429
- extend: {
430
- version: '2.2.0',
431
-
432
- EVENTS: $w('show hide change done'),
433
-
434
- Options: {
435
- format: 'ISO', // a key out of the predefined formats or a format string
436
-
437
- showTime: null, // null for automatic, or true|false to enforce
438
- showButtons: false, // show the bottom buttons
439
-
440
- minDate: false, // the minimal date available
441
- maxDate: false, // the maximal date available
442
-
443
- fxName: 'fade', // set to null if you don't wanna any fx
444
- fxDuration: 'short', // the fx-duration
445
-
446
- firstDay: 1, // 1 for Monday, 0 for Sunday
447
- numberOfMonths: 1, // a number or [x, y] greed definition
448
- timePeriod: 1, // the timepicker minimal periods (in minutes, might be bigger than 60)
449
-
450
- twentyFourHour: null, // null for automatic, or true|false to enforce
451
- listYears: false, // show/hide the years listing buttons
452
-
453
- hideOnPick: false, // hides the popup when the user changes a day
454
-
455
- update: null, // a reference to an input element to assign to
456
- trigger: null, // a reference to a trigger element that would be paired too
457
-
458
- cssRule: '*[data-calendar]' // css rule for calendar related elements
459
- },
460
-
461
- Formats: {
462
- ISO: '%Y-%m-%d',
463
- POSIX: '%Y/%m/%d',
464
- EUR: '%d-%m-%Y',
465
- US: '%m/%d/%Y'
466
- },
467
-
468
- i18n: {
469
- Done: 'Done',
470
- Now: 'Now',
471
- NextMonth: 'Next Month',
472
- PrevMonth: 'Previous Month',
473
- NextYear: 'Next Year',
474
- PrevYear: 'Previous Year',
475
-
476
- dayNames: $w('Sunday Monday Tuesday Wednesday Thursday Friday Saturday'),
477
- dayNamesShort: $w('Sun Mon Tue Wed Thu Fri Sat'),
478
- dayNamesMin: $w('Su Mo Tu We Th Fr Sa'),
479
- monthNames: $w('January February March April May June July August September October November December'),
480
- monthNamesShort: $w('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec')
481
- },
482
-
483
- current: null,
484
-
485
- // hides all the popup calendars
486
- hideAll: function(that_one) {
487
- $$('div.rui-calendar').each(function(element) {
488
- if (element instanceof Calendar && element !== that_one && element.visible() && !element.inlined()) {
489
- element.hide();
490
- }
491
- });
492
- }
493
- },
494
-
495
- /**
496
- * Basic constructor
497
- *
498
- * @param Object options
499
- */
500
- initialize: function(options) {
501
- this.$super('calendar', options);
502
- this.addClass('rui-panel');
503
-
504
- options = this.options;
505
-
506
- this.insert([
507
- this.swaps = new Swaps(options),
508
- this.greed = new Greed(options)
509
- ]);
510
-
511
- if (options.showTime) {
512
- this.insert(this.timepicker = new Timepicker(options));
513
- }
514
-
515
- if (options.showButtons) {
516
- this.insert(this.buttons = new Buttons(options));
517
- }
518
-
519
- this.setDate(new Date()).initEvents();
520
- },
521
-
522
- /**
523
- * Sets the date on the calendar
524
- *
525
- * NOTE: if it's `true` then it will change the date but
526
- * won't shift the months greed (used in the days picking)
527
- *
528
- * @param Date date or String date
529
- * @param Boolean no-shifting mode
530
- * @return Calendar this
531
- */
532
- setDate: function(date, no_shift) {
533
- if ((date = this.parse(date))) {
534
- var options = this.options;
535
-
536
- // checking the date range constrains
537
- if (options.minDate && options.minDate > date) {
538
- date = new Date(options.minDate);
539
- }
540
- if (options.maxDate && options.maxDate < date) {
541
- date = new Date(options.maxDate);
542
- date.setDate(date.getDate() - 1);
543
- }
544
-
545
- // setting the dates greed
546
- this._date = no_shift ? new Date(this._date || this.date) : null;
547
- this.greed.setDate(this._date || date, date);
548
-
549
- // updating the shifters state
550
- if (options.minDate || options.maxDate) {
551
- this.swaps.setDate(date);
552
- }
553
-
554
- // updating the time-picker
555
- if (this.timepicker && !no_shift) {
556
- this.timepicker.setDate(date);
557
- }
558
-
559
- if (date != this.date) {
560
- this.fire('change', {date: this.date = date});
561
- }
562
- }
563
-
564
- return this;
565
- },
566
-
567
- /**
568
- * Returns the current date on the calendar
569
- *
570
- * @return Date currently selected date on the calendar
571
- */
572
- getDate: function() {
573
- return this.date;
574
- },
575
-
576
- /**
577
- * Sets the value as a string
578
- *
579
- * @param String value
580
- * @return Calendar this
581
- */
582
- setValue: function(value) {
583
- return this.setDate(value);
584
- },
585
-
586
- /**
587
- * Returns the value as a string
588
- *
589
- * @param String optional format
590
- * @return String formatted date
591
- */
592
- getValue: function(format) {
593
- return this.format(format);
594
- },
595
-
596
- /**
597
- * Inserts the calendar into the element making it inlined
598
- *
599
- * @param Element element or String element id
600
- * @param String optional position top/bottom/before/after/instead, 'bottom' is default
601
- * @return Calendar this
602
- */
603
- insertTo: function(element, position) {
604
- this.addClass('rui-calendar-inline');
605
- return this.$super(element, position);
606
- },
607
-
608
- /**
609
- * Marks it done
610
- *
611
- * @return Calendar this
612
- */
613
- done: function() {
614
- if (!this.inlined()) {
615
- this.hide();
616
- }
617
-
618
- this.fire('done', {date: this.date});
619
- },
620
-
621
- /**
622
- * Checks if the calendar is inlined
623
- *
624
- * @return boolean check
625
- */
626
- inlined: function() {
627
- return this.hasClass('rui-calendar-inline');
628
- },
629
-
630
- // protected
631
-
632
- /**
633
- * additional options processing
634
- *
635
- * @param Object options
636
- * @return Calendar this
637
- */
638
- setOptions: function(user_options) {
639
- user_options = user_options || {};
640
- this.$super(user_options, $(user_options.trigger || user_options.update));
641
-
642
- var klass = this.constructor, options = this.options;
643
-
644
- // merging the i18n tables
645
- options.i18n = {};
646
-
647
- for (var key in klass.i18n) {
648
- options.i18n[key] = isArray(klass.i18n[key]) ? klass.i18n[key].clone() : klass.i18n[key];
649
- }
650
- $ext(options.i18n, user_options.i18n);
651
-
652
- // defining the current days sequence
653
- options.dayNames = options.i18n.dayNamesMin;
654
- if (options.firstDay) {
655
- options.dayNames.push(options.dayNames.shift());
656
- }
657
-
658
- // the monthes table cleaning up
659
- if (!isArray(options.numberOfMonths)) {
660
- options.numberOfMonths = [options.numberOfMonths, 1];
661
- }
662
-
663
- // min/max dates preprocessing
664
- if (options.minDate) {
665
- options.minDate = this.parse(options.minDate);
666
- }
667
- if (options.maxDate) {
668
- options.maxDate = this.parse(options.maxDate);
669
- options.maxDate.setDate(options.maxDate.getDate() + 1);
670
- }
671
-
672
- // format catching up
673
- options.format = R(klass.Formats[options.format] || options.format).trim();
674
-
675
- // setting up the showTime option
676
- if (options.showTime === null) {
677
- options.showTime = options.format.search(/%[HkIl]/) > -1;
678
- }
679
-
680
- // setting up the 24-hours format
681
- if (options.twentyFourHour === null) {
682
- options.twentyFourHour = options.format.search(/%[Il]/) < 0;
683
- }
684
-
685
- // enforcing the 24 hours format if the time threshold is some weird number
686
- if (options.timePeriod > 60 && 12 % Math.ceil(options.timePeriod/60)) {
687
- options.twentyFourHour = true;
688
- }
689
-
690
- if (options.update) {
691
- this.assignTo(options.update, options.trigger);
692
- }
693
-
694
- return this;
695
- },
696
-
697
- /**
698
- * hides all the other calendars on the page
699
- *
700
- * @return Calendar this
701
- */
702
- hideOthers: function() {
703
- Calendar.hideAll(this);
704
- return this;
705
- }
706
- });
707
-
708
-
709
- /**
710
- * The calendar month/year swapping buttons block
711
- *
712
- * Copyright (C) 2010-2011 Nikolay Nemshilov
713
- */
714
- var Swaps = new Class(Element, {
715
- /**
716
- * Constructor
717
- *
718
- * @param Object options
719
- * @return void
720
- */
721
- initialize: function(options) {
722
- this.$super('div', {'class': 'swaps'});
723
- this.options = options;
724
-
725
- var i18n = options.i18n;
726
-
727
- this.insert([
728
- this.prevMonth = new Button('&lsaquo;', {title: i18n.PrevMonth, 'class': 'prev-month'}),
729
- this.nextMonth = new Button('&rsaquo;', {title: i18n.NextMonth, 'class': 'next-month'})
730
- ]);
731
-
732
- if (options.listYears) {
733
- this.insert([
734
- this.prevYear = new Button('&laquo;', {title: i18n.PrevYear, 'class': 'prev-year'}),
735
- this.nextYear = new Button('&raquo;', {title: i18n.NextYear, 'class': 'next-year'})
736
- ]);
737
- }
738
-
739
- this.buttons = R([this.prevMonth, this.nextMonth, this.prevYear, this.nextYear]).compact();
740
-
741
- this.onClick(this.clicked);
742
- },
743
-
744
- /**
745
- * Changes the swapping buttons state depending on the options and the current date
746
- *
747
- * @param Date date
748
- * @return void
749
- */
750
- setDate: function(date) {
751
- var options = this.options, months_num = options.numberOfMonths[0] * options.numberOfMonths[1],
752
- has_prev_year = true, has_next_year = true, has_prev_month = true, has_next_month = true;
753
-
754
- if (options.minDate) {
755
- var beginning = new Date(date.getFullYear(),0,1,0,0,0);
756
- var min_date = new Date(options.minDate.getFullYear(),0,1,0,0,0);
757
-
758
- has_prev_year = beginning > min_date;
759
-
760
- beginning.setMonth(date.getMonth() - Math.ceil(months_num - months_num/2));
761
- min_date.setMonth(options.minDate.getMonth());
762
-
763
- has_prev_month = beginning >= min_date;
764
- }
765
-
766
- if (options.maxDate) {
767
- var end = new Date(date);
768
- var max_date = new Date(options.maxDate);
769
- var dates = R([end, max_date]);
770
- dates.each(function(date) {
771
- date.setDate(32);
772
- date.setMonth(date.getMonth() - 1);
773
- date.setDate(32 - date.getDate());
774
- date.setHours(0);
775
- date.setMinutes(0);
776
- date.setSeconds(0);
777
- date.setMilliseconds(0);
778
- });
779
-
780
- has_next_month = end < max_date;
781
-
782
- // checking the next year
783
- dates.each('setMonth', 0);
784
- has_next_year = end < max_date;
785
- }
786
-
787
- this.nextMonth[has_next_month ? 'enable':'disable']();
788
- this.prevMonth[has_prev_month ? 'enable':'disable']();
789
-
790
- if (this.nextYear) {
791
- this.nextYear[has_next_year ? 'enable':'disable']();
792
- this.prevYear[has_prev_year ? 'enable':'disable']();
793
- }
794
- },
795
-
796
- // protected
797
-
798
- // handles the clicks on the
799
- clicked: function(event) {
800
- var target = event.target;
801
- if (target && this.buttons.include(target)) {
802
- if (target.enabled()) {
803
- this.fire(target.get('className').split(/\s+/)[0]);
804
- }
805
- }
806
- }
807
- });
808
-
809
-
810
- /**
811
- * Represents a single month block
812
- *
813
- * Copyright (C) 2010-2011 Nikolay Nemshilov
814
- */
815
- var Month = new Class(Element, {
816
- /**
817
- * Constructor
818
- *
819
- * @param Object options
820
- * @return void
821
- */
822
- initialize: function(options) {
823
- this.$super('table', {'class': 'month'});
824
- this.options = options;
825
-
826
- // the caption (for the month name)
827
- this.insert(this.caption = new Element('caption'));
828
-
829
- // the headline for the day-names
830
- this.insert('<thead><tr>'+
831
- options.dayNames.map(function(name) {return '<th>'+ name +'</th>';}).join('') +
832
- '</tr></thead>');
833
-
834
- // the body with the day-cells
835
- this.days = [];
836
-
837
- var tbody = new Element('tbody').insertTo(this), x, y, row;
838
-
839
- for (y=0; y < 6; y++) {
840
- row = new Element('tr').insertTo(tbody);
841
- for (x=0; x < 7; x++) {
842
- this.days.push(new Element('td').insertTo(row));
843
- }
844
- }
845
-
846
- this.onClick(this.clicked);
847
- },
848
-
849
- /**
850
- * Initializes the month values by the date
851
- *
852
- * @param Date date
853
- * @return void
854
- */
855
- setDate: function(date, current_date) {
856
- // getting the number of days in the month
857
- date.setDate(32);
858
- var days_number = 32 - date.getDate();
859
- date.setMonth(date.getMonth()-1);
860
-
861
- var cur_day = Math.ceil(current_date.getTime() / 86400000),
862
- options = this.options, i18n = options.i18n, days = this.days;
863
-
864
- // resetting the first and last two weeks cells
865
- // because there will be some empty cells over there
866
- for (var i=0, len = days.length-1, one, two, tre; i < 7; i++) {
867
- one = days[i]._;
868
- two = days[len - i]._;
869
- tre = days[len - i - 7]._;
870
-
871
- one.innerHTML = two.innerHTML = tre.innerHTML = '';
872
- one.className = two.className = tre.className = 'blank';
873
- }
874
-
875
- // putting the actual day numbers in place
876
- for (var i=1, row=0, week, cell; i <= days_number; i++) {
877
- date.setDate(i);
878
- var day_num = date.getDay();
879
-
880
- if (options.firstDay === 1) { day_num = day_num > 0 ? day_num-1 : 6; }
881
- if (i === 1 || day_num === 0) {
882
- week = days.slice(row*7, row*7 + 7); row ++;
883
- }
884
-
885
- cell = week[day_num]._;
886
-
887
- if (Browser.OLD) { // IE6 has a nasty glitch with that
888
- cell.innerHTML = '';
889
- cell.appendChild(document.createTextNode(i));
890
- } else {
891
- cell.innerHTML = ''+i;
892
- }
893
-
894
- cell.className = cur_day === Math.ceil(date.getTime() / 86400000) ? 'selected' : '';
895
-
896
- if ((options.minDate && options.minDate > date) || (options.maxDate && options.maxDate < date)) {
897
- cell.className = 'disabled';
898
- }
899
-
900
- week[day_num].date = new Date(date);
901
- }
902
-
903
- // setting up the caption with the month name
904
- var caption = (options.listYears ?
905
- i18n.monthNamesShort[date.getMonth()] + ',' :
906
- i18n.monthNames[date.getMonth()])+
907
- ' '+date.getFullYear(),
908
- element = this.caption._;
909
-
910
- if (Browser.OLD) {
911
- element.innerHTML = '';
912
- element.appendChild(document.createTextNode(caption));
913
- } else {
914
- element.innerHTML = caption;
915
- }
916
- },
917
-
918
- // protected
919
-
920
- /**
921
- * Handles clicks on the day-cells
922
- *
923
- * @param Event click event
924
- * @return void
925
- */
926
- clicked: function(event) {
927
- var target = event.target, date = target.date;
928
-
929
- if (target && date && !target.hasClass('disabled') && !target.hasClass('blank')) {
930
- target.addClass('selected');
931
-
932
- this.fire('date-set', {
933
- date: date.getDate(),
934
- month: date.getMonth(),
935
- year: date.getFullYear()
936
- });
937
- }
938
- }
939
- });
940
-
941
-
942
- /**
943
- * The calendar months greed unit
944
- *
945
- * Copyright (C) 2010-2011 Nikolay Nemshilov
946
- */
947
- var Greed = new Class(Element, {
948
- /**
949
- * Constructor
950
- *
951
- * @param Object options
952
- * @return void
953
- */
954
- initialize: function(options) {
955
- this.$super('table', {'class': 'greed'});
956
-
957
- this.months = [];
958
-
959
- var tbody = new Element('tbody').insertTo(this), month;
960
-
961
- for (var y=0; y < options.numberOfMonths[1]; y++) {
962
- var row = new Element('tr').insertTo(tbody);
963
- for (var x=0; x < options.numberOfMonths[0]; x++) {
964
- this.months.push(month = new Month(options));
965
- new Element('td').insertTo(row).insert(month);
966
- }
967
- }
968
- },
969
-
970
- /**
971
- * Sets the months to the date
972
- *
973
- * @param Date date in the middle of the greed
974
- * @param the current date (might be different)
975
- * @return void
976
- */
977
- setDate: function(date, current_date) {
978
- var months = this.months, months_num = months.length;
979
-
980
- current_date = current_date || date;
981
-
982
- for (var i=-Math.ceil(months_num - months_num/2)+1,j=0; i < Math.floor(months_num - months_num/2)+1; i++,j++) {
983
- var month_date = new Date(date);
984
- month_date.setMonth(date.getMonth() + i);
985
- months[j].setDate(month_date, current_date);
986
- }
987
- }
988
- });
989
-
990
-
991
- /**
992
- * The time-picker block unit
993
- *
994
- * Copyright (C) 2010-2011 Nikolay Nemshilov
995
- */
996
- var Timepicker = new Class(Element, {
997
- /**
998
- * Constructor
999
- *
1000
- * @param Object options
1001
- * @return void
1002
- */
1003
- initialize: function(options) {
1004
- this.$super('div', {'class': 'timepicker'});
1005
- this.options = options;
1006
-
1007
- var on_change = R(this.timeChanged).bind(this);
1008
-
1009
- this.insert([
1010
- this.hours = new Element('select').onChange(on_change),
1011
- this.minutes = new Element('select').onChange(on_change)
1012
- ]);
1013
-
1014
- var minutes_threshold = options.timePeriod < 60 ? options.timePeriod : 60;
1015
- var hours_threshold = options.timePeriod < 60 ? 1 : Math.ceil(options.timePeriod / 60);
1016
-
1017
- for (var i=0; i < 60; i++) {
1018
- var caption = zerofy(i);
1019
-
1020
- if (i < 24 && i % hours_threshold == 0) {
1021
- if (options.twentyFourHour) {
1022
- this.hours.insert(new Element('option', {value: i, html: caption}));
1023
- } else if (i < 12) {
1024
- this.hours.insert(new Element('option', {value: i, html: i == 0 ? 12 : i}));
1025
- }
1026
- }
1027
-
1028
- if (i % minutes_threshold == 0) {
1029
- this.minutes.insert(new Element('option', {value: i, html: caption}));
1030
- }
1031
- }
1032
-
1033
-
1034
- // adding the meridian picker if it's a 12 am|pm picker
1035
- if (!options.twentyFourHour) {
1036
- this.meridian = new Element('select').onChange(on_change).insertTo(this);
1037
-
1038
- R(R(options.format).includes(/%P/) ? ['am', 'pm'] : ['AM', 'PM']).each(function(value) {
1039
- this.meridian.insert(new Element('option', {value: value.toLowerCase(), html: value}));
1040
- }, this);
1041
- }
1042
- },
1043
-
1044
- /**
1045
- * Sets the time-picker values by the data
1046
- *
1047
- * @param Date date
1048
- * @return void
1049
- */
1050
- setDate: function(date) {
1051
- var options = this.options;
1052
- var hour = options.timePeriod < 60 ? date.getHours() :
1053
- Math.round(date.getHours()/(options.timePeriod/60)) * (options.timePeriod/60);
1054
- var minute = Math.round(date.getMinutes() / (options.timePeriod % 60)) * options.timePeriod;
1055
-
1056
- if (this.meridian) {
1057
- this.meridian.setValue(hour < 12 ? 'am' : 'pm');
1058
- hour = (hour == 0 || hour == 12) ? 12 : hour > 12 ? (hour - 12) : hour;
1059
- }
1060
-
1061
- this.hours.setValue(hour);
1062
- this.minutes.setValue(minute);
1063
- },
1064
-
1065
- // protected
1066
-
1067
- /**
1068
- * Handles the time-picking events
1069
- *
1070
- * @return void
1071
- */
1072
- timeChanged: function(event) {
1073
- event.stopPropagation();
1074
-
1075
- var hours = parseInt(this.hours.value());
1076
- var minutes = parseInt(this.minutes.value());
1077
-
1078
- if (this.meridian) {
1079
- if (hours == 12) {
1080
- hours = 0;
1081
- }
1082
- if (this.meridian.value() == 'pm') {
1083
- hours += 12;
1084
- }
1085
- }
1086
-
1087
- this.fire('time-set', {hours: hours, minutes: minutes});
1088
- }
1089
- });
1090
-
1091
-
1092
- /**
1093
- * The bottom-buttons block unit
1094
- *
1095
- * Copyright (C) 2010 Nikolay Nemshilov
1096
- */
1097
- var Buttons = new Class(Element, {
1098
- /**
1099
- * Constructor
1100
- *
1101
- * @param Object options
1102
- * @return void
1103
- */
1104
- initialize: function(options) {
1105
- this.$super('div', {'class': 'buttons'});
1106
-
1107
- this.insert([
1108
- new Button(options.i18n.Now, {'class': 'now'}).onClick('fire', 'now-clicked'),
1109
- new Button(options.i18n.Done, {'class': 'done'}).onClick('fire', 'done-clicked')
1110
- ]);
1111
- }
1112
- });
1113
-
1114
-
1115
- /**
1116
- * This module handles the dates parsing/formatting processes
1117
- *
1118
- * To format dates and times this scripts use the GNU (C/Python/Ruby) strftime
1119
- * function formatting principles
1120
- *
1121
- * %a - The abbreviated weekday name (``Sun'')
1122
- * %A - The full weekday name (``Sunday'')
1123
- * %b - The abbreviated month name (``Jan'')
1124
- * %B - The full month name (``January'')
1125
- * %d - Day of the month (01..31)
1126
- * %e - Day of the month without leading zero (1..31)
1127
- * %m - Month of the year (01..12)
1128
- * %y - Year without a century (00..99)
1129
- * %Y - Year with century
1130
- * %H - Hour of the day, 24-hour clock (00..23)
1131
- * %k - Hour of the day, 24-hour clock without leading zero (0..23)
1132
- * %I - Hour of the day, 12-hour clock (01..12)
1133
- * %l - Hour of the day, 12-hour clock without leading zer (0..12)
1134
- * %p - Meridian indicator (``AM'' or ``PM'')
1135
- * %P - Meridian indicator (``pm'' or ``pm'')
1136
- * %M - Minute of the hour (00..59)
1137
- * %S - Second of the minute (00..60)
1138
- * %% - Literal ``%'' character
1139
- *
1140
- * Copyright (C) 2009-2010 Nikolay V. Nemshilov
1141
- */
1142
- Calendar.include({
1143
-
1144
- /**
1145
- * Parses out the given string based on the current date formatting
1146
- *
1147
- * @param String string date
1148
- * @return Date parsed date or null if it wasn't parsed
1149
- */
1150
- parse: function(string) {
1151
- var date;
1152
-
1153
- if (isString(string) && string) {
1154
- var tpl = RegExp.escape(this.options.format);
1155
- var holders = R(tpl.match(/%[a-z]/ig)).map('match', /[a-z]$/i).map('first').without('%');
1156
- var re = new RegExp('^'+tpl.replace(/%p/i, '(pm|PM|am|AM)').replace(/(%[a-z])/ig, '(.+?)')+'$');
1157
-
1158
- var match = R(string).trim().match(re);
1159
-
1160
- if (match) {
1161
- match.shift();
1162
-
1163
- var year = null, month = null, hour = null, minute = null, second = null, meridian;
1164
-
1165
- while (match.length) {
1166
- var value = match.shift();
1167
- var key = holders.shift();
1168
-
1169
- if (key.toLowerCase() == 'b') {
1170
- month = this.options.i18n[key=='b' ? 'monthNamesShort' : 'monthNames'].indexOf(value);
1171
- } else if (key.toLowerCase() == 'p') {
1172
- meridian = value.toLowerCase();
1173
- } else {
1174
- value = parseInt(value, 10);
1175
- switch(key) {
1176
- case 'd':
1177
- case 'e': date = value; break;
1178
- case 'm': month = value-1; break;
1179
- case 'y':
1180
- case 'Y': year = value; break;
1181
- case 'H':
1182
- case 'k':
1183
- case 'I':
1184
- case 'l': hour = value; break;
1185
- case 'M': minute = value; break;
1186
- case 'S': second = value; break;
1187
- }
1188
- }
1189
- }
1190
-
1191
- // converting 1..12am|pm into 0..23 hours marker
1192
- if (meridian) {
1193
- hour = hour == 12 ? 0 : hour;
1194
- hour = (meridian == 'pm' ? hour + 12 : hour);
1195
- }
1196
-
1197
- date = new Date(year, month, date, hour, minute, second);
1198
- }
1199
- } else if (string instanceof Date || Date.parse(string)) {
1200
- date = new Date(string);
1201
- }
1202
-
1203
- return (!date || isNaN(date.getTime())) ? null : date;
1204
- },
1205
-
1206
- /**
1207
- * Formats the current date into a string depend on the current or given format
1208
- *
1209
- * @param String optional format
1210
- * @return String formatted data
1211
- */
1212
- format: function(format) {
1213
- var i18n = this.options.i18n;
1214
- var day = this.date.getDay();
1215
- var month = this.date.getMonth();
1216
- var date = this.date.getDate();
1217
- var year = this.date.getFullYear();
1218
- var hour = this.date.getHours();
1219
- var minute = this.date.getMinutes();
1220
- var second = this.date.getSeconds();
1221
-
1222
- var hour_ampm = (hour == 0 ? 12 : hour < 13 ? hour : hour - 12);
1223
-
1224
- var values = {
1225
- a: i18n.dayNamesShort[day],
1226
- A: i18n.dayNames[day],
1227
- b: i18n.monthNamesShort[month],
1228
- B: i18n.monthNames[month],
1229
- d: zerofy(date),
1230
- e: ''+date,
1231
- m: (month < 9 ? '0' : '') + (month+1),
1232
- y: (''+year).substring(2,4),
1233
- Y: ''+year,
1234
- H: zerofy(hour),
1235
- k: '' + hour,
1236
- I: (hour > 0 && (hour < 10 || (hour > 12 && hour < 22)) ? '0' : '') + hour_ampm,
1237
- l: '' + hour_ampm,
1238
- p: hour < 12 ? 'AM' : 'PM',
1239
- P: hour < 12 ? 'am' : 'pm',
1240
- M: zerofy(minute),
1241
- S: zerofy(second),
1242
- '%': '%'
1243
- };
1244
-
1245
- var result = format || this.options.format;
1246
- for (var key in values) {
1247
- result = result.replace('%'+key, values[key]);
1248
- }
1249
-
1250
- return result;
1251
- }
1252
- });
1253
-
1254
-
1255
- /**
1256
- * This module handles the events connection
1257
- *
1258
- * Copyright (C) 2009-2010 Nikolay Nemshilov
1259
- */
1260
- Calendar.include({
1261
-
1262
- // protected
1263
-
1264
- // connects the events with handlers
1265
- initEvents: function() {
1266
- var shift = '_shiftDate', terminate = this._terminate;
1267
-
1268
- this.on({
1269
- // the dates/months/etc listing events
1270
- 'prev-day': [shift, {Date: -1}],
1271
- 'next-day': [shift, {Date: 1}],
1272
- 'prev-week': [shift, {Date: -7}],
1273
- 'next-week': [shift, {Date: 7}],
1274
- 'prev-month': [shift, {Month: -1}],
1275
- 'next-month': [shift, {Month: 1}],
1276
- 'prev-year': [shift, {FullYear: -1}],
1277
- 'next-year': [shift, {FullYear: 1}],
1278
-
1279
- // the date/time picking events
1280
- 'date-set': this._changeDate,
1281
- 'time-set': this._changeTime,
1282
-
1283
- // the bottom buttons events
1284
- 'now-clicked': this._setNow,
1285
- 'done-clicked': this.done,
1286
-
1287
- // handling the clicks
1288
- 'click': terminate,
1289
- 'mousedown': terminate,
1290
- 'focus': terminate,
1291
- 'blur': terminate
1292
- });
1293
- },
1294
-
1295
- // shifts the date according to the params
1296
- _shiftDate: function(params) {
1297
- var date = new Date(this.date), options = this.options;
1298
-
1299
- // shifting the date according to the params
1300
- for (var key in params) {
1301
- date['set'+key](date['get'+key]() + params[key]);
1302
- }
1303
-
1304
- this.setDate(date);
1305
- },
1306
-
1307
- // changes the current date (not the time)
1308
- _changeDate: function(event) {
1309
- var date = new Date(this.date);
1310
-
1311
- date.setDate(event.date);
1312
- date.setMonth(event.month);
1313
- date.setFullYear(event.year);
1314
-
1315
- this.setDate(date, true); // <- `true` means just change the date without shifting the list
1316
-
1317
- if (this.options.hideOnPick) {
1318
- this.done();
1319
- }
1320
- },
1321
-
1322
- // changes the current time (not the date)
1323
- _changeTime: function(event) {
1324
- var date = new Date(this.date);
1325
-
1326
- date.setHours(event.hours);
1327
- date.setMinutes(event.minutes);
1328
-
1329
- this.setDate(date);
1330
- },
1331
-
1332
- // resets the calendar to the current time
1333
- _setNow: function() {
1334
- this.setDate(new Date());
1335
- },
1336
-
1337
- /** simply stops the event so we didn't bother the things outside of the object
1338
- *
1339
- * @param {Event} event
1340
- * @return void
1341
- * @private
1342
- */
1343
- _terminate: function(event) {
1344
- event.stopPropagation(); // don't let the clicks go anywere out of the clanedar
1345
-
1346
- if (this._hide_delay) {
1347
- this._hide_delay.cancel();
1348
- this._hide_delay = null;
1349
- }
1350
- }
1351
- });
1352
-
1353
-
1354
- /**
1355
- * Document level event listeners for navigation and lazy initialization
1356
- *
1357
- * Copyright (C) 2009-2010 Nikolay Nemshilov
1358
- */
1359
- $(document).on({
1360
- /**
1361
- * Watches the focus events and dispalys the calendar
1362
- * popups when there is a related input element
1363
- *
1364
- * @param Event focus-event
1365
- * @return void
1366
- */
1367
- focus: function(event) {
1368
- var target = event.target instanceof Input && event.target.get('type') == 'text' ? event.target : null;
1369
-
1370
- Calendar.hideAll();
1371
-
1372
- if (target && (target.calendar || target.match(Calendar.Options.cssRule))) {
1373
- (target.calendar || new Calendar({update: target}))
1374
- .setValue(target.value()).showAt(target);
1375
- }
1376
- },
1377
-
1378
- /**
1379
- * Watches the input elements blur events
1380
- * and hides shown popups
1381
- *
1382
- * @param Event blur-event
1383
- * @return void
1384
- */
1385
- blur: function(event) {
1386
- var target = event.target, calendar = target.calendar;
1387
-
1388
- if (calendar) {
1389
- // we use the delay so it didn't get hidden when the user clicks the calendar itself
1390
- calendar._hide_delay = R(function() {
1391
- calendar.hide();
1392
- }).delay(200);
1393
- }
1394
- },
1395
-
1396
- /**
1397
- * Catches clicks on trigger elements
1398
- *
1399
- * @param Event click
1400
- * @return void
1401
- */
1402
- click: function(event) {
1403
- var target = (event.target instanceof Element) ? event.target : null;
1404
-
1405
- if (target && (target.calendar || target.match(Calendar.Options.cssRule))) {
1406
- if (!(target instanceof Input) || target.get('type') != 'text') {
1407
- event.stop();
1408
- (target.calendar || new Calendar({trigger: target}))
1409
- .hide(null).toggleAt(target.assignedInput);
1410
- }
1411
- } else if (!event.find('div.rui-calendar')){
1412
- Calendar.hideAll();
1413
- }
1414
- },
1415
-
1416
- /**
1417
- * Catching the key-downs to navigate in the currently
1418
- * opened Calendar hover
1419
- *
1420
- * @param Event event
1421
- * @return void
1422
- */
1423
- keydown: function(event) {
1424
- var calendar = Calendar.current, name = ({
1425
- 27: 'hide', // Escape
1426
- 37: 'prev-day', // Left Arrow
1427
- 39: 'next-day', // Right Arrow
1428
- 38: 'prev-week', // Up Arrow
1429
- 40: 'next-week', // Down Arrow
1430
- 33: 'prev-month', // Page Up
1431
- 34: 'next-month', // Page Down
1432
- 13: 'done' // Enter
1433
- })[event.keyCode];
1434
-
1435
- if (name && calendar && calendar.visible()) {
1436
- event.stop();
1437
- if (isFunction(calendar[name])) {
1438
- calendar[name]();
1439
- } else {
1440
- calendar.fire(name);
1441
- }
1442
- }
1443
- }
1444
- });
1445
- (function() {
1446
- var style = document.createElement('style'),
1447
- rules = document.createTextNode(".rui-panel{margin:0;padding:.5em;position:relative;background-color:#EEE;border:1px solid #BBB;border-radius:.3em;-moz-border-radius:.3em;-webkit-border-radius:.3em;box-shadow:.15em .3em .5em #BBB;-moz-box-shadow:.15em .3em .5em #BBB;-webkit-box-shadow:.15em .3em .5em #BBB;cursor:default} *.rui-button{display:inline-block; *display:inline; *zoom:1;height:1em;line-height:1em;margin:0;padding:.2em .5em;text-align:center;border:1px solid #CCC;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em;cursor:pointer;color:#333;background-color:#FFF;user-select:none;-moz-user-select:none;-webkit-user-select:none} *.rui-button:hover{color:#111;border-color:#999;background-color:#DDD;box-shadow:#888 0 0 .1em;-moz-box-shadow:#888 0 0 .1em;-webkit-box-shadow:#888 0 0 .1em} *.rui-button:active{color:#000;border-color:#777;text-indent:1px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none} *.rui-button-disabled, *.rui-button-disabled:hover, *.rui-button-disabled:active{color:#888;background:#DDD;border-color:#CCC;cursor:default;text-indent:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}div.rui-re-anchor{margin:0;padding:0;background:none;border:none;float:none;display:inline;position:absolute;z-index:9999}div.rui-calendar .swaps,div.rui-calendar .greed,div.rui-calendar .timepicker,div.rui-calendar .buttons,div.rui-calendar table,div.rui-calendar table tr,div.rui-calendar table th,div.rui-calendar table td,div.rui-calendar table tbody,div.rui-calendar table thead,div.rui-calendar table caption{background:none;border:none;width:auto;height:auto;margin:0;padding:0}div.rui-calendar-inline{position:relative;display:inline-block; *display:inline; *zoom:1;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}div.rui-calendar .swaps{position:relative}div.rui-calendar .swaps .rui-button{position:absolute;float:left;width:1em;padding:.15em .4em}div.rui-calendar .swaps .next-month{right:0em;_right:.5em}div.rui-calendar .swaps .prev-year{left:2.05em}div.rui-calendar .swaps .next-year{right:2.05em;_right:2.52em}div.rui-calendar .greed{border-spacing:0px;border-collapse:collapse;border-size:0}div.rui-calendar .greed td{vertical-align:top;padding-left:.4em}div.rui-calendar .greed>tbody>tr>td:first-child{padding:0}div.rui-calendar .month{margin-top:.2em;border-spacing:1px;border-collapse:separate}div.rui-calendar .month caption{text-align:center}div.rui-calendar .month th{color:#666;text-align:center}div.rui-calendar .month td{text-align:right;padding:.1em .3em;background-color:#FFF;border:1px solid #CCC;cursor:pointer;color:#555;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em}div.rui-calendar .month td:hover{background-color:#CCC;border-color:#AAA;color:#000}div.rui-calendar .month td.blank{background:transparent;cursor:default;border:none}div.rui-calendar .month td.selected{background-color:#BBB;border-color:#AAA;color:#222;font-weight:bold;padding:.1em .2em}div.rui-calendar .month td.disabled{color:#888;background:#EEE;border-color:#CCC;cursor:default}div.rui-calendar .timepicker{border-top:1px solid #ccc;margin-top:.3em;padding-top:.5em;text-align:center}div.rui-calendar .timepicker select{margin:0 .4em}div.rui-calendar .buttons{position:relative;margin-top:.5em}div.rui-calendar .buttons div.rui-button{width:4em;padding:.25em .5em}div.rui-calendar .buttons .done{position:absolute;right:0em;top:0}");
1448
-
1449
- style.type = 'text/css';
1450
-
1451
- if(style.styleSheet) {
1452
- style.styleSheet.cssText = rules.nodeValue;
1453
- } else {
1454
- style.appendChild(rules);
1455
- }
1456
-
1457
- document.getElementsByTagName('head')[0].appendChild(style);
1458
- })();
1459
-
1460
- return Calendar;
1461
- })(document, parseInt, RightJS);