chr 0.2.8 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.coffee +33 -27
  3. data/README.md +6 -1
  4. data/app/assets/javascripts/chr.coffee +18 -16
  5. data/app/assets/javascripts/chr/core/chr.coffee +41 -76
  6. data/app/assets/javascripts/chr/core/chr_router.coffee +141 -0
  7. data/app/assets/javascripts/chr/core/item.coffee +36 -49
  8. data/app/assets/javascripts/chr/core/list.coffee +26 -71
  9. data/app/assets/javascripts/chr/core/list_config.coffee +28 -13
  10. data/app/assets/javascripts/chr/core/list_pagination.coffee +56 -13
  11. data/app/assets/javascripts/chr/core/list_reorder.coffee +2 -2
  12. data/app/assets/javascripts/chr/core/list_search.coffee +2 -2
  13. data/app/assets/javascripts/chr/core/module.coffee +24 -93
  14. data/app/assets/javascripts/chr/core/utils.coffee +4 -0
  15. data/app/assets/javascripts/chr/core/view.coffee +123 -43
  16. data/app/assets/javascripts/chr/core/view_local-storage.coffee +58 -0
  17. data/app/assets/javascripts/chr/store/{_array-store.coffee → array-store.coffee} +3 -1
  18. data/app/assets/javascripts/chr/store/{_object-store.coffee → object-store.coffee} +0 -0
  19. data/app/assets/javascripts/chr/store/rails-array-store.coffee +39 -0
  20. data/app/assets/javascripts/chr/store/{mongosteen-object-store.coffee → rails-form-object-parser.coffee} +11 -20
  21. data/app/assets/javascripts/chr/store/rails-object-store.coffee +35 -0
  22. data/app/assets/javascripts/chr/store/rest-array-store.coffee +3 -5
  23. data/app/assets/javascripts/chr/store/rest-object-store.coffee +1 -1
  24. data/app/assets/javascripts/form/expandable-group.coffee +30 -0
  25. data/app/assets/javascripts/{chr/form → form}/form.coffee +3 -1
  26. data/app/assets/javascripts/{chr/form → form}/input-checkbox.coffee +1 -1
  27. data/app/assets/javascripts/{chr/form → form}/input-color.coffee +2 -0
  28. data/app/assets/javascripts/{chr/form → form}/input-date.coffee +0 -0
  29. data/app/assets/javascripts/{chr/form → form}/input-file.coffee +28 -1
  30. data/app/assets/javascripts/{chr/form → form}/input-form.coffee +14 -5
  31. data/app/assets/javascripts/{chr/form → form}/input-form_reorder.coffee +0 -0
  32. data/app/assets/javascripts/{chr/form → form}/input-hidden.coffee +9 -9
  33. data/app/assets/javascripts/{chr/form → form}/input-list.coffee +61 -53
  34. data/app/assets/javascripts/{chr/form → form}/input-list_reorder.coffee +2 -0
  35. data/app/assets/javascripts/form/input-list_typeahead.coffee +55 -0
  36. data/app/assets/javascripts/{chr/form → form}/input-password.coffee +1 -0
  37. data/app/assets/javascripts/{chr/form → form}/input-select.coffee +10 -11
  38. data/app/assets/javascripts/form/input-select2.coffee +33 -0
  39. data/app/assets/javascripts/{chr/form → form}/input-string.coffee +45 -2
  40. data/app/assets/javascripts/{chr/form → form}/input-text.coffee +6 -3
  41. data/app/assets/javascripts/input-html.coffee +8 -5
  42. data/app/assets/javascripts/input-markdown.coffee +10 -5
  43. data/app/assets/javascripts/input-redactor.coffee +1 -61
  44. data/app/assets/javascripts/redactor/input-redactor.coffee +53 -0
  45. data/app/assets/javascripts/redactor/input-redactor_character.coffee +83 -0
  46. data/app/assets/javascripts/redactor/input-redactor_images.coffee +166 -0
  47. data/app/assets/javascripts/{chr/vendor → vendor}/ace.js +0 -0
  48. data/app/assets/javascripts/{chr/vendor → vendor}/jquery.scrollparent.js +0 -0
  49. data/app/assets/javascripts/{chr/vendor → vendor}/jquery.textarea_autosize.js +0 -0
  50. data/app/assets/javascripts/{chr/vendor → vendor}/jquery.typeahead.js +0 -0
  51. data/app/assets/javascripts/{chr/vendor → vendor}/marked.js +0 -0
  52. data/app/assets/javascripts/{chr/vendor → vendor}/mode-html.js +0 -0
  53. data/app/assets/javascripts/{chr/vendor → vendor}/mode-markdown.js +0 -0
  54. data/app/assets/javascripts/{chr/vendor → vendor}/redactor.fixedtoolbar.js +1 -1
  55. data/app/assets/javascripts/vendor/select2.js +5274 -0
  56. data/app/assets/javascripts/{chr/vendor → vendor}/slip.js +0 -0
  57. data/app/assets/stylesheets/_chr.scss +11 -13
  58. data/app/assets/stylesheets/_input-redactor.scss +17 -16
  59. data/app/assets/stylesheets/{core → chr}/_icons.scss +1 -1
  60. data/app/assets/stylesheets/chr/_main.scss +110 -0
  61. data/app/assets/stylesheets/{core → chr}/_mixins.scss +58 -34
  62. data/app/assets/stylesheets/{core → chr}/_settings.scss +7 -1
  63. data/app/assets/stylesheets/form/_expandable-group.scss +16 -0
  64. data/app/assets/stylesheets/form/_input-select2.scss +94 -0
  65. data/app/assets/stylesheets/form/_main.scss +180 -0
  66. data/app/assets/stylesheets/vendor/select2.css +258 -0
  67. data/bower.json +2 -2
  68. data/dist/chr.js +2292 -2030
  69. data/dist/input-ace.js +18 -8
  70. data/dist/input-redactor.js +0 -156
  71. data/docs/bootstrap.md +1 -1
  72. data/docs/rails.md +10 -10
  73. data/lib/chr.rb +1 -8
  74. data/lib/chr/version.rb +1 -1
  75. data/lib/mongoid/character.rb +30 -0
  76. data/package.json +1 -1
  77. metadata +49 -43
  78. data/app/assets/javascripts/chr/store/mongosteen-array-store.coffee +0 -55
  79. data/app/assets/stylesheets/core/_list.scss +0 -39
  80. data/app/assets/stylesheets/core/_main.scss +0 -49
  81. data/app/assets/stylesheets/core/_responsive.scss +0 -62
  82. data/app/assets/stylesheets/form/_form.scss +0 -41
  83. data/app/assets/stylesheets/form/_input-checkbox.scss +0 -18
  84. data/app/assets/stylesheets/form/_input-color.scss +0 -10
  85. data/app/assets/stylesheets/form/_input-file.scss +0 -29
  86. data/app/assets/stylesheets/form/_input-form.scss +0 -26
  87. data/app/assets/stylesheets/form/_input-list.scss +0 -36
  88. data/app/assets/stylesheets/form/_input-string.scss +0 -8
