neat-rails 0.1.0 → 0.2.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.
@@ -1,5 +1,5 @@
1
1
  module Neat
2
2
  module Rails
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -15,7 +15,6 @@ KEYS = {
15
15
  # viewPath - by default this is set to resource
16
16
  #
17
17
  class window.Neat.CollectionEditor extends Backbone.View
18
- sortedBy: 'name'
19
18
  sortOrder: 'asc'
20
19
  sortAliases: {}
21
20
  templateOptions: {}
@@ -23,29 +22,29 @@ class window.Neat.CollectionEditor extends Backbone.View
23
22
  useKeyboardToChangeRows: true
24
23
  cancelOnEsc: true
25
24
  saveOnEnter: true
26
-
25
+
27
26
  initialize: ->
28
27
  @keyDownHandlers = {}
29
-
28
+
30
29
  @viewPath = @viewPath ? @resource
31
30
  @singular = inflect.singularize(@resource) # e.g. "calendar"
32
31
  @modelView = @modelView ? (()=>
33
32
  viewName = inflect.camelize(@singular) + "View" # e.g. "CalendarView"
34
33
  @debug "expects viewName to be #{viewName}"
35
34
  window[viewName])() # e.g. window["CalendarView"]
36
-
35
+
37
36
  @debug "looking for template at #{"#{@viewPath}/index"}"
38
37
  @template = @template ? Neat.template["#{@viewPath}/index"]
39
-
38
+
40
39
  @paginator = new window.Lail.PaginatedList [],
41
40
  page_size: if window.Neat.forPrint then Infinity else @pageSize
42
41
  always_show: false
43
42
  @paginator.onPageChange _.bind(@renderPage, @)
44
-
43
+
45
44
  @collection.bind 'reset', @__reset, @
46
45
  @collection.bind 'add', @__add, @
47
46
  @collection.bind 'remove', @__remove, @
48
-
47
+
49
48
  # We need to rerender the page if a model's attributes
50
49
  # have changed just in case this would affect how the
51
50
  # models are sorted.
@@ -68,96 +67,101 @@ class window.Neat.CollectionEditor extends Backbone.View
68
67
  @delayedRerender = new Lail.DelayedAction(_.bind(@rerenderPage, @), delay: 500)
69
68
  @collection.bind 'change', =>
70
69
  @delayedRerender.trigger() if @sortedBy
71
-
70
+
72
71
  # If the view's headers are 'a' tags, this view will try
73
72
  # to sort the collection using the header tags.
74
73
  $(@el).delegate '.header a', 'click', _.bind(@sort, @)
75
74
  $(@el).delegate '.editor', 'keydown', _.bind(@onKeyDown, @)
76
-
75
+
77
76
  if @cancelOnEsc
78
77
  @keyDownHandlers['ESC'] = -> @viewInEdit?.cancelEdit()
79
-
78
+
80
79
  if @saveOnEnter
81
80
  @keyDownHandlers['RETURN'] = -> @viewInEdit?.save()
82
-
81
+
83
82
  if @useKeyboardToChangeRows
84
83
  @keyDownHandlers['UP'] = -> @edit @prevView()
85
84
  @keyDownHandlers['DOWN'] = -> @edit @nextView()
86
-
85
+
87
86
  @views = []
88
87
  @viewInEdit = null
89
88
  @templateOptions = {}
90
-
89
+
91
90
  repaginate: ->
92
91
  @rerenderPage(1)
93
-
92
+
94
93
  rerenderPage: (page)->
95
94
  page = @paginator.getCurrentPage() unless _.isNumber(page)
96
- sortField = @sortField(@sortedBy)
97
- items = @collection.sortBy (model)->
98
- val = model.get(sortField) || ''
99
- if _.isString(val) then val.toLowerCase() else val
100
- items.reverse() if @sortOrder == 'desc'
95
+ if @sortedBy
96
+ sortField = @sortField(@sortedBy)
97
+ items = @collection.sortBy (model)->
98
+ val = model.get(sortField) || ''
99
+ if _.isString(val) then val.toLowerCase() else val
100
+ items.reverse() if @sortOrder == 'desc'
101
+ else
102
+ items = @collection.toArray()
101
103
  @paginator.init items, page
102
-
103
-
104
+
105
+
104
106
  render: ->
105
107
  $el = $(@el)
106
108
  $el.html @template(@context())
107
109
  $el.cssHover '.neat-row.neat-interactive'
108
-
110
+
109
111
  @afterRender()
110
-
112
+
111
113
  @updateSortStyle() if @sortedBy
112
-
114
+
113
115
  @paginator.renderPaginationIn($el.find('.pagination'))
114
116
  @repaginate()
115
117
  @
116
-
118
+
117
119
  context: ->
118
120
  collection: @collection
119
-
121
+
120
122
  afterRender: ->
121
123
  @
122
-
124
+
123
125
  renderPage: ->
124
126
  alt = false
125
127
  $ul = $(@el).find("##{@resource}").empty() # e.g. $('#calendars')
126
128
  @views = []
127
129
  self = @
128
-
130
+
129
131
  $(@el).find('.extended-pagination').html(@paginator.renderExtendedPagination())
130
-
132
+
131
133
  for model in @paginator.getCurrentSet()
132
- view = new @modelView # e.g. window.CalendarView
134
+ view = @constructModelView # e.g. window.CalendarView
133
135
  resource: @resource
134
136
  viewPath: @viewPath
135
137
  model: model
136
138
  templateOptions: @templateOptions
137
139
  view.bind 'edit:begin', -> self.beforeEdit.call(self, @)
138
140
  view.bind 'edit:end', -> self.afterEdit.call(self, @)
139
-
141
+
140
142
  @views.push(view)
141
-
143
+
142
144
  $el = $(view.render().el)
143
145
  $el.toggleClass 'alt', !(alt = !alt)
144
146
  $ul.append $el
145
147
  @
146
-
147
-
148
-
148
+
149
+ constructModelView: (options) ->
150
+ new @modelView options
151
+
152
+
149
153
  beforeEdit: (view)->
150
- if @viewInEdit
154
+ if @viewInEdit and @viewInEdit isnt view
151
155
  @debug "cancelling edit for ##{$(@viewInEdit.el).attr('id')} (#{@indexOfViewInEdit()})"
152
156
  @viewInEdit.cancelEdit()
153
157
  @viewInEdit = view
154
158
  @debug "beginning edit for ##{$(@viewInEdit.el).attr('id')} (#{@indexOfViewInEdit()})"
155
-
159
+
156
160
  afterEdit: (view)->
157
161
  @viewInEdit = null if @viewInEdit == view
158
-
159
-
160
-
162
+
163
+
164
+
161
165
  sort: (e)->
162
166
  e.preventDefault()
163
167
  e.stopImmediatePropagation()
@@ -171,69 +175,69 @@ class window.Neat.CollectionEditor extends Backbone.View
171
175
  @repaginate()
172
176
  @updateSortStyle()
173
177
  false
174
-
178
+
175
179
  removeSortStyle: (field)->
176
-
180
+
177
181
  updateSortStyle: ()->
178
182
  @removeSortStyle @sortedBy
179
-
183
+
180
184
  getHeader: (field)->
181
185
  $(@el).find(".header > .#{@singular}-#{field}")
182
-
186
+
183
187
  sortField: (field)->
184
188
  @sortAliases[field] ? field
185
-
186
-
187
-
189
+
190
+
191
+
188
192
  onKeyDown: (e)->
189
193
  keyName = @identifyKey(e.keyCode)
190
194
  handler = @keyDownHandlers[keyName]
191
195
  if handler && !@ignoreKeyEventsForTarget(e.target)
192
196
  e.preventDefault()
193
197
  handler.apply(@)
194
-
198
+
195
199
  identifyKey: (code)->
196
200
  KEYS[code]
197
-
201
+
198
202
  ignoreKeyEventsForTarget: (target)->
199
203
  # i.e. return true if target is in a dropdown control like Chosen
200
204
  false
201
-
202
-
203
-
205
+
206
+
207
+
204
208
  nextView: ->
205
209
  @views[@indexOfViewInEdit() + 1]
206
-
210
+
207
211
  prevView: ->
208
212
  @views[@indexOfViewInEdit() - 1]
209
-
213
+
210
214
  indexOfViewInEdit: ->
211
215
  _.indexOf @views, @viewInEdit
212
-
216
+
213
217
  edit: (view)->
214
218
  if view
215
219
  @viewInEdit?.save()
216
220
  view.edit()
217
221
  @viewInEdit = view
218
-
222
+
219
223
  cancelEdit: ->
220
224
  @viewInEdit?.cancelEdit()
221
-
222
-
223
-
225
+
226
+
227
+
224
228
  __reset: ->
225
229
  @render()
226
-
230
+
227
231
  __add: ->
228
232
  @rerenderPage()
229
-
233
+
230
234
  __remove: ->
231
235
  @rerenderPage()
232
-
233
-
234
-
236
+
237
+
238
+
235
239
  debug: (o...)->
236
240
  @log(o...) if Neat.debug
237
-
241
+
238
242
  log: (o...)->
239
243
  Neat.logger.log "[#{@viewPath}] ", o...
@@ -1,7 +1,7 @@
1
1
  var Lail; if(!Lail) Lail={};
2
2
  Lail.DelayedAction = function(callback, options) {
3
3
  // !todo: paste John Resig's code
4
-
4
+
5
5
  options = options || {};
6
6
  var self = this,
7
7
  delay = options.delay || 1000,
@@ -10,19 +10,19 @@ Lail.DelayedAction = function(callback, options) {
10
10
  counter = 0,
11
11
  _params,
12
12
  _interval;
13
-
13
+
14
14
  this.trigger = function(params) {
15
15
  _params = params;
16
16
  restartCountdown();
17
17
  }
18
-
18
+
19
19
  function restartCountdown() {
20
20
  counter = steps;
21
21
  if(!_interval) {
22
22
  _interval = setInterval(countdown, intervalPeriod);
23
23
  }
24
24
  }
25
-
25
+
26
26
  function countdown() {
27
27
  if(counter > 0) {
28
28
  counter = counter - 1;
@@ -31,14 +31,14 @@ Lail.DelayedAction = function(callback, options) {
31
31
  fireCallback();
32
32
  }
33
33
  }
34
-
34
+
35
35
  function stopCountdown() {
36
36
  if(_interval) {
37
37
  clearInterval(_interval);
38
38
  _interval = null;
39
39
  }
40
40
  }
41
-
41
+
42
42
  function fireCallback() {
43
43
  try {
44
44
  callback(_params);
@@ -46,4 +46,4 @@ Lail.DelayedAction = function(callback, options) {
46
46
  App.debug(e);
47
47
  }
48
48
  }
49
- }
49
+ }
@@ -25,33 +25,33 @@ require._core = {
25
25
  require.resolve = (function () {
26
26
  return function (x, cwd) {
27
27
  if (!cwd) cwd = '/';
28
-
28
+
29
29
  if (require._core[x]) return x;
30
30
  var path = require.modules.path();
31
31
  var y = cwd || '.';
32
-
32
+
33
33
  if (x.match(/^(?:\.\.?\/|\/)/)) {
34
34
  var m = loadAsFileSync(path.resolve(y, x))
35
35
  || loadAsDirectorySync(path.resolve(y, x));
36
36
  if (m) return m;
37
37
  }
38
-
38
+
39
39
  var n = loadNodeModulesSync(x, y);
40
40
  if (n) return n;
41
-
41
+
42
42
  throw new Error("Cannot find module '" + x + "'");
43
-
43
+
44
44
  function loadAsFileSync (x) {
45
45
  if (require.modules[x]) {
46
46
  return x;
47
47
  }
48
-
48
+
49
49
  for (var i = 0; i < require.extensions.length; i++) {
50
50
  var ext = require.extensions[i];
51
51
  if (require.modules[x + ext]) return x + ext;
52
52
  }
53
53
  }
54
-
54
+
55
55
  function loadAsDirectorySync (x) {
56
56
  x = x.replace(/\/+$/, '');
57
57
  var pkgfile = x + '/package.json';
@@ -71,10 +71,10 @@ require.resolve = (function () {
71
71
  if (m) return m;
72
72
  }
73
73
  }
74
-
74
+
75
75
  return loadAsFileSync(x + '/index');
76
76
  }
77
-
77
+
78
78
  function loadNodeModulesSync (x, start) {
79
79
  var dirs = nodeModulesPathsSync(start);
80
80
  for (var i = 0; i < dirs.length; i++) {
@@ -84,23 +84,23 @@ require.resolve = (function () {
84
84
  var n = loadAsDirectorySync(dir + '/' + x);
85
85
  if (n) return n;
86
86
  }
87
-
87
+
88
88
  var m = loadAsFileSync(x);
89
89
  if (m) return m;
90
90
  }
91
-
91
+
92
92
  function nodeModulesPathsSync (start) {
93
93
  var parts;
94
94
  if (start === '/') parts = [ '' ];
95
95
  else parts = path.normalize(start).split('/');
96
-
96
+
97
97
  var dirs = [];
98
98
  for (var i = parts.length - 1; i >= 0; i--) {
99
99
  if (parts[i] === 'node_modules') continue;
100
100
  var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
101
101
  dirs.push(dir);
102
102
  }
103
-
103
+
104
104
  return dirs;
105
105
  }
106
106
  };
@@ -116,9 +116,9 @@ require.alias = function (from, to) {
116
116
  res = require.resolve(from, '/');
117
117
  }
118
118
  var basedir = path.dirname(res);
119
-
119
+
120
120
  var keys = Object_keys(require.modules);
121
-
121
+
122
122
  for (var i = 0; i < keys.length; i++) {
123
123
  var key = keys[i];
124
124
  if (key.slice(0, basedir.length + 1) === basedir + '/') {
@@ -136,7 +136,7 @@ require.define = function (filename, fn) {
136
136
  ? ''
137
137
  : require.modules.path().dirname(filename)
138
138
  ;
139
-
139
+
140
140
  var require_ = function (file) {
141
141
  return require(file, dirname)
142
142
  };
@@ -146,7 +146,7 @@ require.define = function (filename, fn) {
146
146
  require_.modules = require.modules;
147
147
  require_.define = require.define;
148
148
  var module_ = { exports : {} };
149
-
149
+
150
150
  require.modules[filename] = function () {
151
151
  require.modules[filename]._cached = module_.exports;
152
152
  fn.call(
@@ -274,7 +274,7 @@ path = normalizeArray(filter(path.split('/'), function(p) {
274
274
  if (path && trailingSlash) {
275
275
  path += '/';
276
276
  }
277
-
277
+
278
278
  return (isAbsolute ? '/' : '') + path;
279
279
  };
280
280
 
@@ -816,7 +816,7 @@ require.define("/inflect/default_inflections.coffee", function (require, module,
816
816
  });
817
817
 
818
818
  require.define("/index.coffee", function (require, module, exports, __dirname, __filename) {
819
-
819
+
820
820
  module.exports = require("./inflect");
821
821
 
822
822
  });
@@ -9,7 +9,7 @@ $.fn.extend
9
9
  if e.type == 'mouseenter'
10
10
  $(@).addClass('hovered')
11
11
  else
12
- $(@).removeClass('hovered')
13
-
12
+ $(@).removeClass('hovered')
13
+
14
14
  isIn: (selector)->
15
15
  @is(selector) or (@parents(selector).length > 0)
@@ -38,5 +38,5 @@ var Observer = (function(){
38
38
  });
39
39
  }
40
40
  };
41
- return constructor;
41
+ return constructor;
42
42
  })();
@@ -1,10 +1,10 @@
1
1
  var Lail; if(!Lail) Lail={};
2
2
  Lail.PaginatedList = function(list, options) {
3
3
  // todo: paste John Resig's code
4
-
4
+
5
5
  options = options || {};
6
6
  var self = this;
7
-
7
+
8
8
  this.set = [];
9
9
  this.set_length = 0;
10
10
  this.current_page = 1;
@@ -14,15 +14,15 @@ Lail.PaginatedList = function(list, options) {
14
14
  this.observer = new Observer();
15
15
  this.pagination_container = null;
16
16
  this.during_init = false;
17
-
18
-
19
-
17
+
18
+
19
+
20
20
  this.count = function() {
21
21
  return self.set_length;
22
22
  }
23
-
24
-
25
-
23
+
24
+
25
+
26
26
  this.init = function(list, initialPage, options) {
27
27
  if((options || {}).page_size) {
28
28
  self.page_size = options.page_size;
@@ -38,98 +38,98 @@ Lail.PaginatedList = function(list, options) {
38
38
  self.gotoPage(initialPage || 1);
39
39
  self.during_init = false;
40
40
  }
41
-
41
+
42
42
  this.gotoPage = function(page_number) {
43
43
  page_number = +page_number; // needs to be an integer
44
44
  if(page_number < 1) page_number = 1;
45
45
  if(page_number > self.page_count) page_number = self.page_count;
46
46
  if(page_number != self.current_page) __setCurrentPage(page_number);
47
47
  }
48
-
48
+
49
49
  function __setCurrentPage(page_number) {
50
50
  self.current_page = page_number;
51
51
  self.current_set = self.set.slice(self.firstItemIndex(), self.lastItemIndex());
52
52
  renderPagination();
53
53
  notifyOfPageChange();
54
54
  }
55
-
55
+
56
56
  this.firstItemIndex = function() {
57
57
  return (self.current_page - 1) * self.page_size || 0;
58
58
  }
59
-
59
+
60
60
  this.lastItemIndex = function() {
61
61
  var end = self.current_page * self.page_size;
62
62
  return (end > self.set_length) ? self.set_length : end;
63
63
  }
64
-
64
+
65
65
  this.getCurrentPage = function() {
66
66
  return self.current_page;
67
67
  }
68
-
68
+
69
69
  this.getCurrentSet = function() {
70
70
  return self.current_set;
71
71
  }
72
-
72
+
73
73
  this.getEntireSet = function() {
74
74
  return self.set;
75
75
  }
76
-
76
+
77
77
  function renderPagination() {
78
78
  if(self.pagination_container) {
79
79
  self.pagination_container.html(self.renderPagination());
80
80
  }
81
81
  }
82
-
82
+
83
83
  function notifyOfPageChange() {
84
84
  self.observer.fire('changed', {onInit: self.during_init});
85
85
  }
86
-
87
-
88
-
86
+
87
+
88
+
89
89
  this.onPageChange = function(callback) {
90
90
  self.observer.observe('changed', callback);
91
91
  }
92
-
93
-
94
-
92
+
93
+
94
+
95
95
  this.gotoNextPage = function() {
96
- if(self.isLastPage()) {
96
+ if(self.isLastPage()) {
97
97
  return false;
98
98
  } else {
99
99
  self.gotoPage(self.current_page + 1);
100
100
  return true;
101
101
  }
102
102
  }
103
-
103
+
104
104
  this.getNextPageNumber = function() {
105
105
  return self.isLastPage() ? self.current_page : (self.current_page + 1);
106
106
  }
107
-
107
+
108
108
  this.isLastPage = function() {
109
109
  return (self.current_page == self.page_count);
110
110
  }
111
-
112
-
113
-
111
+
112
+
113
+
114
114
  this.gotoPreviousPage = function() {
115
- if(self.isFirstPage()) {
115
+ if(self.isFirstPage()) {
116
116
  return false;
117
117
  } else {
118
118
  self.gotoPage(self.current_page - 1);
119
119
  return true;
120
120
  }
121
121
  }
122
-
122
+
123
123
  this.getPreviousPageNumber = function() {
124
124
  return self.isFirstPage() ? self.current_page : (self.current_page - 1);
125
125
  }
126
-
126
+
127
127
  this.isFirstPage = function() {
128
128
  return (self.current_page == 1);
129
129
  }
130
-
131
-
132
-
130
+
131
+
132
+
133
133
  // !nb: uses jQuery!!!
134
134
  this.renderPaginationIn = function(selector) {
135
135
  self.pagination_container = jQuery(selector);
@@ -147,7 +147,7 @@ Lail.PaginatedList = function(list, options) {
147
147
  return false;
148
148
  });
149
149
  }
150
-
150
+
151
151
  // !todo: use Handlebars
152
152
  this.renderPagination = function() {
153
153
  var html = '',
@@ -155,14 +155,14 @@ Lail.PaginatedList = function(list, options) {
155
155
  count = self.page_count,
156
156
  min = 1,
157
157
  max = count;
158
-
158
+
159
159
  if(this.always_show || count > 1) {
160
160
  if(self.isFirstPage()) {
161
161
  html += '<span class="prev_page disabled">&#171; Previous</span> ';
162
162
  } else {
163
163
  html += '<a class="prev_page" href="#" rel="previous">&#171; Previous</a> ';
164
164
  }
165
-
165
+
166
166
  // list no more than 7 page numbers
167
167
  if(self.page_count > 7) {
168
168
  min = current - 3;
@@ -178,27 +178,27 @@ Lail.PaginatedList = function(list, options) {
178
178
  html += ' <a class="goto_page" href="#" id="page_' + i + '">' + i + '</a> ';
179
179
  }
180
180
  }
181
-
181
+
182
182
  if(self.isLastPage()) {
183
183
  html += ' <span class="next_page disabled">Next &#187;</span>';
184
184
  } else {
185
185
  html += ' <a class="next_page" href="#" rel="next">Next &#187;</a>';
186
186
  }
187
187
  }
188
-
188
+
189
189
  return html;
190
190
  }
191
-
191
+
192
192
  // !todo: use handlebars
193
193
  this.renderExtendedPagination = function() {
194
194
  var html = 'Listing <strong>';
195
- if(self.page_count > 1) {
195
+ if(self.page_count > 1) {
196
196
  html += (self.firstItemIndex()+1) + '&ndash;' + self.lastItemIndex() + '</strong> of <strong>';
197
197
  }
198
198
  return html + self.count() + '</strong>';
199
199
  }
200
-
201
-
202
-
200
+
201
+
202
+
203
203
  this.init(list || []);
204
- }
204
+ }
@@ -1,50 +1,55 @@
1
1
  class window.Neat.ModelEditor extends Backbone.View
2
2
  tagName: 'li'
3
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
10
  @$el.addClass(@resource)
11
-
11
+
12
12
  @model.bind 'change', @render, @
13
-
13
+
14
14
  # Renders the 'show' template normally,
15
15
  # renders 'edit' when in edit mode.
16
16
  @showTemplate = Neat.template["#{@viewPath}/show"]
17
17
  @editTemplate = Neat.template["#{@viewPath}/edit"]
18
-
18
+
19
19
  # Wire up events.
20
20
  # Don't use Backbone's events hash because if subclasses
21
21
  # use that more familiar syntax, they'll blow away events
22
22
  # defined in this class.
23
23
  @$el.delegate('.save-button', 'click', _.bind(@save, @))
24
- @$el.delegate('.delete-button', 'click', _.bind(@delete, @))
24
+ @$el.delegate('.delete-button', 'click', _.bind(@destroy, @))
25
25
  @$el.delegate('.cancel-button', 'click', _.bind(@cancelEdit, @))
26
-
26
+
27
27
  # Begin editing when this resource is clicked
28
28
  # unless the user clicked a link or button.
29
29
  @$el.click (e)=>
30
30
  @edit() if @canEdit() and !$(e.target).isIn('input, button, a, label')
31
-
31
+
32
32
  render: ->
33
33
  json = _.extend(@model.toJSON(), {options: @templateOptions})
34
34
  @$el.html @template()(json)
35
35
  @$el.attr('id', "#{@resource}_#{@model.get('id')}") # e.g. "calendar_5"
36
-
36
+
37
37
  @afterRender()
38
38
  @
39
-
39
+
40
40
  afterRender: ->
41
41
  @
42
-
42
+
43
43
  inEdit: -> @$el.hasClass('editor')
44
44
  canEdit: -> @$el.hasClass('neat-editable') and !@inEdit()
45
45
  template: -> if @inEdit() then @editTemplate else @showTemplate
46
-
46
+
47
47
  cancelEdit: (e)->
48
+ e?.preventDefault()
49
+ e?.stopImmediatePropagation()
50
+ @endEdit()
51
+
52
+ endEdit: (e)->
48
53
  e?.preventDefault()
49
54
  e?.stopImmediatePropagation()
50
55
  if @inEdit()
@@ -53,7 +58,7 @@ class window.Neat.ModelEditor extends Backbone.View
53
58
  @render()
54
59
  @trigger('edit:end')
55
60
  @
56
-
61
+
57
62
  edit: ->
58
63
  unless @inEdit()
59
64
  @$el.addClass('editor').removeClass('neat-editable hovered')
@@ -61,21 +66,21 @@ class window.Neat.ModelEditor extends Backbone.View
61
66
  @render()
62
67
  @autofocus()
63
68
  @
64
-
69
+
65
70
  autofocus: ->
66
71
  @$el.find(':input:visible').first().focus()
67
-
72
+
68
73
  save: (e)->
69
74
  e?.preventDefault()
70
75
  newAttributes = @attributesFromForm(@$el)
71
76
  @debug 'saving: ', newAttributes
72
77
  attributes = @model.changedAttributes(newAttributes)
73
-
78
+
74
79
  return unless @okToSave(attributes)
75
-
80
+
76
81
  if attributes
77
82
  previousAttributes = @model.toJSON()
78
-
83
+
79
84
  @model.save attributes,
80
85
  wait: true
81
86
  success: =>
@@ -83,12 +88,12 @@ class window.Neat.ModelEditor extends Backbone.View
83
88
  @debug " . #{attribute} changed from ", previousAttributes[attribute], " to ", @model.get(attribute)
84
89
  @onSaveSuccess()
85
90
  error: _.bind(@onSaveError, @)
86
-
87
- @cancelEdit()
88
-
91
+
92
+ @endEdit()
93
+
89
94
  okToSave: (attributes)->
90
95
  true
91
-
96
+
92
97
  attributesFromForm: ($el)->
93
98
  attrs = {}
94
99
  $el.find('input, select, textarea').each ->
@@ -110,33 +115,33 @@ class window.Neat.ModelEditor extends Backbone.View
110
115
  else
111
116
  attrs[name] = value
112
117
  attrs
113
-
114
- delete: (e)->
118
+
119
+ destroy: (e)->
115
120
  e?.preventDefault()
116
- @confirmDelete @resource, =>
121
+ @confirmDestroy @resource, =>
117
122
  @$el.removeClass('neat-editable').addClass('deleted')
118
-
123
+
119
124
  @model.destroy
120
125
  wait: true
121
- success: => @onDeleteSuccess
126
+ success: => @onDestroySuccess
122
127
  error: _.bind(@onSaveError, @)
123
- @cancelEdit()
124
-
125
- confirmDelete: (resource, callback)->
128
+ @endEdit()
129
+
130
+ confirmDestroy: (resource, callback)->
126
131
  if confirm("Delete this #{resource}?")
127
132
  callback()
128
-
129
-
130
-
133
+
134
+
135
+
131
136
  onSaveSuccess: ->
132
137
  onSaveError: ->
133
- onDeleteSuccess: ->
134
- onDeleteError: ->
135
-
136
-
137
-
138
+ onDestroySuccess: ->
139
+ onDestroyError: ->
140
+
141
+
142
+
138
143
  debug: (o...)->
139
144
  @log(o...) if Neat.debug
140
-
145
+
141
146
  log: (o...)->
142
147
  Neat.logger.log "[#{@resource}] ", o...
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neat-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Bob Lail
@@ -9,20 +10,22 @@ authors:
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-09-07 00:00:00.000000000 Z
13
+ date: 2016-02-08 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rake
16
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
17
19
  requirements:
18
- - - ">="
20
+ - - ! '>='
19
21
  - !ruby/object:Gem::Version
20
22
  version: '0'
21
23
  type: :development
22
24
  prerelease: false
23
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
24
27
  requirements:
25
- - - ">="
28
+ - - ! '>='
26
29
  - !ruby/object:Gem::Version
27
30
  version: '0'
28
31
  description: It allows editing collections and models inline
@@ -33,7 +36,7 @@ executables: []
33
36
  extensions: []
34
37
  extra_rdoc_files: []
35
38
  files:
36
- - ".gitignore"
39
+ - .gitignore
37
40
  - Gemfile
38
41
  - LICENSE.txt
39
42
  - README.md
@@ -52,25 +55,32 @@ files:
52
55
  - vendor/assets/javascripts/neat/model_editor.coffee
53
56
  homepage: ''
54
57
  licenses: []
55
- metadata: {}
56
58
  post_install_message:
57
59
  rdoc_options: []
58
60
  require_paths:
59
61
  - lib
60
62
  required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
61
64
  requirements:
62
- - - ">="
65
+ - - ! '>='
63
66
  - !ruby/object:Gem::Version
64
67
  version: '0'
68
+ segments:
69
+ - 0
70
+ hash: 2435929593431474536
65
71
  required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
66
73
  requirements:
67
- - - ">="
74
+ - - ! '>='
68
75
  - !ruby/object:Gem::Version
69
76
  version: '0'
77
+ segments:
78
+ - 0
79
+ hash: 2435929593431474536
70
80
  requirements: []
71
81
  rubyforge_project:
72
- rubygems_version: 2.2.2
82
+ rubygems_version: 1.8.23.2
73
83
  signing_key:
74
- specification_version: 4
84
+ specification_version: 3
75
85
  summary: It's like FreightTrain for Backbone. That's pretty neat!
76
86
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 695ee4ffacf2d5ff9962b563842796a8e19f1133
4
- data.tar.gz: 5d86e89f8d9fa6bd3d8bcf4b890bac853047b568
5
- SHA512:
6
- metadata.gz: 26244d4b5882ee55c5413495fe5897dbb93473f4f1135bd3610a0059e368e6cc3f38a41b7037398e3bfe0608670bc038ae5a1e0ebf18e39eebaf9e2a5674cb5f
7
- data.tar.gz: 110fbfca1f62d9101e10f605ac46663a5dbff5ebb7428d765b529d4ba8cebcd9a6baf5299fd40d2f83f9b3acd7aa95d71424216c72637e5317d44af172a0fa3f