neat-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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