puffer 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/app/helpers/puffer_helper.rb +8 -0
- data/app/views/layouts/puffer.html.erb +5 -11
- data/lib/generators/puffer/install/install_generator.rb +2 -2
- data/lib/generators/puffer/install/templates/puffer.rb +12 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/{application.js → puffer.js} +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/{rails-src.js → rails.js} +0 -0
- data/lib/puffer.rb +14 -0
- data/lib/puffer/controller/mutate.rb +8 -2
- data/lib/puffer/extensions/mapper.rb +2 -2
- data/lib/puffer/inputs.rb +1 -1
- data/lib/puffer/path_set.rb +14 -7
- data/lib/puffer/resource.rb +1 -1
- data/puffer.gemspec +8 -44
- data/spec/dummy/config/initializers/puffer.rb +12 -0
- data/spec/dummy/public/puffer/javascripts/{application.js → puffer.js} +0 -0
- data/spec/dummy/public/puffer/javascripts/{rails-src.js → rails.js} +0 -0
- metadata +10 -46
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-autocompleter-src.js +0 -621
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-autocompleter.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-calendar-src.js +0 -1461
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-calendar.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-in-edit-src.js +0 -369
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-in-edit.js +0 -13
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-in-edit.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-lightbox-src.js +0 -905
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-lightbox.js +0 -24
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-lightbox.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-sortable-src.js +0 -428
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-sortable.js +0 -17
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-sortable.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-src.js +0 -5892
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-tabs-src.js +0 -1145
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-tabs.js +0 -29
- data/lib/generators/puffer/install/templates/puffer/javascripts/right-tabs.js.gz +0 -0
- data/lib/generators/puffer/install/templates/puffer/javascripts/right.js.gz +0 -0
- data/spec/dummy/config/puffer.rb +0 -0
- data/spec/dummy/public/puffer/javascripts/right-autocompleter-src.js +0 -621
- data/spec/dummy/public/puffer/javascripts/right-autocompleter.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right-calendar-src.js +0 -1461
- data/spec/dummy/public/puffer/javascripts/right-calendar.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right-in-edit-src.js +0 -369
- data/spec/dummy/public/puffer/javascripts/right-in-edit.js +0 -13
- data/spec/dummy/public/puffer/javascripts/right-in-edit.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right-lightbox-src.js +0 -905
- data/spec/dummy/public/puffer/javascripts/right-lightbox.js +0 -24
- data/spec/dummy/public/puffer/javascripts/right-lightbox.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right-sortable-src.js +0 -428
- data/spec/dummy/public/puffer/javascripts/right-sortable.js +0 -17
- data/spec/dummy/public/puffer/javascripts/right-sortable.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right-src.js +0 -5892
- data/spec/dummy/public/puffer/javascripts/right-tabs-src.js +0 -1145
- data/spec/dummy/public/puffer/javascripts/right-tabs.js +0 -29
- data/spec/dummy/public/puffer/javascripts/right-tabs.js.gz +0 -0
- data/spec/dummy/public/puffer/javascripts/right.js.gz +0 -0
Binary file
|
@@ -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('‹', {title: i18n.PrevMonth, 'class': 'prev-month'}),
|
729
|
-
this.nextMonth = new Button('›', {title: i18n.NextMonth, 'class': 'next-month'})
|
730
|
-
]);
|
731
|
-
|
732
|
-
if (options.listYears) {
|
733
|
-
this.insert([
|
734
|
-
this.prevYear = new Button('«', {title: i18n.PrevYear, 'class': 'prev-year'}),
|
735
|
-
this.nextYear = new Button('»', {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);
|