@@ -12,8 +12,11 @@
12
12
  # Allows to create/delete/reorder list items connected to dynamic or static
13
13
  # collection. Value should be an array of objects.
14
14
  #
15
+ # All items should be unique for now.
16
+ #
15
17
  # Dependencies:
16
18
  #= require ./input-list_reorder
19
+ #= require ./input-list_typeahead
17
20
  #
18
21
  # -----------------------------------------------------------------------------
19
22
 
@@ -22,31 +25,40 @@ class @InputList extends InputString
22
25
  # PRIVATE ===============================================
23
26
 
24
27
  _add_input: ->
25
- # hidden input that stores ids
26
- # we use __LIST__ prefix to identify ARRAY input type and
27
- # process it's value while form submission.
28
- name = if @config.namePrefix then "#{@config.namePrefix}[__LIST__#{@config.target}]" else "[__LIST__#{@config.target}]"
28
+ # @TODO: check if we can use @config.name instead of @config.target
29
+ # @config.target ?= @config.klassName
30
+
31
+ # hidden input that stores ids, we use __LIST__ prefix to identify
32
+ # ARRAY input type and process it's value while form submission.
33
+ name = if @config.namePrefix then "#{ @config.namePrefix }[__LIST__#{ @config.target }]" else "[__LIST__#{ @config.target }]"
29
34
 
