chr 0.2.5 → 0.2.7

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: bc38de2cb0b82aa71968cd48127d83146daa2bfd
4
- data.tar.gz: 9a373db5e5f9d4e1ce08ef020b8691b4b3c5d473
3
+ metadata.gz: 5a86d147a723188f151bcacca8c35a403bd6fcf3
4
+ data.tar.gz: f1be1f7997afb7976ecfbda0f1641b69e12e3ac2
5
5
  SHA512:
6
- metadata.gz: b13c5bdb285b264cd540f236b6c55aa8c5671c66122798a5c1f840b8055d18c1a775d60c7fb9305c10cb3e8e06d20c616ae1fe6d296739c198418929bf1f06ca
7
- data.tar.gz: 8223dd3c23d34d4da1cfbba9d22f7089e5ebe201a26ad6e58f6d08d482803c0613e794607f348a1e0ba7ef8dd587ce9e680bb6ce16ab1db72992f4920ea2dce3
6
+ metadata.gz: 2aec7e0a14af19ce53844ab6b58e615a26db8338a9bfbf7382869ce6f796383128b409625bd2fcc091e02b42a92a93f035902f7dfa8857d0c65eeb0e6aefc8be
7
+ data.tar.gz: 918c153a9f11d8e7add0fcd26fedf80cf701bc398c3f1c7c0367dbf7f0374b61a140ef24516cd73692ed117eaec20cfca4dd944ad8f5f8210fb9a4d3dfd16905
data/README.md CHANGED
@@ -14,20 +14,19 @@ Application setup:
14
14
  postsConfig = (data) ->
15
15
  itemTitleField: 'title'
16
16
  arrayStore: new RestArrayStore({
17
- resource: 'post'
18
17
  path: '/admin/posts'
19
18
  sortBy: 'title'
20
19
  })
21
20
  formSchema:
22
- title { type: 'string' }
23
- body: { type: 'text' }
21
+ title: { type: 'string' }
22
+ body: { type: 'text' }
24
23
 
25
24
  $ ->
26
25
  config =
27
26
  modules:
28
27
  posts: postsConfig()
29
28
 
