anjlab-widgets 0.0.8 → 1.0.0

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/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Anjlab::Widgets
2
2
 
3
- TODO: Write a gem description
3
+ Bootstrap date and time pickers for rails (ready for rails 4).
4
+
5
+ Note: `simple_form` gem is supported.
6
+
7
+ Currently `en` and `ru` locales supported.
4
8
 
5
9
  ## Installation
6
10
 
@@ -12,13 +16,84 @@ And then execute:
12
16
 
13
17
  $ bundle
14
18
 
15
- Or install it yourself as:
19
+ ## Usage
20
+
21
+ Add date and time pickers to your application.js
16
22
 
17
- $ gem install anjlab-widgets
23
+ ```javascript
24
+ //= require anjlab/datepicker
25
+ //= require anjlab/timepicker
26
+ ```
18
27
 
19
- ## Usage
28
+ Add date and time pickers to your application.css.scss
29
+
30
+ ```scss
31
+ @import 'twitter/bootstrap';
32
+
33
+ @import 'anjlab/datepicker';
34
+ @import 'anjlab/timepicker';
35
+ ```
36
+
37
+ ### With FormBuilder
38
+
39
+ ```erb
40
+ <%= f.text_field :updated_at, value: Anjlab::Widgets.format_date(f.object.updated_at), "data-widget"=>"datepicker" %>
41
+ <%= f.text_field :updated_at, value: Anjlab::Widgets.format_time(f.object.updated_at), "data-widget"=>"timepicker" %>
42
+ ```
43
+
44
+ ### With simple_form!
45
+
46
+ You have two options here:
47
+
48
+ Overwrite standart :date, :datetime and :time inputs:
49
+
50
+ ```ruby
51
+ # config/initializers/simple_form.rb
52
+ SimpleForm.setup do |config|
53
+ Anjlab::Widgets.simple_form as_default: true
54
+ #...
55
+ end
56
+ ```
57
+ In your forms:
58
+
59
+ ```erb
60
+ <%= f.input :created_at # :datetime %>
61
+ <%= f.input :created_at, as: :date %>
62
+ <%= f.input :created_at, as: :time %>
63
+ ```
64
+
65
+ Or use prefixed input types:
66
+
67
+ ```ruby
68
+ # config/initializers/simple_form.rb
69
+ SimpleForm.setup do |config|
70
+ Anjlab::Widgets.simple_form
71
+ #...
72
+ end
73
+ ```
74
+
75
+ In your forms:
76
+
77
+ ```erb
78
+ <%= f.input :created_at, as: :anjlab_datetime %>
79
+ <%= f.input :created_at, as: :anjlab_date %>
80
+ <%= f.input :created_at, as: :anjlab_time %>
81
+ ```
82
+
83
+ ## Screen shots
84
+
85
+ ### Desktop
86
+ ![date picker](https://raw.github.com/anjlab/anjlab-widgets/master/date_pic.png)
87
+
88
+ ![time picker](https://raw.github.com/anjlab/anjlab-widgets/master/time_pic.png)
89
+
90
+ ### Mobile native
91
+
92
+ Converts to native controls if possible (except Chrome - it has ugly native controls).
93
+
94
+ ![native date picker](https://raw.github.com/anjlab/anjlab-widgets/master/native_date_pic.PNG)
20
95
 
21
- TODO: Write usage instructions here
96
+ ![native time picker](https://raw.github.com/anjlab/anjlab-widgets/master/native_time_pic.PNG)
22
97
 
23
98
  ## Contributing
24
99
 
File without changes
@@ -125,10 +125,40 @@ DateTools.template = '<div class="datepicker dropdown-menu">'+
125
125
  '</div>'+
126
126
  '</div>'
127
127
 
128
- class Datepicker
129
-
128
+ class NativeRailsDatepicker
130
129
  constructor: (element, options)->
131
130
  @element = $(element)
131
+ @rails = options.rails ? @element.data('rails') ? false
132
+
133
+ @element.on {
134
+ keyup: $.proxy(@update, this)
135
+ change: $.proxy(@update, this)
136
+ }
137
+
138
+ update: ->
139
+ @date = DateTools.parseDate @element.val(), {
140
+ separator: '-'
141
+ parts: ["yyyy", "mm", "dd"]
142
+ }
143
+
144
+ @updateRails()
145
+
146
+ updateRails: ->
147
+ return if !@rails
148
+
149
+ parent = @element.closest('.controls, form, div')
150
+ if @date == null
151
+ parent.find('.js-aw-1i, .js-aw-2i, .js-aw-3i').val('')
152
+ else
153
+ parent.find('.js-aw-1i').val(@date.getFullYear())
154
+ parent.find('.js-aw-2i').val(@date.getMonth() + 1)
155
+ parent.find('.js-aw-3i').val(@date.getDate())
156
+
157
+
158
+ class Datepicker extends NativeRailsDatepicker
159
+
160
+ constructor: (element, options)->
161
+ super(element, options)
132
162
  @locale = options.locale || @element.data('date-locale') || DateTools.getLocale()
133
163
  @format = DateTools.parseFormat(options.format || @element.data('date-format') || Locales[@locale].dates.format);
134
164
  @allowBlank = options.allowBlank ? @element.data('date-allow-blank') ? true
@@ -143,8 +173,9 @@ class Datepicker
143
173
  if @isInput
144
174
  @element.on {
145
175
  focus: $.proxy(@show, this)
176
+ click: $.proxy(@show, this)
146
177
  blur: $.proxy(@hide, this)
147
- keyup: $.proxy(@update, this)
178
+ keyup: $.proxy(@update, this)
148
179
  }
149
180
  else
150
181
  if @component
@@ -243,6 +274,7 @@ class Datepicker
243
274
  year = d.getFullYear()
244
275
  month = d.getMonth()
245
276
 
277
+ @updateRails()
246
278
  date = if @date != null then @date else DateTools.today()
247
279
  currentDate = if @date != null then @date.valueOf() else 0
248
280
 
@@ -363,12 +395,13 @@ $.fn.datepicker = (option) ->
363
395
  $this = $(this)
364
396
  data = $this.data('datepicker')
365
397
  options = typeof option == 'object' && option
366
- if nativePicker
367
- convertToNative($this, options)
368
- else
369
- if !data
398
+ if !data
399
+ if nativePicker
400
+ convertToNative($this, options)
401
+ $this.data('datepicker', (data = new NativeRailsDatepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
402
+ else
370
403
  $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))))
371
- data[option]() if typeof option == 'string'
404
+ data[option]() if typeof option == 'string'
372
405
 
373
406
  $.fn.datepicker.defaults = { }
374
407
  $.fn.datepicker.Constructor = Datepicker
@@ -377,7 +410,8 @@ $ ->
377
410
  input = document.createElement("input")
378
411
  input.setAttribute("type", "date")
379
412
  # Chrome has ugly native date picker so we show ours
413
+ # nativePicker = input.type == "date"
380
414
  nativePicker = input.type == "date" && !navigator.userAgent.match(/chrome/i)
381
415
 
382
416
  $("input[data-widget=datepicker]").datepicker()
383
-
417
+ $(document).on 'focus.data-api click.data-api touchstart.data-api', 'input[data-widget=datepicker]', (e)-> $(e.target).datepicker()
@@ -2,10 +2,35 @@ TimeTools =
2
2
 
3
3
  template: "<div class='timepicker dropdown-menu'><div class='times'></div></div>"
4
4
 
5
- class Timepicker
6
-
5
+ class NativeRailsTimepicker
7
6
  constructor: (element, options)->
8
7
  @element = $(element)
8
+ @rails = options.rails ? @element.data('rails') ? false
9
+
10
+ @element.on {
11
+ keyup: $.proxy(@update, this)
12
+ change: $.proxy(@update, this)
13
+ }
14
+
15
+ update: ->
16
+ @time = @element.val()
17
+ @updateRails()
18
+
19
+ updateRails: ->
20
+ return if !@rails
21
+ parent = @element.closest('.controls, form, div')
22
+ parts = @time.split(':')
23
+ if parts.length == 2
24
+ parent.find('.js-aw-4i').val(parts[0])
25
+ parent.find('.js-aw-5i').val(parts[1])
26
+ else
27
+ parent.find('.js-aw-4i, .js-aw-5i').val('')
28
+
29
+ class Timepicker extends NativeRailsTimepicker
30
+
31
+ constructor: (element, options)->
32
+ super(element, options)
33
+
9
34
  @picker = $(TimeTools.template).appendTo('body').on({
10
35
  click: $.proxy(@click, this)
11
36
  mousedown: $.proxy(@mousedown, this)
@@ -13,13 +38,15 @@ class Timepicker
13
38
 
14
39
  @element.on {
15
40
  focus: $.proxy(@show, this)
41
+ click: $.proxy(@show, this)
16
42
  blur: $.proxy(@hide, this)
17
- keyup: $.proxy(@update, this)
43
+
18
44
  }
19
45
 
20
46
  @step = options.step || @element.data('date-time-step') || 30
21
47
  @minTime = options.minTime || @element.data('date-time-min') || 9 * 60
22
48
  @maxTime = options.maxTime || @element.data('date-time-max') || 20 * 60
49
+
23
50
 
24
51
  @fillTimes()
25
52
  @update()
@@ -45,13 +72,14 @@ class Timepicker
45
72
  type: 'changeDate'
46
73
  date: @time
47
74
  }
75
+ @hide()
48
76
 
49
77
  mousedown: (e)->
50
78
  e.stopPropagation()
51
79
  e.preventDefault()
52
80
 
53
81
  update: ->
54
- @time = this.element.val()
82
+ super()
55
83
  @picker.find('a.active').removeClass('active')
56
84
  @picker.find("a[data-time='#{@time}']").addClass('active')
57
85
 
@@ -113,23 +141,24 @@ nativePicker = false
113
141
  $.fn.timepicker = (option) ->
114
142
  @each ->
115
143
  $this = $(this)
116
- if nativePicker
117
- $this.prop("type", "time")
118
- else
119
- data = $this.data('timepicker')
120
- options = typeof option == 'object' && option
121
- if !data
144
+ data = $this.data('timepicker')
145
+ options = typeof option == 'object' && option
146
+ if !data
147
+ if nativePicker
148
+ $this.prop('type', 'time')
149
+ $this.data('timepicker', (data = new NativeRailsTimepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
150
+ else
122
151
  $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults,options))))
123
- data[option]() if typeof option == 'string'
152
+ data[option]() if typeof option == 'string'
124
153
 
125
154
  $.fn.timepicker.defaults = { }
126
155
  $.fn.timepicker.Constructor = Timepicker
127
156
 
128
157
  $ ->
129
- input = document.createElement("input")
130
- input.setAttribute("type", "time")
131
- nativePicker = input.type == "time"
158
+ input = document.createElement('input')
159
+ input.setAttribute('type', 'time')
160
+ # skip ugly chrome native control for now
161
+ nativePicker = input.type == 'time' && !navigator.userAgent.match(/chrome/i)
132
162
 
133
163
  $("input[data-widget=timepicker]").timepicker()
134
-
135
-
164
+ $(document).on 'focus.data-api click.data-api touchstart.data-api', 'input[data-widget=timepicker]', (e)-> $(e.target).timepicker()
@@ -15,6 +15,8 @@
15
15
 
16
16
  a {
17
17
  @include border-radius(4px);
18
+ display: block;
19
+ padding: 0 1em;
18
20
 
19
21
  &:hover {
20
22
  background: $grayLighter;
data/date_pic.png ADDED
Binary file
@@ -0,0 +1,53 @@
1
+ module Anjlab
2
+ module Widgets
3
+ class DateTimeInput < SimpleForm::Inputs::DateTimeInput
4
+
5
+ def label_target
6
+ attribute_name
7
+ end
8
+
9
+ def input
10
+ time = options[:value] || @builder.object[attribute_name]
11
+
12
+ html = ''
13
+
14
+ allow_blank = !options[:required]
15
+
16
+ date_data = {
17
+ "data-widget" => "datepicker",
18
+ "data-rails" => true,
19
+ "data-date-allow-blank" => allow_blank,
20
+ :value => Widgets::format_date(time),
21
+ :required => input_html_options[:required],
22
+ :class => "#{input_html_options[:date_class] || 'input-small'}"
23
+ }
24
+
25
+ time_data = {
26
+ "data-widget" => "timepicker",
27
+ "data-rails" => true,
28
+ :value => Widgets::format_time(time),
29
+ :required => input_html_options[:required],
30
+ :class => "#{input_html_options[:time_class] || 'input-small'}"
31
+ }
32
+
33
+ case input_type
34
+ when :datetime, :anjlab_datetime
35
+ html << @builder.text_field(attribute_name, date_data)
36
+ html << '&nbsp;&nbsp;&nbsp;'
37
+ html << @builder.text_field(attribute_name, time_data)
38
+ when :date, :anjlab_date
39
+ html << @builder.text_field(attribute_name, date_data)
40
+ when :time, :anjlab_time
41
+ html << @builder.text_field(attribute_name, time_data)
42
+ end
43
+
44
+ values = time ? [time.year, time.month, time.day, time.hour, time.min] : [''] * 5
45
+ values.each_with_index do |v, index|
46
+ i = index + 1
47
+ html << @builder.hidden_field("#{attribute_name}(#{i}i)", value: v, class: "js-aw-#{i}i")
48
+ end
49
+ html
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,5 +1,5 @@
1
1
  module Anjlab
2
2
  module Widgets
3
- VERSION = "0.0.8"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -67,8 +67,16 @@ module Anjlab
67
67
  end
68
68
 
69
69
  def self.format_time time
70
- nil if time.nil?
70
+ return '' if time.nil?
71
71
  time.strftime "%H:%M"
72
72
  end
73
+
74
+ def self.simple_form options={}
75
+ require 'anjlab-widgets/simple_form'
76
+ SimpleForm::FormBuilder.map_type :anjlab_date, :anjlab_time, :anjlab_datetime, to: DateTimeInput
77
+ if options[:as_default]
78
+ SimpleForm::FormBuilder.map_type :date, :time, :datetime, to: DateTimeInput
79
+ end
80
+ end
73
81
  end
74
82
  end
Binary file
Binary file
data/time_pic.png ADDED
Binary file
metadata CHANGED
@@ -2,94 +2,94 @@
2
2
  name: anjlab-widgets
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.8
5
+ version: 1.0.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Yury Korolev
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
12
+ date: 2013-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
+ name: anjlab-bootstrap-rails
15
16
  version_requirements: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: 2.0.3
20
- none: false
21
- prerelease: false
22
- name: anjlab-bootstrap-rails
23
22
  requirement: !ruby/object:Gem::Requirement
23
+ none: false
24
24
  requirements:
25
25
  - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: 2.0.3
28
- none: false
28
+ prerelease: false
29
29
  type: :runtime
30
30
  - !ruby/object:Gem::Dependency
31
+ name: rails
31
32
  version_requirements: !ruby/object:Gem::Requirement
33
+ none: false
32
34
  requirements:
33
35
  - - ! '>='
34
36
  - !ruby/object:Gem::Version
35
37
  version: '3.2'
36
- none: false
37
- prerelease: false
38
- name: rails
39
38
  requirement: !ruby/object:Gem::Requirement
39
+ none: false
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
43
  version: '3.2'
44
- none: false
44
+ prerelease: false
45
45
  type: :development
46
46
  - !ruby/object:Gem::Dependency
47
+ name: bundler
47
48
  version_requirements: !ruby/object:Gem::Requirement
49
+ none: false
48
50
  requirements:
49
51
  - - ! '>='
50
52
  - !ruby/object:Gem::Version
51
53
  version: '1.0'
52
- none: false
53
- prerelease: false
54
- name: bundler
55
54
  requirement: !ruby/object:Gem::Requirement
55
+ none: false
56
56
  requirements:
57
57
  - - ! '>='
58
58
  - !ruby/object:Gem::Version
59
59
  version: '1.0'
60
- none: false
60
+ prerelease: false
61
61
  type: :development
62
62
  - !ruby/object:Gem::Dependency
63
+ name: sqlite3
63
64
  version_requirements: !ruby/object:Gem::Requirement
65
+ none: false
64
66
  requirements:
65
67
  - - ! '>='
66
68
  - !ruby/object:Gem::Version
67
69
  version: '0'
68
- none: false
69
- prerelease: false
70
- name: sqlite3
71
70
  requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
72
  requirements:
73
73
  - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- none: false
76
+ prerelease: false
77
77
  type: :development
78
78
  - !ruby/object:Gem::Dependency
79
+ name: rspec-rails
79
80
  version_requirements: !ruby/object:Gem::Requirement
81
+ none: false
80
82
  requirements:
81
83
  - - ! '>='
82
84
  - !ruby/object:Gem::Version
83
85
  version: 2.9.0
84
- none: false
85
- prerelease: false
86
- name: rspec-rails
87
86
  requirement: !ruby/object:Gem::Requirement
87
+ none: false
88
88
  requirements:
89
89
  - - ! '>='
90
90
  - !ruby/object:Gem::Version
91
91
  version: 2.9.0
92
- none: false
92
+ prerelease: false
93
93
  type: :development
94
94
  description: Collection of UI widgets on top of anjlab-bootstrap-rails. Datepicker
95
95
  and Timepicker for now.
@@ -105,9 +105,21 @@ files:
105
105
  - README.md
106
106
  - Rakefile
107
107
  - anjlab-widgets.gemspec
108
+ - app/assets/images/ajax-loader.gif
109
+ - app/assets/javascripts/anjlab/datepicker.js.coffee
110
+ - app/assets/javascripts/anjlab/timepicker.js.coffee
111
+ - app/assets/javascripts/bootstrap-modal.js
112
+ - app/assets/javascripts/bootstrap-modalmanager.js
113
+ - app/assets/stylesheets/anjlab/datepicker.css.scss
114
+ - app/assets/stylesheets/anjlab/timepicker.css.scss
115
+ - app/assets/stylesheets/bootstrap-modal.css
116
+ - date_pic.png
108
117
  - lib/anjlab-widgets.rb
109
118
  - lib/anjlab-widgets/engine.rb
119
+ - lib/anjlab-widgets/simple_form.rb
110
120
  - lib/anjlab-widgets/version.rb
121
+ - native_date_pic.PNG
122
+ - native_time_pic.PNG
111
123
  - spec/dummy/README.rdoc
112
124
  - spec/dummy/Rakefile
113
125
  - spec/dummy/app/assets/javascripts/application.js
@@ -147,14 +159,7 @@ files:
147
159
  - spec/dummy/script/rails
148
160
  - spec/spec_helper.rb
149
161
  - spec/views/widgets/datepicker_spec.rb
150
- - vendor/assets/images/ajax-loader.gif
151
- - vendor/assets/javascripts/anjlab/datepicker.js.coffee
152
- - vendor/assets/javascripts/anjlab/timepicker.js.coffee
153
- - vendor/assets/javascripts/bootstrap-modal.js
154
- - vendor/assets/javascripts/bootstrap-modalmanager.js
155
- - vendor/assets/stylesheets/anjlab/datepicker.css.scss
156
- - vendor/assets/stylesheets/anjlab/timepicker.css.scss
157
- - vendor/assets/stylesheets/bootstrap-modal.css
162
+ - time_pic.png
158
163
  homepage: https://github.com/anjlab/anjlab-widgets
159
164
  licenses: []
160
165
  post_install_message:
@@ -162,23 +167,23 @@ rdoc_options: []
162
167
  require_paths:
163
168
  - lib
164
169
  required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
165
171
  requirements:
166
172
  - - ! '>='
167
173
  - !ruby/object:Gem::Version
168
174
  version: '0'
175
+ hash: 1068616150774873195
169
176
  segments:
170
177
  - 0
171
- hash: 2463130067864864405
172
- none: false
173
178
  required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
174
180
  requirements:
175
181
  - - ! '>='
176
182
  - !ruby/object:Gem::Version
177
183
  version: '0'
184
+ hash: 1068616150774873195
178
185
  segments:
179
186
  - 0
180
- hash: 2463130067864864405
181
- none: false
182
187
  requirements: []
183
188
  rubyforge_project:
184
189
  rubygems_version: 1.8.24