30
35
  @$input =$ "<input type='hidden' name='#{ name }' value='' />"
31
36
  @$el.append @$input
32
37
 
38
+ # list holder for items
39
+ @reorderContainerClass = @config.klassName
40
+ @$items =$ "<ul class='#{ @reorderContainerClass }'></ul>"
41
+ @$el.append @$items
42
+
33
43
  # other options might be added here (static collection)
34
- if @config.typeahead
35
- # typeahead input for adding new items
36
- placeholder = @config.typeahead.placeholder
37
- @typeaheadInput =$ "<input type='text' placeholder='#{ placeholder }' />"
38
- @$el.append @typeaheadInput
39
44
 
40
- @_add_items()
45
+ @_create_typeahead_el(@config.typeahead.placeholder)
46
+
47
+ @_render_items()
41
48
  @_update_input_value()
42
49
 
43
50
 
44
51
  _update_input_value: ->
45
52
  ids = []
46
- @$items.children('li').each (i, el)->
47
- ids.push $(el).attr('data-id')
53
+ @$items.children('li').each (i, el) -> ids.push $(el).attr('data-id')
54
+
55
+ # @TODO: we need a better separator here, comma is too generic
56
+ # it's used cause most cases list of IDs concidered to be here,
57
+ # we might make this a @config setting.
48
58
  value = ids.join(',')
59
+
49
60
  @$input.val(value)
61
+ @$input.trigger('change')
50
62
 
51
63
 
52
64
  _remove_item: ($el) ->
@@ -57,62 +69,54 @@ class @InputList extends InputString
57
69
  @_update_input_value()
58
70
 
59
71
 
60
- _add_item: (o) ->
61
- id = o['_id']
72
+ _ordered_ids: ->
73
+ ids = @$input.val().split(',')
74
+ if ids[0] == '' then ids = []
75
+ return ids
76
+
77
+
78
+ _render_items: ->
79
+ @$items.html('')
80
+ @objects = {}
81
+
82
+ for o in @value
83
+ @_render_item(o)
62
84
 
63
- @objects[id] = o
85
+
86
+ _render_item: (o) ->
87
+ @_add_object(o)
64
88
 
65
89
  if @config.itemTemplate
66
90
  item = @config.itemTemplate(o)
67
91
  else
68
92
  item = o[@config.titleFieldName]
69
93
 
70
- listItem =$ """<li data-id='#{ id }'>
94
+ listItem =$ """<li data-id='#{ o._id }'>
71
95
  <span class='icon-reorder' data-container-class='#{ @reorderContainerClass }'></span>
72
96
  #{ item }
73
97
  <a href='#' class='action_remove'>Remove</a>