30
- chr.start(config)
29
+ chr.start(config)
31
30
  ```
32
31
 
33
32
  Styles setup:
@@ -80,14 +80,6 @@ class @List
80
80
  @$newBtn.on 'click', (e) => @_new(e)
81
81
  @$header.append @$newBtn
82
82
 
83
- # search
84
- @$search =$ """<div class='search' style='display: none;'>
85
- <a href='#' class='icon'></a>
86
- <input type='text' placeholder='Search...' />
87
- <a href='#' class='cancel'>Cancel</a>
88
- </div>"""
89
- @$header.append @$search
90
-
91
83
  if @config.items then @_process_config_items()
92
84
  if @config.arrayStore then @_bind_config_array_store()
93
85
  if @config.objectStore then @_bind_config_object_store()
@@ -52,10 +52,10 @@
52
52
  @_bind_pagination()
53
53
 
54
54
  if @config.arrayStore.searchable
55
- @_bind_search(this)
55
+ @_bind_search()
56
56
 
57
57
  if @config.arrayStore.reorderable
58
- @_bind_reorder(this)
58
+ @_bind_reorder()
59
59
 
60
60
 
61
61
  _bind_config_object_store: ->
@@ -1,26 +1,34 @@
1
1
  # -----------------------------------------------------------------------------
2
2
  # LIST PAGINATION
3
- # todo:
4
- # - trigger onScroll event only when scrolling down
5
3
  # -----------------------------------------------------------------------------
6
4
 
7
5
  @listPagination =
6
+
8
7
  # PRIVATE ===============================================
9
8
 
10
9
  _bind_pagination: ->
11
- arrayStore = @config.arrayStore
10
+ @lastScrollTop = 0
11
+
12
12
  @$items.scroll (e) =>
13
- if ! arrayStore.dataFetchLock
14
- # TODO: update this logic as it's not reliable when items has different height
15
- $listChildren = @$items.children()
16
- listChildrenCount = $listChildren.length
17
- listFirstChildHeight = $listChildren.first().outerHeight()
18
- listHeight = listChildrenCount * listFirstChildHeight
19
- viewHeight = @$el.height()
20
-
21
- if listHeight < (viewHeight + e.target.scrollTop + 100)
22
- @_show_spinner()
23
- arrayStore.load()
13
+ # trigger next page loading only when scrolling to bottom
14
+ if @lastScrollTop < e.target.scrollTop
15
+ @lastScrollTop = e.target.scrollTop
16
+
17
+ if ! @config.arrayStore.dataFetchLock
18
+
19
+ if @listItemsHeight < (@listViewHeight + e.target.scrollTop + 100)
20
+ @_show_spinner()
21
+ @config.arrayStore.load
22
+ onSuccess: => @_update_height_params()
23
+ onError: => chr.showAlert("Can't load next page, server error 500.")
24
+
25
+ @_update_height_params()
26
+
27
+
28
+ _update_height_params: ->
29
+ @listViewHeight = @$el.height()
30
+ @listItemsHeight = 0
31
+ @$items.children().each (i, el) => @listItemsHeight += $(el).height()
24
32
 
25
33
 
26
34
 
@@ -8,12 +8,13 @@
8
8
  # -----------------------------------------------------------------------------
9
9
 
10
10
  @listReorder =
11
+
11
12
  # PRIVATE ===============================================
12
13
 
13
- _bind_reorder: (listEl) ->
14
- items = listEl.items
15
- list = listEl.$items.get(0)
16
- arrayStore = listEl.config.arrayStore
14
+ _bind_reorder: ->
15
+ items = @items
16
+ list = @$items.get(0)
17
+ arrayStore = @config.arrayStore
17
18
 
18
19
  config = arrayStore.reorderable
19
20
 
@@ -3,38 +3,51 @@
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
5
  @listSearch =
6
+
6
7
  # PRIVATE ===============================================
7
8
 
8
- _bind_search: (listEl) ->
9
- $input = listEl.$search
10
- arrayStore = listEl.config.arrayStore
9
+ _bind_search: ->
10
+ @$search =$ "<div class='search'></div>"
11
+ @$searchIcon =$ "<a href='#' class='icon'></a>"
12
+ @$searchInput =$ "<input type='text' placeholder='Search...' />"
13
+ @$searchCancel =$ "<a href='#' class='cancel'>Cancel</a>"
11
14
 
12
- search = (input) ->
13
- query = $(input).val()
14
- listEl._show_spinner()
15
- arrayStore.search(query)
15
+ @$header.append(@$search)
16
+ @$search.append(@$searchIcon)
17
+ @$search.append(@$searchInput)
18
+ @$search.append(@$searchCancel)
16
19
 
17
- show = ->
18
- listEl.$el.addClass 'list-search'
19
- $input.find('input').focus()
20
+ @$searchInput.on 'keyup', (e) =>
21
+ if e.keyCode == 27 # esc
22
+ return @_on_search_cancel()
20
23
 
21
- cancel = ->
22
- listEl.$el.removeClass 'list-search'
23
- $input.find('input').val('')
24
- listEl._show_spinner()
25
- arrayStore.reset()
24
+ if e.keyCode == 13 # enter
25
+ return @_on_search()
26
26
 
27
- $input.show()
27
+ @$searchIcon.on 'click', (e) => e.preventDefault() ; @_on_search_show()
28
+ @$searchCancel.on 'click', (e) => e.preventDefault() ; @_on_search_cancel()
28
29
 
29
- $input.on 'keyup', 'input', (e) =>
30
- if e.keyCode == 27 # esc
31
- return cancel()
32
30
 
33
- if e.keyCode == 13 # enter
34
- return search(e.target)
31
+ # EVENTS ================================================
32
+
33
+ _on_search: ->
34
+ query = @$searchInput.val()
35
+ @_show_spinner()
36
+ @config.arrayStore.search(query)
37
+
38
+
39
+ _on_search_show: ->
40
+ @$el.addClass('list-search')
41
+ @$searchInput.focus()
42
+ @$search.show()
43
+
35
44
 
36
- $input.on 'click', '.icon', (e) => e.preventDefault() ; show()
37
- $input.on 'click', '.cancel', (e) => e.preventDefault() ; cancel()
45
+ _on_search_cancel: ->
46
+ @$el.removeClass('list-search')
47
+ @$searchInput.val('')
48
+ @_show_spinner()
49
+ # use reset(false) to do not sync with the existing list items
50
+ @config.arrayStore.reset(false)
38
51
 
39
52
 
40
53
 
@@ -45,6 +45,8 @@ class @ArrayStore
45
45
  @_initialize_database()
46
46
 
47
47
 
48
+ # PRIVATE ===============================================
49
+
48
50
  # when store is reorderable update sorting configuration
49
51
  _initialize_reorderable: ->
50
52
  if @reorderable
@@ -163,6 +165,8 @@ class @ArrayStore
163
165
  return object
164
166
 
165
167
 
168
+ # PUBLIC ================================================
169
+
166
170
  # subsribe to store event
167
171
  on: (eventType, callback) ->
168
172
  $(this).on eventType, (e, data) -> callback(e, data)
@@ -13,12 +13,18 @@ class @ObjectStore
13
13
  constructor: (@config={}) ->
14
14
  @_initialize_database()
15
15
 
16
+ # PRIVATE ===============================================
17
+
16
18
  _initialize_database: ->
17
19
  @_data = @config.data
18
20
 
21
+
22
+ # PUBLIC ================================================
23
+
19
24
  loadObject: ->
20
25
  @_data
21
26
 
27
+
22
28
  update: (id, value, callback) ->
23
29
  $.extend(@_data, value)
24
30
  callback?(@_data)
@@ -26,7 +26,9 @@
26
26
  #
27
27
  # -----------------------------------------------------------------------------
28
28
  class @MongosteenArrayStore extends RestArrayStore
29
- # initial store configuration
29
+
30
+ # PRIVATE ===============================================
31
+
30
32
  _initialize_database: ->
31
33
  @dataFetchLock = false
32
34
  @ajaxConfig =
@@ -41,6 +43,7 @@ class @MongosteenArrayStore extends RestArrayStore
41
43
  @objectsPerPage = chr.itemsPerPageRequest ? 20
42
44
 
43
45
  if @pagination
46
+ @lastPageLoaded = false
44
47
  @_bind_pagination_sync()
45
48
 
46
49
 
@@ -49,8 +52,6 @@ class @MongosteenArrayStore extends RestArrayStore
49
52
  # database while loading next page
50
53
  # ---------------------------------------------------------
51
54
  _bind_pagination_sync: ->
52
- @lastPageLoaded = false
53
-
54
55
  # when object's added to the end of the list & not on the last page,
55
56
  # we don't know it's position on the backend, so remove it from store
56
57
  $(this).on 'object_added', (e, data) =>
@@ -87,7 +88,7 @@ class @MongosteenArrayStore extends RestArrayStore
87
88
  @nextPage -= 1 ; @load()
88
89
 
89
90
 
90
- _udpate_next_page: (data) ->
91
+ _update_next_page: (data) ->
91
92
  if @pagination
92
93
  if data.length > 0
93
94
  @lastPageLoaded = true
@@ -140,9 +141,13 @@ class @MongosteenArrayStore extends RestArrayStore
140
141
  return formDataObject
141
142
 
142
143
 
143
- # load results for search query
144
+ # PUBLIC ================================================
145
+
146
+ # load first page of results for search query, skip store 'object_removed'
147
+ # event handler on @_reset_data()
144
148
  search: (@searchQuery) ->
145
- @nextPage = 1
149
+ @nextPage = 1
150
+ @lastPageLoaded = true
146
151
  @_reset_data()
147
152
  @load()
148
153
 
@@ -165,7 +170,7 @@ class @MongosteenArrayStore extends RestArrayStore
165
170
  params = $.param(params)
166
171
 
167
172
  @_ajax 'GET', null, params, ((data) =>
168
- @_udpate_next_page(data)
173
+ @_update_next_page(data)
169
174
  @_add_data_object(o) for o in data
170
175
 
171
176
  callbacks.onSuccess(data)
@@ -174,12 +179,18 @@ class @MongosteenArrayStore extends RestArrayStore
174
179
  ), callbacks.onError
175
180
 
176
181
 
177
- # reset data and load first page
178
- reset: ->
182
+ # reset data and load first page, by default this sync with
183
+ # objects that are currently in the _data, if you want to reset
184
+ # these use `reset(false)`
185
+ reset: (sync_with_existing_objects=true)->
179
186
  @searchQuery = ''
180
187
  @nextPage = 1
181
188
  params = {}
182
189
 
190
+ if ! sync_with_existing_objects
191
+ @lastPageLoaded = true
192
+ @_reset_data()
193
+
183
194
  if @pagination
184
195
  @lastPageLoaded = false
185
196
  params.page = @nextPage
@@ -188,7 +199,7 @@ class @MongosteenArrayStore extends RestArrayStore
188
199
  params = $.param(params)
189
200
 
190
201
  @_ajax 'GET', null, params, ((data) =>
191
- @_udpate_next_page(data)
202
+ @_update_next_page(data)
192
203
  @_sync_with_data_objects(data)
193
204
 
194
205
  $(this).trigger('objects_added', { objects: data })
@@ -10,7 +10,9 @@
10
10
  # MONGOSTEEN (RAILS) OBJECT STORE IMPLEMENTATION
11
11
  # -----------------------------------------------------------------------------
12
12
  class @MongosteenObjectStore extends RestObjectStore
13
- # initial store configuration
13
+
14
+ # PRIVATE ===============================================
15
+
14
16
  _initialize_database: ->
15
17
  @dataFetchLock = false
16
18
  @ajaxConfig =
@@ -10,7 +10,9 @@
10
10
  # REST ARRAY STORE
11
11
  # -----------------------------------------------------------------------------
12
12
  class @RestArrayStore extends ArrayStore
13
- # initial store configuration
13
+
14
+ # PRIVATE ===============================================
15
+
14
16
  _initialize_database: ->
15
17
  @dataFetchLock = false
16
18
  @ajaxConfig = {}
@@ -65,6 +67,8 @@ class @RestArrayStore extends ArrayStore
65
67
  @_update_data_object(id, objectsMap[id])
66
68
 
67
69
 
70
+ # PUBLIC ================================================
71
+
68
72
  # load a single object, this is used in view when
69
73
  # store has not required item
70
74
  loadObject: (id, callbacks={}) ->
@@ -10,6 +10,9 @@
10
10
  # REST OBJECT STORE
11
11
  # -----------------------------------------------------------------------------
12
12
  class @RestObjectStore extends ObjectStore
13
+
14
+ # PRIVATE ===============================================
15
+
13
16
  _initialize_database: ->
14
17
  @dataFetchLock = false
15
18
  @ajaxConfig = {}
@@ -51,6 +54,8 @@ class @RestObjectStore extends ObjectStore
51
54
  $.ajax options
52
55
 
53
56
 
57
+ # PUBLIC ================================================
58
+
54
59
  # load a single object, this is used in view when
55
60
  # store has not required item
56
61
  loadObject: (callbacks={}) ->
@@ -30,7 +30,7 @@ class @InputRedactor extends InputString
30
30
 
31
31
  initialize: ->
32
32
  plugins = [ 'fixedtoolbar' ]
33
- if Loft then plugins.push('loft')
33
+ if Loft? then plugins.push('loft')
34
34
 
35
35
  redactor_options =
36
36
  focus: false
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chr",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "homepage": "https://github.com/slate-studio/chr",
5
5
  "authors": [
6
6
  "Slate Studio (http://www.slatestudio.com)"
@@ -3085,10 +3085,10 @@ this.listConfig = {
3085
3085
  this._bind_pagination();
3086
3086
  }
3087
3087
  if (this.config.arrayStore.searchable) {
3088
- this._bind_search(this);
3088
+ this._bind_search();
3089
3089
  }
3090
3090
  if (this.config.arrayStore.reorderable) {
3091
- return this._bind_reorder(this);
3091
+ return this._bind_reorder();
3092
3092
  }
3093
3093
  },
3094
3094
  _bind_config_object_store: function() {}
@@ -3096,33 +3096,46 @@ this.listConfig = {
3096
3096
 
3097
3097
  this.listPagination = {
3098
3098
  _bind_pagination: function() {
3099
- var arrayStore;
3100
- arrayStore = this.config.arrayStore;
3101
- return this.$items.scroll((function(_this) {
3099
+ this.lastScrollTop = 0;
3100
+ this.$items.scroll((function(_this) {
3102
3101
  return function(e) {
3103
- var $listChildren, listChildrenCount, listFirstChildHeight, listHeight, viewHeight;
3104
- if (!arrayStore.dataFetchLock) {
3105
- $listChildren = _this.$items.children();
3106
- listChildrenCount = $listChildren.length;
3107
- listFirstChildHeight = $listChildren.first().outerHeight();
3108
- listHeight = listChildrenCount * listFirstChildHeight;
3109
- viewHeight = _this.$el.height();
3110
- if (listHeight < (viewHeight + e.target.scrollTop + 100)) {
3111
- _this._show_spinner();
3112
- return arrayStore.load();
3102
+ if (_this.lastScrollTop < e.target.scrollTop) {
3103
+ _this.lastScrollTop = e.target.scrollTop;
3104
+ if (!_this.config.arrayStore.dataFetchLock) {
3105
+ if (_this.listItemsHeight < (_this.listViewHeight + e.target.scrollTop + 100)) {
3106
+ _this._show_spinner();
3107
+ return _this.config.arrayStore.load({
3108
+ onSuccess: function() {
3109
+ return _this._update_height_params();
3110
+ },
3111
+ onError: function() {
3112
+ return chr.showAlert("Can't load next page, server error 500.");
3113
+ }
3114
+ });
3115
+ }
3113
3116
  }
3114
3117
  }
3115
3118
  };
3116
3119
  })(this));
3120
+ return this._update_height_params();
3121
+ },
3122
+ _update_height_params: function() {
3123
+ this.listViewHeight = this.$el.height();
3124
+ this.listItemsHeight = 0;
3125
+ return this.$items.children().each((function(_this) {
3126
+ return function(i, el) {
3127
+ return _this.listItemsHeight += $(el).height();
3128
+ };
3129
+ })(this));
3117
3130
  }
3118
3131
  };
3119
3132
 
3120
3133
  this.listReorder = {
3121
- _bind_reorder: function(listEl) {
3134
+ _bind_reorder: function() {
3122
3135
  var _getObjectNewPosition, arrayStore, config, items, list;
3123
- items = listEl.items;
3124
- list = listEl.$items.get(0);
3125
- arrayStore = listEl.config.arrayStore;
3136
+ items = this.items;
3137
+ list = this.$items.get(0);
3138
+ arrayStore = this.config.arrayStore;
3126
3139
  config = arrayStore.reorderable;
3127
3140
  _getObjectNewPosition = function(el) {
3128
3141
  var $el, newPosition, nextObjectId, nextObjectPosition, prevObjectId, prevObjectPosition;
@@ -3178,49 +3191,54 @@ this.listReorder = {
3178
3191
  };
3179
3192
 
3180
3193
  this.listSearch = {
3181
- _bind_search: function(listEl) {
3182
- var $input, arrayStore, cancel, search, show;
3183
- $input = listEl.$search;
3184
- arrayStore = listEl.config.arrayStore;
3185
- search = function(input) {
3186
- var query;
3187
- query = $(input).val();
3188
- listEl._show_spinner();
3189
- return arrayStore.search(query);
3190
- };
3191
- show = function() {
3192
- listEl.$el.addClass('list-search');
3193
- return $input.find('input').focus();
3194
- };
3195
- cancel = function() {
3196
- listEl.$el.removeClass('list-search');
3197
- $input.find('input').val('');
3198
- listEl._show_spinner();
3199
- return arrayStore.reset();
3200
- };
3201
- $input.show();
3202
- $input.on('keyup', 'input', (function(_this) {
3194
+ _bind_search: function() {
3195
+ this.$search = $("<div class='search'></div>");
3196
+ this.$searchIcon = $("<a href='#' class='icon'></a>");
3197
+ this.$searchInput = $("<input type='text' placeholder='Search...' />");
3198
+ this.$searchCancel = $("<a href='#' class='cancel'>Cancel</a>");
3199
+ this.$header.append(this.$search);
3200
+ this.$search.append(this.$searchIcon);
3201
+ this.$search.append(this.$searchInput);
3202
+ this.$search.append(this.$searchCancel);
3203
+ this.$searchInput.on('keyup', (function(_this) {
3203
3204
  return function(e) {
3204
3205
  if (e.keyCode === 27) {
3205
- return cancel();
3206
+ return _this._on_search_cancel();
3206
3207
  }
3207
3208
  if (e.keyCode === 13) {
3208
- return search(e.target);
3209
+ return _this._on_search();
3209
3210
  }
3210
3211
  };
3211
3212
  })(this));
3212
- $input.on('click', '.icon', (function(_this) {
3213
+ this.$searchIcon.on('click', (function(_this) {
3213
3214
  return function(e) {
3214
3215
  e.preventDefault();
3215
- return show();
3216
+ return _this._on_search_show();
3216
3217
  };
3217
3218
  })(this));
3218
- return $input.on('click', '.cancel', (function(_this) {
3219
+ return this.$searchCancel.on('click', (function(_this) {
3219
3220
  return function(e) {
3220
3221
  e.preventDefault();
3221
- return cancel();
3222
+ return _this._on_search_cancel();
3222
3223
  };
3223
3224
  })(this));
3225
+ },
3226
+ _on_search: function() {
3227
+ var query;
3228
+ query = this.$searchInput.val();
3229
+ this._show_spinner();
3230
+ return this.config.arrayStore.search(query);
3231
+ },
3232
+ _on_search_show: function() {
3233
+ this.$el.addClass('list-search');
3234
+ this.$searchInput.focus();
3235
+ return this.$search.show();
3236
+ },
3237
+ _on_search_cancel: function() {
3238
+ this.$el.removeClass('list-search');
3239
+ this.$searchInput.val('');
3240
+ this._show_spinner();
3241
+ return this.config.arrayStore.reset(false);
3224
3242
  }
3225
3243
  };
3226
3244
 
@@ -3276,8 +3294,6 @@ this.List = (function() {
3276
3294
  })(this));
3277
3295
  this.$header.append(this.$newBtn);
3278
3296
  }
3279
- this.$search = $("<div class='search' style='display: none;'>\n <a href='#' class='icon'></a>\n <input type='text' placeholder='Search...' />\n <a href='#' class='cancel'>Cancel</a>\n</div>");
3280
- this.$header.append(this.$search);
3281
3297
  if (this.config.items) {
3282
3298
  this._process_config_items();
3283
3299
  }
@@ -5505,12 +5521,12 @@ this.MongosteenArrayStore = (function(superClass) {
5505
5521
  this.nextPage = 1;
5506
5522
  this.objectsPerPage = (ref2 = chr.itemsPerPageRequest) != null ? ref2 : 20;
5507
5523
  if (this.pagination) {
5524
+ this.lastPageLoaded = false;
5508
5525
  return this._bind_pagination_sync();
5509
5526
  }
5510
5527
  };
5511
5528
 
5512
5529
  MongosteenArrayStore.prototype._bind_pagination_sync = function() {
5513
- this.lastPageLoaded = false;
5514
5530
  $(this).on('object_added', (function(_this) {
5515
5531
  return function(e, data) {
5516
5532
  var new_object, new_object_position;
@@ -5551,7 +5567,7 @@ this.MongosteenArrayStore = (function(superClass) {
5551
5567
  return this.load();
5552
5568
  };
5553
5569
 
5554
- MongosteenArrayStore.prototype._udpate_next_page = function(data) {
5570
+ MongosteenArrayStore.prototype._update_next_page = function(data) {
5555
5571
  if (this.pagination) {
5556
5572
  if (data.length > 0) {
5557
5573
  this.lastPageLoaded = true;
@@ -5602,6 +5618,7 @@ this.MongosteenArrayStore = (function(superClass) {
5602
5618
  MongosteenArrayStore.prototype.search = function(searchQuery) {
5603
5619
  this.searchQuery = searchQuery;
5604
5620
  this.nextPage = 1;
5621
+ this.lastPageLoaded = true;
5605
5622
  this._reset_data();
5606
5623
  return this.load();
5607
5624
  };
@@ -5629,7 +5646,7 @@ this.MongosteenArrayStore = (function(superClass) {
5629
5646
  return this._ajax('GET', null, params, ((function(_this) {
5630
5647
  return function(data) {
5631
5648
  var i, len, o;
5632
- _this._udpate_next_page(data);
5649
+ _this._update_next_page(data);
5633
5650
  for (i = 0, len = data.length; i < len; i++) {
5634
5651
  o = data[i];
5635
5652
  _this._add_data_object(o);
@@ -5642,11 +5659,18 @@ this.MongosteenArrayStore = (function(superClass) {
5642
5659
  })(this)), callbacks.onError);
5643
5660
  };
5644
5661
 
5645
- MongosteenArrayStore.prototype.reset = function() {
5662
+ MongosteenArrayStore.prototype.reset = function(sync_with_existing_objects) {
5646
5663
  var params;
5664
+ if (sync_with_existing_objects == null) {
5665
+ sync_with_existing_objects = true;
5666
+ }
5647
5667
  this.searchQuery = '';
5648
5668
  this.nextPage = 1;
5649
5669
  params = {};
5670
+ if (!sync_with_existing_objects) {
5671
+ this.lastPageLoaded = true;
5672
+ this._reset_data();
5673
+ }
5650
5674
  if (this.pagination) {
5651
5675
  this.lastPageLoaded = false;
5652
5676
  params.page = this.nextPage;
@@ -5655,7 +5679,7 @@ this.MongosteenArrayStore = (function(superClass) {
5655
5679
  params = $.param(params);
5656
5680
  return this._ajax('GET', null, params, ((function(_this) {
5657
5681
  return function(data) {
5658
- _this._udpate_next_page(data);
5682
+ _this._update_next_page(data);
5659
5683
  _this._sync_with_data_objects(data);
5660
5684
  return $(_this).trigger('objects_added', {
5661
5685
  objects: data
@@ -125,7 +125,7 @@ this.InputRedactor = (function(superClass) {
125
125
  InputRedactor.prototype.initialize = function() {
126
126
  var base, base1, plugins, redactor_options;
127
127
  plugins = ['fixedtoolbar'];
128
- if (Loft) {
128
+ if (typeof Loft !== "undefined" && Loft !== null) {
129
129
  plugins.push('loft');
130
130
  }
131
131
  redactor_options = {
@@ -102,8 +102,7 @@ Admin app layout ```app/views/layouts/admin.html.erb```:
102
102
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
103
103
  <title>Admin</title>
104
104
  <%= csrf_meta_tags %>
105
- <%= stylesheet_link_tag :admin, media: "all" %>
106
- <%= javascript_include_tag :admin %>
105
+ <%= stylesheet_link_tag :admin, media: "all" %>
107
106
  </head>
108
107
 
109
108
  <%= yield %>
@@ -116,6 +115,7 @@ Admin index view ```app/views/admin/index.html.erb```:
116
115
  <body class='loading'>
117
116
  <%= link_to 'Sign Out', destroy_admin_session_path, method: :delete, style: 'display:none;' %>
118
117
  </body>
118
+ <%= javascript_include_tag :admin %>
119
119
  ```
