kolo 0.6.8 → 0.6.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5ef38089284ea8b6f3a16236122f0fe21c9828c
4
- data.tar.gz: 0e54d0624c639853a5393b846525384c524cb1d5
3
+ metadata.gz: 921b9e90304df02753965f1812a7c5866abfa179
4
+ data.tar.gz: bd8a1cebabbdc185d55fc7c847e554ea28098d7e
5
5
  SHA512:
6
- metadata.gz: 639abf179c3cd0ad5afb5ad2538e30287147a90b89a150cb564de83149fb2ff3a9d2685c56ff2f07b1a2e542360cad22662eda31f9cedc718a97150d0fe5e971
7
- data.tar.gz: 63cff983dd4757054057360351465984e6cdf26cf63329b4b83836a07550a688d6ee82760cc7ce602d7e582c12700bc9c299fa9a894f6c4b5a19c0a9d9fbf477
6
+ metadata.gz: db23c23dcd0d87ab6d93a26c3743433317c7d5cfdab1f60216141c1917fa67411d858d580200c21c7a550638f8022117266a15244c57a180a467b2617c4dd1c3
7
+ data.tar.gz: 82f778ae373f0ed512c9055699eaa174c6c4e865c21b8609a9beb99da8909bd9ccfe912e0e6f1b232d5684b0913fef1f6acfd8315a81d78b91b137c5d7e9e903
@@ -0,0 +1,474 @@
1
+ /* =========================================================
2
+ * bootstrap-datepicker.js
3
+ * http://www.eyecon.ro/bootstrap-datepicker
4
+ * =========================================================
5
+ * Copyright 2012 Stefan Petre
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ========================================================= */
19
+
20
+ !function( $ ) {
21
+
22
+ // Picker object
23
+
24
+ var Datepicker = function(element, options){
25
+ this.element = $(element);
26
+ this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
27
+ this.picker = $(DPGlobal.template)
28
+ .appendTo('body')
29
+ .on({
30
+ click: $.proxy(this.click, this)//,
31
+ //mousedown: $.proxy(this.mousedown, this)
32
+ });
33
+ this.isInput = this.element.is('input');
34
+ this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
35
+
36
+ if (this.isInput) {
37
+ this.element.on({
38
+ focus: $.proxy(this.show, this),
39
+ //blur: $.proxy(this.hide, this),
40
+ keyup: $.proxy(this.update, this)
41
+ });
42
+ } else {
43
+ if (this.component){
44
+ this.component.on('click', $.proxy(this.show, this));
45
+ } else {
46
+ this.element.on('click', $.proxy(this.show, this));
47
+ }
48
+ }
49
+
50
+ this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
51
+ if (typeof this.minViewMode === 'string') {
52
+ switch (this.minViewMode) {
53
+ case 'months':
54
+ this.minViewMode = 1;
55
+ break;
56
+ case 'years':
57
+ this.minViewMode = 2;
58
+ break;
59
+ default:
60
+ this.minViewMode = 0;
61
+ break;
62
+ }
63
+ }
64
+ this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
65
+ if (typeof this.viewMode === 'string') {
66
+ switch (this.viewMode) {
67
+ case 'months':
68
+ this.viewMode = 1;
69
+ break;
70
+ case 'years':
71
+ this.viewMode = 2;
72
+ break;
73
+ default:
74
+ this.viewMode = 0;
75
+ break;
76
+ }
77
+ }
78
+ this.startViewMode = this.viewMode;
79
+ this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
80
+ this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
81
+ this.onRender = options.onRender;
82
+ this.fillDow();
83
+ this.fillMonths();
84
+ this.update();
85
+ this.showMode();
86
+ };
87
+
88
+ Datepicker.prototype = {
89
+ constructor: Datepicker,
90
+
91
+ show: function(e) {
92
+ this.picker.show();
93
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
94
+ this.place();
95
+ $(window).on('resize', $.proxy(this.place, this));
96
+ if (e ) {
97
+ e.stopPropagation();
98
+ e.preventDefault();
99
+ }
100
+ if (!this.isInput) {
101
+ }
102
+ var that = this;
103
+ $(document).on('mousedown', function(ev){
104
+ if ($(ev.target).closest('.datepicker').length == 0) {
105
+ that.hide();
106
+ }
107
+ });
108
+ this.element.trigger({
109
+ type: 'show',
110
+ date: this.date
111
+ });
112
+ },
113
+
114
+ hide: function(){
115
+ this.picker.hide();
116
+ $(window).off('resize', this.place);
117
+ this.viewMode = this.startViewMode;
118
+ this.showMode();
119
+ if (!this.isInput) {
120
+ $(document).off('mousedown', this.hide);
121
+ }
122
+ //this.set();
123
+ this.element.trigger({
124
+ type: 'hide',
125
+ date: this.date
126
+ });
127
+ },
128
+
129
+ set: function() {
130
+ var formated = DPGlobal.formatDate(this.date, this.format);
131
+ if (!this.isInput) {
132
+ if (this.component){
133
+ this.element.find('input').prop('value', formated);
134
+ }
135
+ this.element.data('date', formated);
136
+ } else {
137
+ this.element.prop('value', formated);
138
+ }
139
+ },
140
+
141
+ setValue: function(newDate) {
142
+ if (typeof newDate === 'string') {
143
+ this.date = DPGlobal.parseDate(newDate, this.format);
144
+ } else {
145
+ this.date = new Date(newDate);
146
+ }
147
+ this.set();
148
+ this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
149
+ this.fill();
150
+ },
151
+
152
+ place: function(){
153
+ var offset = this.component ? this.component.offset() : this.element.offset();
154
+ this.picker.css({
155
+ top: offset.top + this.height,
156
+ left: offset.left
157
+ });
158
+ },
159
+
160
+ update: function(newDate){
161
+ this.date = DPGlobal.parseDate(
162
+ typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
163
+ this.format
164
+ );
165
+ this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
166
+ this.fill();
167
+ },
168
+
169
+ fillDow: function(){
170
+ var dowCnt = this.weekStart;
171
+ var html = '<tr>';
172
+ while (dowCnt < this.weekStart + 7) {
173
+ html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
174
+ }
175
+ html += '</tr>';
176
+ this.picker.find('.datepicker-days thead').append(html);
177
+ },
178
+
179
+ fillMonths: function(){
180
+ var html = '';
181
+ var i = 0
182
+ while (i < 12) {
183
+ html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
184
+ }
185
+ this.picker.find('.datepicker-months td').append(html);
186
+ },
187
+
188
+ fill: function() {
189
+ var d = new Date(this.viewDate),
190
+ year = d.getFullYear(),
191
+ month = d.getMonth(),
192
+ currentDate = this.date.valueOf();
193
+ this.picker.find('.datepicker-days th:eq(1)')
194
+ .text(DPGlobal.dates.months[month]+' '+year);
195
+ var prevMonth = new Date(year, month-1, 28,0,0,0,0),
196
+ day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
197
+ prevMonth.setDate(day);
198
+ prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
199
+ var nextMonth = new Date(prevMonth);
200
+ nextMonth.setDate(nextMonth.getDate() + 42);
201
+ nextMonth = nextMonth.valueOf();
202
+ var html = [];
203
+ var clsName,
204
+ prevY,
205
+ prevM;
206
+ while(prevMonth.valueOf() < nextMonth) {
207
+ if (prevMonth.getDay() === this.weekStart) {
208
+ html.push('<tr>');
209
+ }
210
+ clsName = this.onRender(prevMonth);
211
+ prevY = prevMonth.getFullYear();
212
+ prevM = prevMonth.getMonth();
213
+ if ((prevM < month && prevY === year) || prevY < year) {
214
+ clsName += ' old';
215
+ } else if ((prevM > month && prevY === year) || prevY > year) {
216
+ clsName += ' new';
217
+ }
218
+ if (prevMonth.valueOf() === currentDate) {
219
+ clsName += ' active';
220
+ }
221
+ html.push('<td class="day '+clsName+'">'+prevMonth.getDate() + '</td>');
222
+ if (prevMonth.getDay() === this.weekEnd) {
223
+ html.push('</tr>');
224
+ }
225
+ prevMonth.setDate(prevMonth.getDate()+1);
226
+ }
227
+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
228
+ var currentYear = this.date.getFullYear();
229
+
230
+ var months = this.picker.find('.datepicker-months')
231
+ .find('th:eq(1)')
232
+ .text(year)
233
+ .end()
234
+ .find('span').removeClass('active');
235
+ if (currentYear === year) {
236
+ months.eq(this.date.getMonth()).addClass('active');
237
+ }
238
+
239
+ html = '';
240
+ year = parseInt(year/10, 10) * 10;
241
+ var yearCont = this.picker.find('.datepicker-years')
242
+ .find('th:eq(1)')
243
+ .text(year + '-' + (year + 9))
244
+ .end()
245
+ .find('td');
246
+ year -= 1;
247
+ for (var i = -1; i < 11; i++) {
248
+ html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
249
+ year += 1;
250
+ }
251
+ yearCont.html(html);
252
+ },
253
+
254
+ click: function(e) {
255
+ e.stopPropagation();
256
+ e.preventDefault();
257
+ var target = $(e.target).closest('span, td, th');
258
+ if (target.length === 1) {
259
+ switch(target[0].nodeName.toLowerCase()) {
260
+ case 'th':
261
+ switch(target[0].className) {
262
+ case 'switch':
263
+ this.showMode(1);
264
+ break;
265
+ case 'prev':
266
+ case 'next':
267
+ this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
268
+ this.viewDate,
269
+ this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
270
+ DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
271
+ );
272
+ this.fill();
273
+ this.set();
274
+ break;
275
+ }
276
+ break;
277
+ case 'span':
278
+ if (target.is('.month')) {
279
+ var month = target.parent().find('span').index(target);
280
+ this.viewDate.setMonth(month);
281
+ } else {
282
+ var year = parseInt(target.text(), 10)||0;
283
+ this.viewDate.setFullYear(year);
284
+ }
285
+ if (this.viewMode !== 0) {
286
+ this.date = new Date(this.viewDate);
287
+ this.element.trigger({
288
+ type: 'changeDate',
289
+ date: this.date,
290
+ viewMode: DPGlobal.modes[this.viewMode].clsName
291
+ });
292
+ }
293
+ this.showMode(-1);
294
+ this.fill();
295
+ this.set();
296
+ break;
297
+ case 'td':
298
+ if (target.is('.day') && !target.is('.disabled')){
299
+ var day = parseInt(target.text(), 10)||1;
300
+ var month = this.viewDate.getMonth();
301
+ if (target.is('.old')) {
302
+ month -= 1;
303
+ } else if (target.is('.new')) {
304
+ month += 1;
305
+ }
306
+ var year = this.viewDate.getFullYear();
307
+ this.date = new Date(year, month, day,0,0,0,0);
308
+ this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
309
+ this.fill();
310
+ this.set();
311
+ this.element.trigger({
312
+ type: 'changeDate',
313
+ date: this.date,
314
+ viewMode: DPGlobal.modes[this.viewMode].clsName
315
+ });
316
+ }
317
+ break;
318
+ }
319
+ }
320
+ },
321
+
322
+ mousedown: function(e){
323
+ e.stopPropagation();
324
+ e.preventDefault();
325
+ },
326
+
327
+ showMode: function(dir) {
328
+ if (dir) {
329
+ this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
330
+ }
331
+ this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
332
+ }
333
+ };
334
+
335
+ $.fn.datepicker = function ( option, val ) {
336
+ return this.each(function () {
337
+ var $this = $(this),
338
+ data = $this.data('datepicker'),
339
+ options = typeof option === 'object' && option;
340
+ if (!data) {
341
+ $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
342
+ }
343
+ if (typeof option === 'string') data[option](val);
344
+ });
345
+ };
346
+
347
+ $.fn.datepicker.defaults = {
348
+ onRender: function(date) {
349
+ return '';
350
+ }
351
+ };
352
+ $.fn.datepicker.Constructor = Datepicker;
353
+
354
+ var DPGlobal = {
355
+ modes: [
356
+ {
357
+ clsName: 'days',
358
+ navFnc: 'Month',
359
+ navStep: 1
360
+ },
361
+ {
362
+ clsName: 'months',
363
+ navFnc: 'FullYear',
364
+ navStep: 1
365
+ },
366
+ {
367
+ clsName: 'years',
368
+ navFnc: 'FullYear',
369
+ navStep: 10
370
+ }],
371
+ dates:{
372
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
373
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
374
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
375
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
376
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
377
+ },
378
+ isLeapYear: function (year) {
379
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
380
+ },
381
+ getDaysInMonth: function (year, month) {
382
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
383
+ },
384
+ parseFormat: function(format){
385
+ var separator = format.match(/[.\/\-\s].*?/),
386
+ parts = format.split(/\W+/);
387
+ if (!separator || !parts || parts.length === 0){
388
+ throw new Error("Invalid date format.");
389
+ }
390
+ return {separator: separator, parts: parts};
391
+ },
392
+ parseDate: function(date, format) {
393
+ var parts = date.split(format.separator),
394
+ date = new Date(),
395
+ val;
396
+ date.setHours(0);
397
+ date.setMinutes(0);
398
+ date.setSeconds(0);
399
+ date.setMilliseconds(0);
400
+ if (parts.length === format.parts.length) {
401
+ var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
402
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
403
+ val = parseInt(parts[i], 10)||1;
404
+ switch(format.parts[i]) {
405
+ case 'dd':
406
+ case 'd':
407
+ day = val;
408
+ date.setDate(val);
409
+ break;
410
+ case 'mm':
411
+ case 'm':
412
+ month = val - 1;
413
+ date.setMonth(val - 1);
414
+ break;
415
+ case 'yy':
416
+ year = 2000 + val;
417
+ date.setFullYear(2000 + val);
418
+ break;
419
+ case 'yyyy':
420
+ year = val;
421
+ date.setFullYear(val);
422
+ break;
423
+ }
424
+ }
425
+ date = new Date(year, month, day, 0 ,0 ,0);
426
+ }
427
+ return date;
428
+ },
429
+ formatDate: function(date, format){
430
+ var val = {
431
+ d: date.getDate(),
432
+ m: date.getMonth() + 1,
433
+ yy: date.getFullYear().toString().substring(2),
434
+ yyyy: date.getFullYear()
435
+ };
436
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
437
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
438
+ var date = [];
439
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
440
+ date.push(val[format.parts[i]]);
441
+ }
442
+ return date.join(format.separator);
443
+ },
444
+ headTemplate: '<thead>'+
445
+ '<tr>'+
446
+ '<th class="prev">&lsaquo;</th>'+
447
+ '<th colspan="5" class="switch"></th>'+
448
+ '<th class="next">&rsaquo;</th>'+
449
+ '</tr>'+
450
+ '</thead>',
451
+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
452
+ };
453
+ DPGlobal.template = '<div class="datepicker dropdown-menu">'+
454
+ '<div class="datepicker-days">'+
455
+ '<table class=" table-condensed">'+
456
+ DPGlobal.headTemplate+
457
+ '<tbody></tbody>'+
458
+ '</table>'+
459
+ '</div>'+
460
+ '<div class="datepicker-months">'+
461
+ '<table class="table-condensed">'+
462
+ DPGlobal.headTemplate+
463
+ DPGlobal.contTemplate+
464
+ '</table>'+
465
+ '</div>'+
466
+ '<div class="datepicker-years">'+
467
+ '<table class="table-condensed">'+
468
+ DPGlobal.headTemplate+
469
+ DPGlobal.contTemplate+
470
+ '</table>'+
471
+ '</div>'+
472
+ '</div>';
473
+
474
+ }( window.jQuery );
@@ -252,6 +252,7 @@ class Model
252
252
 