74
98
  </li>"""
75
- @$items.append listItem
99
+ @$items.append(listItem)
76
100
  @_update_input_value()
77
101
 
78
102
 
79
- _add_items: ->
80
- @reorderContainerClass = @config.klassName
81
- @objects = {}
82
- @$items =$ "<ul class='#{ @reorderContainerClass }'></ul>"
103
+ _add_object: (o) ->
104
+ @_normalize_object(o)
105
+ @objects[o._id] = o
83
106
 
84
- for o in @value
85
- @_add_item(o)
86
107
 
87
- @typeaheadInput.before @$items
108
+ _normalize_object: (o) ->
109
+ o._id ?= o.id
110
+ if ! o._id then console.log("::: list item is missing an 'id' or '_id' :::")
88
111
 
89
112
 
90
113
  # PUBLIC ================================================
91
114
 
92
115
  initialize: ->
116
+ @config.beforeInitialize?(this)
117
+
93
118
  # typeahead
94
- if @config.typeahead
95
- limit = @config.typeahead.limit || 5
96
- dataSource = new Bloodhound
97
- datumTokenizer: Bloodhound.tokenizers.obj.whitespace(@config.titleFieldName)
98
- queryTokenizer: Bloodhound.tokenizers.whitespace
99
- remote: @config.typeahead.url
100
- limit: limit
101
-
102
- dataSource.initialize()
103
-
104
- @typeaheadInput.typeahead({
105
- hint: false
106
- highlight: true
107
- }, {
108
- name: @config.klassName,
109
- displayKey: @config.titleFieldName,
110
- source: dataSource.ttAdapter()
111
- })
112
-
113
- @typeaheadInput.on 'typeahead:selected', (e, object, dataset) =>
114
- @_add_item(object)
115
- @typeaheadInput.typeahead('val', '')
119
+ @_bind_typeahead()
116
120
 
117
121
  # remove
118
122
  @$items.on 'click', '.action_remove', (e) =>
@@ -124,19 +128,23 @@ class @InputList extends InputString
124
128
  @config.onInitialize?(this)
125
129
 
126
130
 
131
+ updateValue: (@value) ->
132
+ @_render_items()
133
+
134
+
127
135
  hash: (hash={}) ->
128
- hash[@config.klassName] = []
129
- ids = @$input.val().split(',')
130
- hash[@config.klassName].push(@objects[id]) for id in ids
131
- return hash
136
+ hash[@config.target] = @$input.val()
137
+ ordered_objects = []
132
138
 
139
+ for id in @_ordered_ids()
140
+ ordered_objects.push(@objects[id])
133
141
 
134
- updateValue: (@value) ->
135
- @$items.html('')
136
- @_add_item(o) for o in @value
142
+ hash[@config.klassName] = ordered_objects
143
+ return hash
137
144
 
138
145
 
139
146
  include(InputList, inputListReorder)
147
+ include(InputList, inputListTypeahead)
140
148
 
141
149
 
142
150
  chr.formInputs['list'] = InputList
@@ -11,7 +11,9 @@
11
11
  # -----------------------------------------------------------------------------
12
12
 
13
13
  @inputListReorder =
14
+
14
15
  # PRIVATE ===============================================
16
+
15
17
  _bind_reorder: ->
16
18
  list = @$items.get(0)
17
19
  new Slip(list)
@@ -0,0 +1,55 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT LIST TYPEAHEAD
11
+ # -----------------------------------------------------------------------------
12
+
13
+ @inputListTypeahead =
14
+
15
+ # PRIVATE ===============================================
16
+
17
+ _create_typeahead_el: (placeholder) ->
18
+ # typeahead input for adding new items
19
+ @typeaheadInput =$ "<input type='text' placeholder='#{ placeholder }' />"
20
+ @$el.append @typeaheadInput
21
+
22
+
23
+ _bind_typeahead: ->
24
+ limit = @config.typeahead.limit || 5
25
+ dataSource = new Bloodhound
26
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace(@config.titleFieldName)
27
+ queryTokenizer: Bloodhound.tokenizers.whitespace
28
+ remote:
29
+ url: @config.typeahead.url
30
+ # exclude objects that are already in the list
31
+ filter: (parsedResponse) =>
32
+ data = []
33
+ for o in parsedResponse
34
+ @_normalize_object(o) ; if ! @objects[o._id] then data.push(o)
35
+ return data
36
+ limit: limit
37
+
38
+ dataSource.initialize()
39
+
40
+ @typeaheadInput.typeahead({
41
+ hint: false
42
+ highlight: true
43
+ }, {
44
+ name: @config.klassName
45
+ displayKey: @config.titleFieldName
46
+ source: dataSource.ttAdapter()
47
+ })
48
+
49
+ @typeaheadInput.on 'typeahead:selected', (e, object, dataset) =>
50
+ @_render_item(object)
51
+ @typeaheadInput.typeahead('val', '')
52
+
53
+
54
+
55
+
@@ -15,6 +15,7 @@ class @InputPassword extends InputString
15
15
 
16
16
  _add_input: ->
17
17
  @$input =$ "<input type='password' name='#{ @name }' value='#{ @value }' />"
18
+ @$input.on 'keyup', (e) => @$input.trigger('change')
18
19
  @$el.append @$input
19
20
 
20
21
 
@@ -9,23 +9,23 @@
9
9
  # -----------------------------------------------------------------------------
10
10
  # INPUT SELECT
11
11
  # -----------------------------------------------------------------------------
12
- # Todo:
13
- # - add empty value option
14
- # - an option to pull data from store
15
- # -----------------------------------------------------------------------------
16
12
 
17
13
  class @InputSelect extends InputString
18
14
 
19
15
  # PRIVATE ===============================================
20
16
 
21
17
  _create_el: ->
22
- @$el =$ "<div class='input-#{ @config.type } input-#{ @config.klass } #{ @config.klassName }'>"
18
+ @$el =$ "<div class='input-#{ @config.type } input-#{ @config.klass } input-#{ @config.klassName }'>"
23
19
 
24
20
 
25
21
  _add_input: ->
26
- @$input =$ """<select name='#{ @name }' id='#{ @name }'></select>"""
22
+ @$input =$ """<select name='#{ @name }'></select>"""
27
23
  @$el.append @$input
28
24
 
25
+ @_add_options()
26
+
27
+
28
+ _add_options: ->
29
29
  if @config.optionsHashFieldName
30
30
  @value = String(@value)
31
31
  if @object
@@ -33,10 +33,6 @@ class @InputSelect extends InputString
33
33
  else
34
34
  @config.optionsHash = { '': '--' }
35
35
 
36
- @_add_options()
37
-
38
-
39
- _add_options: ->
40
36
  if @config.collection
41
37
  @_add_collection_options()
42
38
 
@@ -74,7 +70,10 @@ class @InputSelect extends InputString
74
70
 
75
71
  # PUBLIC ================================================
76
72
 
77
- updateValue: (@value) ->
73
+ updateValue: (@value, @object) ->
74
+ @$input.html('')
75
+ @_add_options()
76
+
78
77
  @$input.val(@value).prop('selected', true)
79
78
 
80
79
 
@@ -0,0 +1,33 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT SELECT 2
11
+ # -----------------------------------------------------------------------------
12
+ #
13
+ # Dependencies:
14
+ #= require vendor/select2
15
+ #
16
+ # -----------------------------------------------------------------------------
17
+
18
+ class @InputSelect2 extends InputSelect
19
+ initialize: ->
20
+ @config.beforeInitialize?(this)
21
+
22
+ # https://select2.github.io/options.html
23
+ options = @config.pluginOptions || {}
24
+ @$input.select2(options)
25
+
26
+ @config.onInitialize?(this)
27
+
28
+
29
+ chr.formInputs['select2'] = InputSelect2
30
+
31
+
32
+
33
+
@@ -20,7 +20,7 @@
20
20
  # hideErrorMessage() - hide error message
21
21
  #
22
22
  # Dependencies:
23
- #= require ../vendor/jquery.typeahead
23
+ #= require vendor/jquery.typeahead
24
24
  #
25
25
  # -----------------------------------------------------------------------------
26
26
  class @InputString
@@ -29,6 +29,9 @@ class @InputString
29
29
  @_add_label()
30
30
  @_add_input()
31
31
  @_add_placeholder()
32
+ @_add_disabled()
33
+ @_add_required()
34
+ @_add_limit()
32
35
 
33
36
  return this
34
37
 
@@ -43,7 +46,7 @@ class @InputString
43
46
 
44
47
 
45
48
  _create_el: ->
46
- @$el =$ "<label for='#{ @name }' class='input-#{ @config.type } input-#{ @config.klass } #{ @config.klassName }'>"
49
+ @$el =$ "<label for='#{ @name }' class='input-#{ @config.type } input-#{ @config.klass } input-#{ @config.klassName }'>"
47
50
 
48
51
 
49
52
  _add_label: ->
@@ -55,8 +58,11 @@ class @InputString
55
58
 
56
59
  _add_input: ->
57
60
  @$input =$ "<input type='text' name='#{ @name }' value='#{ @_safe_value() }' />"
61
+ # trigger change event on keyup so value is cached while typing
62
+ @$input.on 'keyup', (e) => @$input.trigger('change')
58
63
  @$el.append @$input
59
64
 
65
+
60
66
  if @config.options and $.isArray(@config.options)
61
67
  data = new Bloodhound
62
68
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value')
@@ -85,6 +91,43 @@ class @InputString
85
91
  @$input.attr 'placeholder', @config.placeholder
86
92
 
87
93
 
94
+ _add_disabled: ->
95
+ if @config.disabled
96
+ @$input.prop('disabled', true)
97
+ @$el.addClass('input-disabled')
98
+
99
+
100
+ _add_required: ->
101
+ if @config.required
102
+ @$el.addClass('input-required')
103
+
104
+
105
+ _add_limit: ->
106
+ if @config.limit
107
+ @$charCounter =$ "<span class='input-character-counter'></span>"
108
+ @$errorMessage.before @$charCounter
109
+ @$input.on 'keyup', =>
110
+ @_update_character_counter()
111
+ @_update_character_counter()
112
+
113
+
114
+ _update_character_counter: ->
115
+ characters = @$input.val().length
116
+ left = @config.limit - characters
117
+
118
+ if left >= 0
119
+ @$charCounter.html("(#{ left } left)")
120
+
121
+ else
122
+ @$charCounter.html("(#{ left })")
123
+
124
+
125
+ if characters > @config.limit
126
+ @$charCounter.addClass('exceeds')
127
+ else
128
+ @$charCounter.removeClass('exceeds')
129
+
130
+
88
131
  # PUBLIC ================================================
89
132
 
90
133
  initialize: ->
@@ -11,8 +11,8 @@
11
11
  # -----------------------------------------------------------------------------
12
12
  #
13
13
  # Dependencies:
14
- #= require ../vendor/jquery.scrollparent
15
- #= require ../vendor/jquery.textarea_autosize
14
+ #= require vendor/jquery.scrollparent
15
+ #= require vendor/jquery.textarea_autosize
16
16
  #
17
17
  # -----------------------------------------------------------------------------
18
18
  class @InputText extends InputString
@@ -21,13 +21,16 @@ class @InputText extends InputString
21
21
 
22
22
  _add_input: ->
23
23
  @$input =$ "<textarea class='autosize' name='#{ @name }' rows=1>#{ @_safe_value() }</textarea>"
24
+ # trigger change event on keyup so value is cached while typing
25
+ @$input.on 'keyup', (e) => @$input.trigger('change')
24
26
  @$el.append @$input
25
27
 
26
28
 
27
29
  # PUBLIC ================================================
28
30
 
29
31
  initialize: ->
30
- # TODO: refactor a bit plugin code so there is no blink while jumping from object to object
32
+ @config.beforeInitialize?(this)
33
+
31
34
  @$input.textareaAutoSize()
32
35
 
33
36
  @config.onInitialize?(this)