neat-rails 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0917bb29396d40820cd7ea76add02769a75ebf06
4
- data.tar.gz: 215afdec3ef8a2ea45eed909282ce24b33cb573a
3
+ metadata.gz: 695ee4ffacf2d5ff9962b563842796a8e19f1133
4
+ data.tar.gz: 5d86e89f8d9fa6bd3d8bcf4b890bac853047b568
5
5
  SHA512:
6
- metadata.gz: 881a5a3ee3673cf59dcb969c1fb92be12f0cc1851e238f7ab4842191ff28bd60667427c97d7479b5665ecd0b8e540412118e9aab8ee8f8741a843671f875a3c4
7
- data.tar.gz: a383cfcdfcf454b35d9a5d2d4486a127f2482de763ae076b6472338e05eb3455bc89ece97427f6af4e0fcfe2e7891c753c72a5185608fa179751fce892f66e33
6
+ metadata.gz: 26244d4b5882ee55c5413495fe5897dbb93473f4f1135bd3610a0059e368e6cc3f38a41b7037398e3bfe0608670bc038ae5a1e0ebf18e39eebaf9e2a5674cb5f
7
+ data.tar.gz: 110fbfca1f62d9101e10f605ac46663a5dbff5ebb7428d765b529d4ba8cebcd9a6baf5299fd40d2f83f9b3acd7aa95d71424216c72637e5317d44af172a0fa3f
@@ -1,5 +1,5 @@
1
1
  module Neat
2
2
  module Rails
3
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -6,6 +6,7 @@
6
6
  //
7
7
  //= require_self
8
8
  //= require ./neat/lib/inflect
9
+ //= require ./neat/lib/observer
9
10
  //= require ./neat/lib/paginated_list
10
11
  //= require ./neat/lib/delayed_action
11
12
  //= require ./neat/lib/jquery_extensions
@@ -20,14 +20,13 @@ class window.Neat.CollectionEditor extends Backbone.View
20
20
  sortAliases: {}
21
21
  templateOptions: {}
22
22
  pageSize: 30
23
-
24
- keyDownHandlers:
25
- ESC: -> @viewInEdit?.cancelEdit()
26
- RETURN: -> @viewInEdit?.save()
27
- UP: -> @edit @prevView()
28
- DOWN: -> @edit @nextView()
23
+ useKeyboardToChangeRows: true
24
+ cancelOnEsc: true
25
+ saveOnEnter: true
29
26
 
30
27
  initialize: ->
28
+ @keyDownHandlers = {}
29
+
31
30
  @viewPath = @viewPath ? @resource
32
31
  @singular = inflect.singularize(@resource) # e.g. "calendar"