253
253
  select: ->
254
254
  @db.selected this
255
+ @initDateControls()
255
256
 
256
257
  deselect: ->
257
258
  @deleting false
@@ -265,6 +266,19 @@ class Model
265
266
  @select()
266
267
  @editing true
267
268
 
269
+ initDateControls: ->
270
+ setTimeout ->
271
+ return unless @requiresDatePicker()
272
+ $('input.datepicker').datepicker(format: 'yyyy-mm-dd')
273
+ $('input.datepicker').on 'changeDate', (evt)->
274
+ $(this).trigger 'change'
275
+ , 100
276
+
277
+ requiresDatePicker: ->
278
+ i = document.createElement 'input'
279
+ i.setAttribute 'type', 'date'
280
+ return i.type != 'date'
281
+
268
282
  startDeleting: ->
269
283
  @edit()
270
284
  @deleting true
@@ -0,0 +1,182 @@
1
+ /*!
2
+ * Datepicker for Bootstrap
3
+ *
4
+ * Copyright 2012 Stefan Petre
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ */
9
+ .datepicker {
10
+ top: 0;
11
+ left: 0;
12
+ padding: 4px;
13
+ margin-top: 1px;
14
+ -webkit-border-radius: 4px;
15
+ -moz-border-radius: 4px;
16
+ border-radius: 4px;
17
+ /*.dow {
18
+ border-top: 1px solid #ddd !important;
19
+ }*/
20
+
21
+ }
22
+ .datepicker:before {
23
+ content: '';
24
+ display: inline-block;
25
+ border-left: 7px solid transparent;
26
+ border-right: 7px solid transparent;
27
+ border-bottom: 7px solid #ccc;
28
+ border-bottom-color: rgba(0, 0, 0, 0.2);
29
+ position: absolute;
30
+ top: -7px;
31
+ left: 6px;
32
+ }
33
+ .datepicker:after {
34
+ content: '';
35
+ display: inline-block;
36
+ border-left: 6px solid transparent;
37
+ border-right: 6px solid transparent;
38
+ border-bottom: 6px solid #ffffff;
39
+ position: absolute;
40
+ top: -6px;
41
+ left: 7px;
42
+ }
43
+ .datepicker > div {
44
+ display: none;
45
+ }
46
+ .datepicker table {
47
+ width: 100%;
48
+ margin: 0;
49
+ }
50
+ .datepicker td,
51
+ .datepicker th {
52
+ text-align: center;
53
+ width: 20px;
54
+ height: 20px;
55
+ -webkit-border-radius: 4px;
56
+ -moz-border-radius: 4px;
57
+ border-radius: 4px;
58
+ }
59
+ .datepicker td.day:hover {
60
+ background: #eeeeee;
61
+ cursor: pointer;
62
+ }
63
+ .datepicker td.day.disabled {
64
+ color: #eeeeee;
65
+ }
66
+ .datepicker td.old,
67
+ .datepicker td.new {
68
+ color: #999999;
69
+ }
70
+ .datepicker td.active,
71
+ .datepicker td.active:hover {
72
+ color: #ffffff;
73
+ background-color: #006dcc;
74
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
75
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
76
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
77
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
78
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
79
+ background-repeat: repeat-x;
80
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
81
+ border-color: #0044cc #0044cc #002a80;
82
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
83
+ *background-color: #0044cc;
84
+ /* Darken IE7 buttons by default so they stand out more given they won't have borders */
85
+
86
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
87
+ color: #fff;
88
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
89
+ }
90
+ .datepicker td.active:hover,
91
+ .datepicker td.active:hover:hover,
92
+ .datepicker td.active:focus,
93
+ .datepicker td.active:hover:focus,
94
+ .datepicker td.active:active,
95
+ .datepicker td.active:hover:active,
96
+ .datepicker td.active.active,
97
+ .datepicker td.active:hover.active,
98
+ .datepicker td.active.disabled,
99
+ .datepicker td.active:hover.disabled,
100
+ .datepicker td.active[disabled],
101
+ .datepicker td.active:hover[disabled] {
102
+ color: #ffffff;
103
+ background-color: #0044cc;
104
+ *background-color: #003bb3;
105
+ }
106
+ .datepicker td.active:active,
107
+ .datepicker td.active:hover:active,
108
+ .datepicker td.active.active,
109
+ .datepicker td.active:hover.active {
110
+ background-color: #003399 \9;
111
+ }
112
+ .datepicker td span {
113
+ display: block;
114
+ width: 47px;
115
+ height: 54px;
116
+ line-height: 54px;
117
+ float: left;
118
+ margin: 2px;
119
+ cursor: pointer;
120
+ -webkit-border-radius: 4px;
121
+ -moz-border-radius: 4px;
122
+ border-radius: 4px;
123
+ }
124
+ .datepicker td span:hover {
125
+ background: #eeeeee;
126
+ }
127
+ .datepicker td span.active {
128
+ color: #ffffff;
129
+ background-color: #006dcc;
130
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
131
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
132
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
133
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
134
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
135
+ background-repeat: repeat-x;
136
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
137
+ border-color: #0044cc #0044cc #002a80;
138
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
139
+ *background-color: #0044cc;
140
+ /* Darken IE7 buttons by default so they stand out more given they won't have borders */
141
+
142
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
143
+ color: #fff;
144
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
145
+ }
146
+ .datepicker td span.active:hover,
147
+ .datepicker td span.active:focus,
148
+ .datepicker td span.active:active,
149
+ .datepicker td span.active.active,
150
+ .datepicker td span.active.disabled,
151
+ .datepicker td span.active[disabled] {
152
+ color: #ffffff;
153
+ background-color: #0044cc;
154
+ *background-color: #003bb3;
155
+ }
156
+ .datepicker td span.active:active,
157
+ .datepicker td span.active.active {
158
+ background-color: #003399 \9;
159
+ }
160
+ .datepicker td span.old {
161
+ color: #999999;
162
+ }
163
+ .datepicker th.switch {
164
+ width: 145px;
165
+ }
166
+ .datepicker th.next,
167
+ .datepicker th.prev {
168
+ font-size: 21px;
169
+ }
170
+ .datepicker thead tr:first-child th {
171
+ cursor: pointer;
172
+ }
173
+ .datepicker thead tr:first-child th:hover {
174
+ background: #eeeeee;
175
+ }
176
+ .input-append.date .add-on i,
177
+ .input-prepend.date .add-on i {
178
+ display: block;
179
+ cursor: pointer;
180
+ width: 16px;
181
+ height: 16px;
182
+ }
data/lib/kolo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kolo
2
- VERSION = "0.6.8"
2
+ VERSION = "0.6.9"
3
3
  end