120
120
 
121
121
  New session view for devise ```app/views/admin/devise_overrides/sessions/new.html.erb```:
@@ -191,50 +191,28 @@ Last import in the code above is optional. But here is a default source for it a
191
191
 
192
192
  ```scss
193
193
  .sign-in {
194
- font-size: 14px;
195
- color: #555;
196
- margin: 3em 0 0 3em;
197
-
198
- h2 {
199
- text-transform: uppercase;
200
- font-size: 1em;
201
- font-size: 16px;
202
- color: $black;
203
- margin-bottom: 1.5em;
204
- }
194
+ margin: 2em; max-width: 18em;
205
195
 
206
- p {
207
- margin: -1.5em 0 2em;
208
- color: $positiveColor;
209
- }
196
+ h2 { text-transform: uppercase; color: $black; }
197
+ input { @include noFocus(); }
198
+ label { color: $black; }
199
+ .input { margin-bottom: .75em; }
210
200
 
211
- .form-actions, .form-inputs {
212
- max-width: 280px;
213
- }
201
+ .input input[type=checkbox] { margin-right: .5em; }
214
202
 
215
- .input {
216
- margin-bottom: 1.5em;
203
+ .input input.email, .input input.password {
204
+ float: right; margin: -2px 0 0; width: 12em;
205
+ border: 0; border-bottom: 1px solid $contrastColor;
217
206
  }
218
207
 
219
- input.string, input.password {
220
- float: right;
221
- margin-top: -.45em;
222
- padding: .25em .5em;
223
- width: 13.5em;
224
- }
225
-
226
- label.boolean input {
227
- margin-right: .25em;
228
- }
208
+ .input.boolean { margin-top: 1.25em; }
229
209
 
230
210
  .form-actions input {
231
- width: 100%;
232
- padding: 1em 2em;
233
- background-color: $positiveColor;
234
- border: 0;
235
- color: $white;
211
+ width: 100%; padding: 1em 2em; margin-top: .75em;
212
+ color: $white; background-color: $positiveColor; border: 0;
236
213
  }
237
214
  }
215
+
238
216
  ```
239
217
 
240
218
  **Third**: make sure admin assets are precompiled on production, include ```admin.js``` and ```admin.css``` in ```config/initializers/assets.rb```:
@@ -1,3 +1,3 @@
1
1
  module Chr
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.7"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chr",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "devDependencies": {
5
5
  "grunt": "^0.4.5",
6
6
  "grunt-contrib-clean": "^0.6.0",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Kravets
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-05 00:00:00.000000000 Z
11
+ date: 2015-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bourbon