chr 0.2.8 → 0.3.5

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.
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)