33
32
  @modelView = @modelView ? (()=>
@@ -43,9 +42,9 @@ class window.Neat.CollectionEditor extends Backbone.View
43
42
  always_show: false
44
43
  @paginator.onPageChange _.bind(@renderPage, @)
45
44
 
46
- @collection.bind 'reset', @render, @
47
- @collection.bind 'add', @rerenderPage, @
48
- @collection.bind 'remove', @rerenderPage, @
45
+ @collection.bind 'reset', @__reset, @
46
+ @collection.bind 'add', @__add, @
47
+ @collection.bind 'remove', @__remove, @
49
48
 
50
49
  # We need to rerender the page if a model's attributes
51
50
  # have changed just in case this would affect how the
@@ -67,13 +66,24 @@ class window.Neat.CollectionEditor extends Backbone.View
67
66
  # has settled into new state.
68
67
  #
69
68
  @delayedRerender = new Lail.DelayedAction(_.bind(@rerenderPage, @), delay: 500)
70
- @collection.bind 'change', @delayedRerender.trigger
69
+ @collection.bind 'change', =>
70
+ @delayedRerender.trigger() if @sortedBy
71
71
 
72
72
  # If the view's headers are 'a' tags, this view will try
73
73
  # to sort the collection using the header tags.
74
74
  $(@el).delegate '.header a', 'click', _.bind(@sort, @)
75
75
  $(@el).delegate '.editor', 'keydown', _.bind(@onKeyDown, @)
76
76
 
77
+ if @cancelOnEsc
78
+ @keyDownHandlers['ESC'] = -> @viewInEdit?.cancelEdit()
79
+
80
+ if @saveOnEnter
81
+ @keyDownHandlers['RETURN'] = -> @viewInEdit?.save()
82
+
83
+ if @useKeyboardToChangeRows
84
+ @keyDownHandlers['UP'] = -> @edit @prevView()
85
+ @keyDownHandlers['DOWN'] = -> @edit @nextView()
86
+
77
87
  @views = []
78
88
  @viewInEdit = null
79
89
  @templateOptions = {}
@@ -93,8 +103,8 @@ class window.Neat.CollectionEditor extends Backbone.View
93
103
 
94
104
  render: ->
95
105
  $el = $(@el)
96
- $el.html @template(collection: @collection)
97
- $el.cssHover '.row.interactive'
106
+ $el.html @template(@context())
107
+ $el.cssHover '.neat-row.neat-interactive'
98
108
 
99
109
  @afterRender()
100
110
 
@@ -104,6 +114,9 @@ class window.Neat.CollectionEditor extends Backbone.View
104
114
  @repaginate()
105
115
  @
106
116
 
117
+ context: ->
118
+ collection: @collection
119
+
107
120
  afterRender: ->
108
121
  @
109
122
 
@@ -208,6 +221,17 @@ class window.Neat.CollectionEditor extends Backbone.View
208
221
 
209
222
 
210
223
 
224
+ __reset: ->
225
+ @render()
226
+
227
+ __add: ->
228
+ @rerenderPage()
229
+
230
+ __remove: ->
231
+ @rerenderPage()
232
+
233
+
234
+
211
235
  debug: (o...)->
212
236
  @log(o...) if Neat.debug
213
237
 
@@ -0,0 +1,42 @@
1
+ /* Observer: this awesome class is described by The Grubbsian
2
+ http://www.thegrubbsian.com/?p=100 */
3
+ /* modified to use prototype extensions */
4
+
5
+ var Observer = (function(){
6
+ var Observation = function(name, func) {
7
+ this.name = name;
8
+ this.func = func;
9
+ };
10
+ var constructor = function() {
11
+ this.observations = [];
12
+ };
13
+ constructor.prototype = {
14
+ observe: function(name, func) {
15
+ var exists = this.observations.find(function(i) {
16
+ return (i.name==name) && (i.func==func);
17
+ });
18
+ if(!exists) {
19
+ this.observations.push(new Observation(name, func));
20
+ }
21
+ },
22
+ unobserve: function(name, func) {
23
+ for(var i=0; i<this.observations.length;) {
24
+ var observation = this.observations[i];
25
+ if((observation.name==name) && (observation.func==func)) {
26
+ this.observations.splice(i, 1);
27
+ } else {
28
+ i += 1;
29
+ }
30
+ }
31
+ },
32
+ fire: function(name, data, scope) {
33
+ if(!(data instanceof Array)) data = [data];
34
+ this.observations.each(function(i) {
35
+ if(i.name == name) {
36
+ i.func.apply(scope, data);
37
+ }
38
+ });
39
+ }
40
+ };
41
+ return constructor;
42
+ })();
@@ -1,67 +1,78 @@
1
1
  class window.Neat.ModelEditor extends Backbone.View
2
2
  tagName: 'li'
3
- className: 'row interactive editable'
3
+ className: 'neat-row neat-interactive neat-editable'
4
4
 
5
5
  initialize: (options)->
6
6
  options = options ? {}
7
7
  @templateOptions = options.templateOptions ? {}
8
8
  @viewPath = @viewPath ? options.viewPath
9
9
  @resource = @resource ? window.inflect.singularize(options.resource)
10
- $(@el).addClass(@resource)
10
+ @$el.addClass(@resource)
11
+
12
+ @model.bind 'change', @render, @
11
13
 
12
14
  # Renders the 'show' template normally,
13
15
  # renders 'edit' when in edit mode.
14
- @showTemplate = JST["#{@viewPath}/show"]
15
- @editTemplate = JST["#{@viewPath}/edit"]
16
+ @showTemplate = Neat.template["#{@viewPath}/show"]
17
+ @editTemplate = Neat.template["#{@viewPath}/edit"]
16
18
 
17
19
  # Wire up events.
18
20
  # Don't use Backbone's events hash because if subclasses
19
21
  # use that more familiar syntax, they'll blow away events
20
22
  # defined in this class.
21
- $(@el).delegate('.save-button', 'click', _.bind(@save, @))
22
- $(@el).delegate('.delete-button', 'click', _.bind(@delete, @))
23
- $(@el).delegate('.cancel-button', 'click', _.bind(@cancelEdit, @))
23
+ @$el.delegate('.save-button', 'click', _.bind(@save, @))
24
+ @$el.delegate('.delete-button', 'click', _.bind(@delete, @))
25
+ @$el.delegate('.cancel-button', 'click', _.bind(@cancelEdit, @))
24
26
 
25
27
  # Begin editing when this resource is clicked
26
28
  # unless the user clicked a link or button.
27
- $(@el).click (e)=>
29
+ @$el.click (e)=>
28
30
  @edit() if @canEdit() and !$(e.target).isIn('input, button, a, label')
29
31
 
30
32
  render: ->
31
33
  json = _.extend(@model.toJSON(), {options: @templateOptions})
32
- $(@el).html @template()(json)
33
- $(@el).attr('id', "#{@resource}_#{@model.get('id')}") # e.g. "calendar_5"
34
+ @$el.html @template()(json)
35
+ @$el.attr('id', "#{@resource}_#{@model.get('id')}") # e.g. "calendar_5"
36
+
37
+ @afterRender()
34
38
  @
35
39
 
36
- inEdit: -> $(@el).hasClass('editor')
37
- canEdit: -> $(@el).hasClass('editable') and !@inEdit()
40
+ afterRender: ->
41
+ @
42
+
43
+ inEdit: -> @$el.hasClass('editor')
44
+ canEdit: -> @$el.hasClass('neat-editable') and !@inEdit()
38
45
  template: -> if @inEdit() then @editTemplate else @showTemplate
39
46
 
40
47
  cancelEdit: (e)->
41
48
  e?.preventDefault()
42
49
  e?.stopImmediatePropagation()
43
50
  if @inEdit()
44
- $(@el).removeClass('editor').addClass('editable')
51
+ @$el.find(':focus').blur()
52
+ @$el.removeClass('editor').addClass('neat-editable')
45
53
  @render()
46
54
  @trigger('edit:end')
47
55
  @
48
56
 
49
57
  edit: ->
50
58
  unless @inEdit()
51
- $el = $(@el)
52
- $el.addClass('editor').removeClass('editable hovered')
59
+ @$el.addClass('editor').removeClass('neat-editable hovered')
53
60
  @trigger('edit:begin')
54
61
  @render()
55
- $el.find(':input:visible').first().focus()
62
+ @autofocus()
56
63
  @
57
64
 
65
+ autofocus: ->
66
+ @$el.find(':input:visible').first().focus()
67
+
58
68
  save: (e)->
59
69
  e?.preventDefault()
60
- $form = $(@el).closest('form')
61
- newAttributes = $form.serializeObject()
70
+ newAttributes = @attributesFromForm(@$el)
62
71
  @debug 'saving: ', newAttributes
63
72
  attributes = @model.changedAttributes(newAttributes)
64
73
 
74
+ return unless @okToSave(attributes)
75
+
65
76
  if attributes
66
77
  previousAttributes = @model.toJSON()
67
78
 
@@ -75,21 +86,45 @@ class window.Neat.ModelEditor extends Backbone.View
75
86
 
76
87
  @cancelEdit()
77
88
 
89
+ okToSave: (attributes)->
90
+ true
91
+
92
+ attributesFromForm: ($el)->
93
+ attrs = {}
94
+ $el.find('input, select, textarea').each ->
95
+ elem = $(this)
96
+ name = elem.attr('name')
97
+ if name
98
+ elemType = elem.attr('type')
99
+ value = elem.val()
100
+
101
+ if name.substr(-2) == '[]'
102
+ name = name.substring(0, name.length - 2)
103
+ attrs[name] = attrs[name] || []
104
+ attrs[name].push elem.val()
105
+
106
+ else if elemType == 'checkbox' || elemType == 'radio'
107
+ attrs[name] = '' if typeof(attrs[name]) == 'undefined'
108
+ attrs[name] = value if elem.prop('checked')
109
+
110
+ else
111
+ attrs[name] = value
112
+ attrs
113
+
78
114
  delete: (e)->
79
115
  e?.preventDefault()
80
- if @confirmDelete(@resource)
81
- $(@el).removeClass('editable').addClass('deleted')
116
+ @confirmDelete @resource, =>
117
+ @$el.removeClass('neat-editable').addClass('deleted')
82
118
 
83
119
  @model.destroy
84
120
  wait: true
85
- success: =>
86
- @model.collection.remove(@model) if @model.collection
87
- @onDeleteSuccess
121
+ success: => @onDeleteSuccess
88
122
  error: _.bind(@onSaveError, @)
89
123
  @cancelEdit()
90
124
 
91
- confirmDelete: (resource)->
92
- confirm("Delete this #{resource}?")
125
+ confirmDelete: (resource, callback)->
126
+ if confirm("Delete this #{resource}?")
127
+ callback()
93
128
 
94
129
 
95
130
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neat-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Lail
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-07 00:00:00.000000000 Z
12
+ date: 2015-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -47,6 +47,7 @@ files:
47
47
  - vendor/assets/javascripts/neat/lib/delayed_action.js
48
48
  - vendor/assets/javascripts/neat/lib/inflect.js
49
49
  - vendor/assets/javascripts/neat/lib/jquery_extensions.coffee
50
+ - vendor/assets/javascripts/neat/lib/observer.js
50
51
  - vendor/assets/javascripts/neat/lib/paginated_list.js
51
52
  - vendor/assets/javascripts/neat/model_editor.coffee
52
53
  homepage: ''
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  version: '0'
69
70
  requirements: []
70
71
  rubyforge_project:
71
- rubygems_version: 2.2.0
72
+ rubygems_version: 2.2.2
72
73
  signing_key:
73
74
  specification_version: 4
74
75
  summary: It's like FreightTrain for Backbone. That's pretty neat!