@@ -1,31 +1,33 @@
1
- // Generated by CoffeeScript 1.6.2
1
+ // Generated by CoffeeScript 1.7.1
2
2
  (function() {
3
3
  var Db, Model, ViewModel,
4
4
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
5
5
 
6
6
  ViewModel = (function() {
7
7
  function ViewModel() {
8
- var _this = this;
9
-
10
8
  this.loading = ko.observable(false);
11
9
  this.flashMessage = ko.observable('');
12
- this.flashMessage.subscribe(function(newValue) {
13
- if ((newValue != null) && newValue !== '') {
14
- setTimeout(function() {
15
- return _this.flashMessage('');
16
- }, 10000);
17
- }
18
- return true;
19
- });
10
+ this.flashMessage.subscribe((function(_this) {
11
+ return function(newValue) {
12
+ if ((newValue != null) && newValue !== '') {
13
+ setTimeout(function() {
14
+ return _this.flashMessage('');
15
+ }, 10000);
16
+ }
17
+ return true;
18
+ };
19
+ })(this));
20
20
  this.errorMessage = ko.observable('');
21
- this.errorMessage.subscribe(function(newValue) {
22
- if ((newValue != null) && newValue !== '') {
23
- setTimeout(function() {
24
- return _this.errorMessage('');
25
- }, 10000);
26
- }
27
- return true;
28
- });
21
+ this.errorMessage.subscribe((function(_this) {
22
+ return function(newValue) {
23
+ if ((newValue != null) && newValue !== '') {
24
+ setTimeout(function() {
25
+ return _this.errorMessage('');
26
+ }, 10000);
27
+ }
28
+ return true;
29
+ };
30
+ })(this));
29
31
  }
30
32
 
31
33
  ViewModel.prototype.systemNotification = function(name, value) {
@@ -34,12 +36,12 @@
34
36
  };
35
37
 
36
38
  ViewModel.prototype.flashPanel = function(elementId) {
37
- var _this = this;
38
-
39
39
  $(elementId).fadeIn();
40
- return setTimeout(function() {
41
- return $(elementId).fadeOut();
42
- }, 10000);
40
+ return setTimeout((function(_this) {
41
+ return function() {
42
+ return $(elementId).fadeOut();
43
+ };
44
+ })(this), 10000);
43
45
  };
44
46
 
45
47
  return ViewModel;
@@ -48,8 +50,6 @@
48
50
 
49
51
  Db = (function() {
50
52
  function Db(viewModel, name, url, pushStateUri) {
51
- var _this = this;
52
-
53
53
  this.viewModel = viewModel;
54
54
  this.name = name;
55
55
  this.pushStateUri = pushStateUri;
@@ -74,14 +74,16 @@
74
74
  this.createUrl = ko.observable(url);
75
75
  this.items = ko.observableArray([]);
76
76
  this.selected = ko.observable(null);
77
- this.selected.subscribe(function(newValue) {
78
- if (_this.selected() == null) {
79
- return;
80
- }
81
- if (_this.selected().hasBeenSelected) {
82
- return _this.selected().hasBeenSelected();
83
- }
84
- });
77
+ this.selected.subscribe((function(_this) {
78
+ return function(newValue) {
79
+ if (_this.selected() == null) {
80
+ return;
81
+ }
82
+ if (_this.selected().hasBeenSelected) {
83
+ return _this.selected().hasBeenSelected();
84
+ }
85
+ };
86
+ })(this));
85
87
  this.plural = "" + this.name + "s";
86
88
  this.sortFunction = null;
87
89
  this.onAfterLoad = null;
@@ -91,25 +93,28 @@
91
93
  this.onAfterPost = null;
92
94
  this.autoLoading = false;
93
95
  this.loading = false;
94
- this.url.subscribe(function(newValue) {
95
- if (newValue != null) {
96
- return _this.load(false);
97
- }
98
- });
99
- if ((this.pushStateUri != null) && (history.pushState != null)) {
100
- this.selected.subscribe(function(newValue) {
101
- if ((newValue != null) && (newValue.id != null)) {
102
- return history.pushState(_this.selected().name(), _this.selected().name(), "" + _this.pushStateUri + "/" + (_this.selected().id));
103
- } else {
104
- return history.pushState('', '', _this.pushStateUri);
96
+ this.url.subscribe((function(_this) {
97
+ return function(newValue) {
98
+ if (newValue != null) {
99
+ return _this.load(false);
105
100
  }
106
- });
101
+ };
102
+ })(this));
103
+ if ((this.pushStateUri != null) && (history.pushState != null)) {
104
+ this.selected.subscribe((function(_this) {
105
+ return function(newValue) {
106
+ if ((newValue != null) && (newValue.id != null)) {
107
+ return history.pushState(_this.selected().name(), _this.selected().name(), "" + _this.pushStateUri + "/" + (_this.selected().id));
108
+ } else {
109
+ return history.pushState('', '', _this.pushStateUri);
110
+ }
111
+ };
112
+ })(this));
107
113
  }
108
114
  }
109
115
 
110
116
  Db.prototype.find = function(id) {
111
117
  var item, _i, _len, _ref;
112
-
113
118
  _ref = this.items();
114
119
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
115
120
  item = _ref[_i];
@@ -122,7 +127,6 @@
122
127
 
123
128
  Db.prototype.findOrCreate = function(id) {
124
129
  var item;
125
-
126
130
  item = this.find(id);
127
131
  if (item == null) {
128
132
  item = this.newItem(id);
@@ -139,8 +143,6 @@
139
143
  };
140
144
 
141
145
  Db.prototype.load = function(autoReload, afterLoad) {
142
- var _this = this;
143
-
144
146
  if (autoReload == null) {
145
147
  autoReload = false;
146
148
  }
@@ -156,30 +158,32 @@
156
158
  if (this.onBeforeLoad != null) {
157
159
  this.onBeforeLoad();
158
160
  }
159
- $.get(this.url(), function(data) {
160
- _this.doLoad(data);
161
- if (afterLoad != null) {
162
- afterLoad(data);
163
- }
164
- if (_this.onAfterLoad != null) {
165
- _this.onAfterLoad(data);
166
- }
167
- _this.viewModel.loading(false);
168
- return _this.viewModel.systemNotification(_this.plural, 'loaded');
169
- });
161
+ $.get(this.url(), (function(_this) {
162
+ return function(data) {
163
+ _this.doLoad(data);
164
+ if (afterLoad != null) {
165
+ afterLoad(data);
166
+ }
167
+ if (_this.onAfterLoad != null) {
168
+ _this.onAfterLoad(data);
169
+ }
170
+ _this.viewModel.loading(false);
171
+ return _this.viewModel.systemNotification(_this.plural, 'loaded');
172
+ };
173
+ })(this));
170
174
  }
171
175
  if (autoReload) {
172
176
  this.autoLoading = true;
173
- setTimeout(function() {
174
- return _this.load(true, afterLoad);
175
- }, 30000);
177
+ setTimeout((function(_this) {
178
+ return function() {
179
+ return _this.load(true, afterLoad);
180
+ };
181
+ })(this), 30000);
176
182
  }
177
183
  return false;
178
184
  };
179
185
 
180
186
  Db.prototype.postTo = function(url, data, afterPost) {
181
- var _this = this;
182
-
183
187
  this.viewModel.systemNotification(this.name, 'saving');
184
188
  this.viewModel.loading(true);
185
189
  $.ajax({
@@ -187,24 +191,25 @@
187
191
  dataType: 'json',
188
192
  type: 'POST',
189
193
  data: data,
190
- success: function(data) {
191
- if (afterPost != null) {
192
- afterPost(data);
193
- }
194
- if (_this.onAfterPost != null) {
195
- _this.onAfterPost(data);
196
- }
197
- _this.viewModel.loading(false);
198
- _this.viewModel.systemNotification(_this.name, 'saved');
199
- return _this.load(false);
200
- }
194
+ success: (function(_this) {
195
+ return function(data) {
196
+ if (afterPost != null) {
197
+ afterPost(data);
198
+ }
199
+ if (_this.onAfterPost != null) {
200
+ _this.onAfterPost(data);
201
+ }
202
+ _this.viewModel.loading(false);
203
+ _this.viewModel.systemNotification(_this.name, 'saved');
204
+ return _this.load(false);
205
+ };
206
+ })(this)
201
207
  });
202
208
  return true;
203
209
  };
204
210
 
205
211
  Db.prototype.add = function() {
206
212
  var itemToAdd;
207
-
208
213
  itemToAdd = this.newItem(null);
209
214
  this.selected(itemToAdd);
210
215
  this.viewModel.systemNotification(this.name, 'new');
@@ -224,7 +229,6 @@
224
229
 
225
230
  Db.prototype.doLoad = function(data) {
226
231
  var item, itemData, _i, _len, _ref;
227
-
228
232
  _ref = this.itemDataFrom(data);
229
233
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
230
234
  itemData = _ref[_i];
@@ -243,8 +247,6 @@
243
247
  };
244
248
 
245
249
  Db.prototype.doCreate = function(item, afterSave) {
246
- var _this = this;
247
-
248
250
  this.viewModel.systemNotification(this.name, 'saving');
249
251
  this.viewModel.loading(true);
250
252
  $.ajax({
@@ -252,28 +254,28 @@
252
254
  dataType: 'json',
253
255
  type: 'POST',
254
256
  data: this.toJS(item),
255
- success: function(data) {
256
- if (data.id != null) {
257
- item.id = data.id;
258
- }
259
- _this.selected(null);
260
- if (afterSave != null) {
261
- afterSave(item);
262
- }
263
- if (_this.onAfterSave != null) {
264
- _this.onAfterSave(item);
265
- }
266
- _this.viewModel.systemNotification(_this.name, 'saved');
267
- _this.viewModel.loading(false);
268
- return _this.load();
269
- }
257
+ success: (function(_this) {
258
+ return function(data) {
259
+ if (data.id != null) {
260
+ item.id = data.id;
261
+ }
262
+ _this.selected(null);
263
+ if (afterSave != null) {
264
+ afterSave(item);
265
+ }
266
+ if (_this.onAfterSave != null) {
267
+ _this.onAfterSave(item);
268
+ }
269
+ _this.viewModel.systemNotification(_this.name, 'saved');
270
+ _this.viewModel.loading(false);
271
+ return _this.load();
272
+ };
273
+ })(this)
270
274
  });
271
275
  return false;
272
276
  };
273
277
 
274
278
  Db.prototype.doUpdate = function(item, afterSave) {
275
- var _this = this;
276
-
277
279
  this.viewModel.systemNotification(this.name, 'saving');
278
280
  this.viewModel.loading(true);
279
281
  $.ajax({
@@ -281,45 +283,47 @@
281
283
  dataType: 'json',
282
284
  type: 'PUT',
283
285
  data: this.toJS(item),
284
- success: function(data) {
285
- _this.selected(null);
286
- if (afterSave != null) {
287
- afterSave(item);
288
- }
289
- if (_this.onAfterSave != null) {
290
- _this.onAfterSave(item);
291
- }
292
- _this.viewModel.systemNotification(_this.name, 'saved');
293
- _this.viewModel.loading(false);
294
- return _this.load();
295
- }
286
+ success: (function(_this) {
287
+ return function(data) {
288
+ _this.selected(null);
289
+ if (afterSave != null) {
290
+ afterSave(item);
291
+ }
292
+ if (_this.onAfterSave != null) {
293
+ _this.onAfterSave(item);
294
+ }
295
+ _this.viewModel.systemNotification(_this.name, 'saved');
296
+ _this.viewModel.loading(false);
297
+ return _this.load();
298
+ };
299
+ })(this)
296
300
  });
297
301
  return false;
298
302
  };
299
303
 
300
304
  Db.prototype.doDestroy = function(item, afterDelete) {
301
- var _this = this;
302
-
303
305
  this.viewModel.systemNotification(this.name, 'deleting');
304
306
  this.viewModel.loading(true);
305
307
  $.ajax({
306
308
  url: this.urlFor(item),
307
309
  dataType: 'json',
308
310
  type: 'DELETE',
309
- success: function(data) {
310
- item.id = null;
311
- _this.selected(null);
312
- _this.items.remove(item);
313
- if (afterDelete != null) {
314
- afterDelete();
315
- }
316
- if (_this.onAfterDelete != null) {
317
- _this.onAfterDelete(item);
318
- }
319
- _this.viewModel.systemNotification(_this.name, 'deleted');
320
- _this.viewModel.loading(false);
321
- return _this.load();
322
- }
311
+ success: (function(_this) {
312
+ return function(data) {
313
+ item.id = null;
314
+ _this.selected(null);
315
+ _this.items.remove(item);
316
+ if (afterDelete != null) {
317
+ afterDelete();
318
+ }
319
+ if (_this.onAfterDelete != null) {
320
+ _this.onAfterDelete(item);
321
+ }
322
+ _this.viewModel.systemNotification(_this.name, 'deleted');
323
+ _this.viewModel.loading(false);
324
+ return _this.load();
325
+ };
326
+ })(this)
323
327
  });
324
328
  return false;
325
329
  };
@@ -358,8 +362,6 @@
358
362
 
359
363
  Model = (function() {
360
364
  function Model(id, db) {
361
- var _this = this;
362
-
363
365
  this.id = id;
364
366
  this.db = db;
365
367
  this.elementSelector = __bind(this.elementSelector, this);
@@ -368,9 +370,11 @@
368
370
  this.editing = ko.observable(false);
369
371
  this.deleting = ko.observable(false);
370
372
  this.updating = ko.observable(false);
371
- this.selected = ko.computed(function() {
372
- return _this.db.selected() === _this;
373
- });
373
+ this.selected = ko.computed((function(_this) {
374
+ return function() {
375
+ return _this.db.selected() === _this;
376
+ };
377
+ })(this));
374
378
  }
375
379
 
376
380
  Model.prototype.viewModel = function() {
@@ -394,7 +398,8 @@
394
398
  };
395
399
 
396
400
  Model.prototype.select = function() {
397
- return this.db.selected(this);
401
+ this.db.selected(this);
402
+ return this.initDateControls();
398
403
  };
399
404
 
400
405
  Model.prototype.deselect = function() {
@@ -410,6 +415,27 @@
410
415
  return this.editing(true);
411
416
  };
412
417
 
418
+ Model.prototype.initDateControls = function() {
419
+ return setTimeout(function() {
420
+ if (!this.requiresDatePicker()) {
421
+ return;
422
+ }
423
+ $('input.datepicker').datepicker({
424
+ format: 'yyyy-mm-dd'
425
+ });
426
+ return $('input.datepicker').on('changeDate', function(evt) {
427
+ return $(this).trigger('change');
428
+ });
429
+ }, 100);
430
+ };
431
+
432
+ Model.prototype.requiresDatePicker = function() {
433
+ var i;
434
+ i = document.createElement('input');
435
+ i.setAttribute('type', 'date');
436
+ return i.type !== 'date';
437
+ };
438
+
413
439
  Model.prototype.startDeleting = function() {
414
440
  this.edit();
415
441
  return this.deleting(true);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kolo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.8
4
+ version: 0.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rahoul Baruah
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2014-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,6 +60,7 @@ files:
60
60
  - lib/assets/images/glyphicons-halflings.png
61
61
  - lib/assets/images/loader.gif
62
62
  - lib/assets/javascripts/bindings.js.coffee
63
+ - lib/assets/javascripts/bootstrap-datepicker.js
63
64
  - lib/assets/javascripts/bootstrap.min.js
64
65
  - lib/assets/javascripts/data-access.js.coffee
65
66
  - lib/assets/javascripts/jquery.hammer.js
@@ -70,6 +71,7 @@ files:
70
71
  - lib/assets/javascripts/knockout.mapping.js
71
72
  - lib/assets/stylesheets/bootstrap-responsive.css
72
73
  - lib/assets/stylesheets/bootstrap.css
74
+ - lib/assets/stylesheets/datepicker.css
73
75
  - lib/assets/stylesheets/font-awesome.css.erb
74
76
  - lib/kolo.rb
75
77
  - lib/kolo/icons.rb