extjs_scaffold 0.1.1 → 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.
data/README.md CHANGED
@@ -1,16 +1,23 @@
1
1
  # ExtjsScaffold
2
2
 
3
- Rails 3.1 Scaffold generator for Extjs 4
3
+ Rails 3.2 Scaffold generator for Extjs 4.1
4
4
 
5
5
  ## Usage
6
6
 
7
7
  ### Install
8
+ 1) Add pagination gem to Gemfile
9
+
10
+ gem "kaminari"
11
+
12
+ or
13
+
14
+ gem "will_paginate", "~> 3.0.0"
8
15
 
9
- 1) Install Sencha Extjs 4 into public
16
+ 2) Install Sencha Extjs 4 into public
10
17
 
11
18
  public/extjs
12
19
 
13
- 2) Add Extjs to app/views/layouts/application.html.erb
20
+ 3) Add Extjs to app/views/layouts/application.html.erb
14
21
 
15
22
  <html>
16
23
  <head>
@@ -28,7 +35,7 @@ Rails 3.1 Scaffold generator for Extjs 4
28
35
  </body>
29
36
  </html>
30
37
 
31
- 3) Add Extjs MVC structure app/assets/javascripts/application.js
38
+ 4) Add Extjs MVC structure app/assets/javascripts/application.js
32
39
 
33
40
  //= require_self
34
41
  //= require_tree ./ux
@@ -39,7 +46,7 @@ Rails 3.1 Scaffold generator for Extjs 4
39
46
  //= require_tree ./controller
40
47
  //= require_tree .
41
48
 
42
- 4) Run the install generator
49
+ 5) Run the install generator
43
50
 
44
51
  rails generate extjs_scaffold:install
45
52
 
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["mwinkler"]
9
9
  s.email = ["mhwinkler@gmail.com"]
10
10
  s.homepage = "https://github.com/mojomaze/extjs_scaffold"
11
- s.summary = "Scaffold Generator for Rails 3.1 and Extjs 4"
12
- s.description = "Scaffold Generator for Rails 3.1 and Sencha Extjs 4"
11
+ s.summary = "Scaffold Generator for Rails 3.2 and Extjs 4.1"
12
+ s.description = "Scaffold Generator for Rails 3.2 and Sencha Extjs 4.1"
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -23,5 +23,5 @@ Gem::Specification.new do |s|
23
23
  s.add_development_dependency "cucumber"
24
24
  s.add_development_dependency "cucumber-rails"
25
25
  s.add_development_dependency "aruba", "< 0.4.7"
26
- s.add_runtime_dependency "rails", "~> 3.1.0"
26
+ s.add_runtime_dependency "rails", "~> 3.2.0"
27
27
  end
@@ -13,7 +13,7 @@ Feature: Generate Extjs Install and Scaffold
13
13
  And I append to "Gemfile" with:
14
14
  """
15
15
  gem "haml"
16
- gem "kaminari"
16
+ gem "kaminari", "~> 0.13.0"
17
17
  gem "extjs_renderer", "~> 0.1.0"
18
18
  gem 'extjs_scaffold', :path => '../../../'
19
19
 
@@ -74,6 +74,10 @@ Feature: Generate Extjs Install and Scaffold
74
74
  | app/models/product.rb |
75
75
  | app/views/products/index.html.erb |
76
76
  | test/functional/products_controller_test.rb |
77
+ And I run `rails g scaffold team name:string`
78
+ Then the following files should exist:
79
+ | app/views/products/index.html.erb |
80
+ | test/functional/teams_controller_test.rb |
77
81
  And I append to "Gemfile" with:
78
82
  """
79
83
  gem "rspec", "~> 2.7.0"
@@ -1,3 +1,3 @@
1
1
  module ExtjsScaffold
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -55,10 +55,6 @@ module ExtjsScaffold
55
55
  empty_directory File.join("app/assets/javascripts/ux", "grid")
56
56
  template 'GridPanel.js', File.join('app/assets/javascripts/ux/grid/', 'Panel.js')
57
57
 
58
- #toolbar
59
- empty_directory File.join("app/assets/javascripts/ux", "toolbar")
60
- template 'ScrollingToolbar.js', File.join('app/assets/javascripts/ux/toolbar/', 'Scrolling.js')
61
-
62
58
  #window
63
59
  empty_directory File.join("app/assets/javascripts/ux", "window")
64
60
  template 'EditWindow.js', File.join('app/assets/javascripts/ux/window/', 'EditWindow.js')
@@ -12,11 +12,6 @@ Ext.define('<%= app_name %>.ux.grid.Panel', {
12
12
  */
13
13
  multiSelect: true,
14
14
 
15
- // Use a PagingGridScroller
16
- verticalScrollerType: 'paginggridscroller',
17
- invalidateScrollerOnRefresh: false,
18
- //disableSelection: true,
19
-
20
15
  enableColumnHide: false,
21
16
  enableColumnMove: false,
22
17
  enableColumnResize: false,
@@ -114,17 +109,6 @@ Ext.define('<%= app_name %>.ux.grid.Panel', {
114
109
  items: topitems
115
110
  });
116
111
 
117
- if (!me.hideBottomToolbar) {
118
- toolbars.push({
119
- xtype: 'scrollingtoolbar',
120
- itemId: 'bottomtoolbar',
121
- store: me.store,
122
- dock: 'bottom',
123
- displayInfo: true,
124
- displayReload: me.enableStoreReload
125
- });
126
- }
127
-
128
112
  return toolbars;
129
113
  },
130
114
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @author Adapted from Ext.ux.form.SearchField example
2
+ * @author Ext.ux.form.SearchField example
3
3
  * http://www.sencha.com/
4
4
  * @class App.ux.form.field.SearchField
5
5
  * @extends Ext.form.field.Trigger
@@ -25,80 +25,74 @@
25
25
  */
26
26
  Ext.define('<%= app_name %>.ux.form.field.SearchField', {
27
27
  extend: 'Ext.form.field.Trigger',
28
+
28
29
  alias: 'widget.searchfield',
29
30
 
30
- trigger1Cls: 'x-form-clear-trigger',
31
- trigger2Cls: 'x-form-search-trigger',
31
+ trigger1Cls: Ext.baseCSSPrefix + 'form-clear-trigger',
32
+
33
+ trigger2Cls: Ext.baseCSSPrefix + 'form-search-trigger',
32
34
 
33
- emptyText: '',
34
- width: 180,
35
+ hasSearch : false,
36
+ paramName : 'query',
35
37
 
36
- /**
37
- * @cfg {store} store
38
- * The associated data store to receive query
39
- */
40
- store: '',
38
+ initComponent: function() {
39
+ var me = this;
41
40
 
42
- /**
43
- * @cfg {String} queryParam
44
- * The query param name sent to store
45
- * (defaults to <tt>query</tt>)
46
- */
47
- queryParam: 'query',
41
+ me.callParent(arguments);
42
+ me.on('specialkey', function(f, e){
43
+ if (e.getKey() == e.ENTER) {
44
+ me.onTrigger2Click();
45
+ }
46
+ });
48
47
 
49
- initComponent: function(){
50
- this.callParent(arguments);
51
- this.on('specialkey', this.checkEnterKey, this);
52
- },
48
+ // We're going to use filtering
49
+ me.store.remoteFilter = true;
53
50
 
54
- onRender: function() {
55
- this.callParent(arguments);
56
- this.triggerEl.elements[0].setDisplayed('none');
57
- },
51
+ // Set up the proxy to encode the filter in the simplest way as a name/value pair
58
52
 
59
- // Handle enter key presses, execute the search if the field has a value
60
- checkEnterKey: function(field, e) {
61
- var value = this.getValue();
62
- if (e.getKey() === e.ENTER) {
63
- this.search();
53
+ // If the Store has not been *configured* with a filterParam property, then use our filter parameter name
54
+ if (!me.store.proxy.hasOwnProperty('filterParam')) {
55
+ me.store.proxy.filterParam = me.paramName;
56
+ }
57
+ me.store.proxy.encodeFilters = function(filters) {
58
+ return filters[0].value;
64
59
  }
65
60
  },
66
61
 
67
- onTrigger2Click: function() {
68
- this.search();
69
- },
70
-
71
- onTrigger1Click: function() {
72
- this.clearSearch();
62
+ afterRender: function(){
63
+ this.callParent();
64
+ this.triggerCell.item(0).setDisplayed(false);
73
65
  },
74
66
 
75
- search: function() {
67
+ onTrigger1Click : function(){
76
68
  var me = this;
77
- me.triggerEl.elements[0].setDisplayed('block');
78
- var v = this.getRawValue();
79
- if (v.length < 1){
80
- me.clearSearch();
81
- return;
82
- }
83
- if (me.store) {
84
- var query = {}
85
- query[me.queryParam] = v;
86
- Ext.apply(me.store.proxy.extraParams, query);
87
- me.store.load();
69
+
70
+ if (me.hasSearch) {
71
+ me.setValue('');
72
+ me.store.clearFilter();
73
+ me.hasSearch = false;
74
+ me.triggerCell.item(0).setDisplayed(false);
75
+ me.updateLayout();
88
76
  }
89
- me.doComponentLayout();
90
77
  },
91
78
 
92
- clearSearch: function() {
93
- var me = this;
94
- me.triggerEl.elements[0].setDisplayed('none');
95
- me.setValue('');
96
- if (me.store) {
97
- var query = {}
98
- query[me.queryParam] = '';
99
- Ext.apply(me.store.proxy.extraParams, query);
100
- me.store.load();
79
+ onTrigger2Click : function(){
80
+ var me = this,
81
+ store = me.store,
82
+ proxy = store.getProxy(),
83
+ value = me.getValue();
84
+
85
+ if (value.length > 0) {
86
+ // Param name is ignored here since we use custom encoding in the proxy.
87
+ // id is used by the Store to replace any previous filter
88
+ me.store.filter({
89
+ id: me.paramName,
90
+ property: me.paramName,
91
+ value: value
92
+ });
93
+ me.hasSearch = true;
94
+ me.triggerCell.item(0).setDisplayed(true);
95
+ me.updateLayout();
101
96
  }
102
- me.doComponentLayout();
103
97
  }
104
98
  });
@@ -30,13 +30,14 @@ module ExtjsScaffold
30
30
  template "model.rb", "app/models/#{controller_file_name}_tmp.rb"
31
31
  f = File.open "#{destination_root}/app/models/#{controller_file_name}_tmp.rb", "r"
32
32
  model_methods = f.read
33
- # insert after belongs_to or inject
34
- refs = attributes.select{|attr| attr.reference? }.collect{|a| a.name}
33
+ # make related tables updateable - add to attr_accessible
34
+ refs = reference_attributes.map{|a| ":#{a.name}_id, :#{a.name}_#{reference_field(a)}"}
35
35
  if refs.size > 0
36
- insert_into_file "app/models/#{singular_table_name}.rb", model_methods, :after => "belongs_to :#{refs.last}"
37
- else
38
- inject_into_class "app/models/#{singular_table_name}.rb", singular_table_name.capitalize, model_methods
36
+ refs_attr = refs.sort.join(", ")
37
+ insert_into_file "app/models/#{singular_table_name}.rb", ", "+refs_attr, :after => /attr_accessible.*/
39
38
  end
39
+ # add search with pagination class method
40
+ insert_into_file "app/models/#{singular_table_name}.rb", "\n"+model_methods, :after => /attr_accessible.*/
40
41
  remove_file "app/models/#{controller_file_name}_tmp.rb"
41
42
  end
42
43
  end
@@ -291,6 +292,29 @@ module ExtjsScaffold
291
292
  def updatefield_width(attribute)
292
293
  return %w(boolean date integer).include?(attribute.type.to_s) ? 275 : 575
293
294
  end
295
+
296
+ private
297
+
298
+ def resource_attributes
299
+ key_value singular_table_name, "{ #{attributes_hash} }"
300
+ end
301
+
302
+ def attributes_hash
303
+ return if accessible_attributes.empty?
304
+
305
+ accessible_attributes.map do |a|
306
+ name = a.name
307
+ key_value name, "@#{singular_table_name}.#{name}"
308
+ end.sort.join(', ')
309
+ end
310
+
311
+ def accessible_attributes
312
+ attributes.reject(&:reference?)
313
+ end
314
+
315
+ def reference_attributes
316
+ attributes.select(&:reference?)
317
+ end
294
318
  end
295
319
  end
296
320
  end
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  test "should create <%= singular_table_name %>" do
26
26
  assert_difference('<%= class_name %>.count') do
27
- post :create, <%= singular_table_name %>: @<%= singular_table_name %>.attributes
27
+ post :create, <%= resource_attributes %>
28
28
  end
29
29
 
30
30
  assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
@@ -32,7 +32,7 @@ end
32
32
 
33
33
  test "should create <%= singular_table_name %> via xhr json requests" do
34
34
  assert_difference('<%= class_name %>.count') do
35
- xhr :post, :create, <%= singular_table_name %>: @<%= singular_table_name %>.attributes, :format => :json
35
+ xhr :post, :create, <%= resource_attributes %>, :format => :json
36
36
  end
37
37
 
38
38
  json = ActiveSupport::JSON.decode(@response.body)
@@ -55,7 +55,7 @@ end
55
55
  end
56
56
 
57
57
  test "should update <%= singular_table_name %> via xhr json" do
58
- xhr :put, :update, id: @<%= singular_table_name %>.to_param, <%= singular_table_name %>: @<%= singular_table_name %>.attributes, :format => :json
58
+ xhr :put, :update, id: @<%= singular_table_name %>.to_param, <%= resource_attributes %>, :format => :json
59
59
  json = ActiveSupport::JSON.decode(@response.body)
60
60
  assert json['success']
61
61
  assert_equal json['data']['id'], @<%= singular_table_name %>.id
@@ -84,11 +84,6 @@ describe ExtjsScaffold::Generators::InstallGenerator do
84
84
  contains "Ext.define('#{app_name}.ux.grid.Panel', {"
85
85
  end
86
86
  end
87
- directory "toolbar" do
88
- file "Scrolling.js" do
89
- contains "Ext.define('#{app_name}.ux.toolbar.Scrolling', {"
90
- end
91
- end
92
87
  directory "window" do
93
88
  file "EditWindow.js" do
94
89
  contains "Ext.define('#{app_name}.ux.window.EditWindow', {"
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: extjs_scaffold
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - mwinkler
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-03 00:00:00 Z
13
+ date: 2012-06-27 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sqlite3
@@ -97,10 +97,10 @@ dependencies:
97
97
  requirements:
98
98
  - - ~>
99
99
  - !ruby/object:Gem::Version
100
- version: 3.1.0
100
+ version: 3.2.0
101
101
  type: :runtime
102
102
  version_requirements: *id008
103
- description: Scaffold Generator for Rails 3.1 and Sencha Extjs 4
103
+ description: Scaffold Generator for Rails 3.2 and Sencha Extjs 4.1
104
104
  email:
105
105
  - mhwinkler@gmail.com
106
106
  executables: []
@@ -133,7 +133,6 @@ files:
133
133
  - lib/generators/extjs_scaffold/install/templates/GridPanel.js
134
134
  - lib/generators/extjs_scaffold/install/templates/ParentComboField.js
135
135
  - lib/generators/extjs_scaffold/install/templates/Rails.js
136
- - lib/generators/extjs_scaffold/install/templates/ScrollingToolbar.js
137
136
  - lib/generators/extjs_scaffold/install/templates/SearchField.js
138
137
  - lib/generators/extjs_scaffold/install/templates/UpdateWindow.js
139
138
  - lib/generators/extjs_scaffold/install/templates/Updateable.js
@@ -236,7 +235,7 @@ rubyforge_project:
236
235
  rubygems_version: 1.8.8
237
236
  signing_key:
238
237
  specification_version: 3
239
- summary: Scaffold Generator for Rails 3.1 and Extjs 4
238
+ summary: Scaffold Generator for Rails 3.2 and Extjs 4.1
240
239
  test_files:
241
240
  - features/scaffold_generator.feature
242
241
  - features/step_definitions/aruba_ext_steps.rb
@@ -1,170 +0,0 @@
1
- /**
2
- * @author Mark H Winkler
3
- * @class App.ux.toolbar.Scrolling
4
- * @extends Ext.toolbar.Toolbar
5
- * <p>Extends toolbar.Toolbar</p>
6
- * <p>Stripped down version of Ext.toolbar.Paging that shows total recs from store</p>
7
- */
8
- Ext.define('<%= app_name %>.ux.toolbar.Scrolling', {
9
- extend: 'Ext.toolbar.Toolbar',
10
- alias: 'widget.scrollingtoolbar',
11
- requires: ['Ext.toolbar.TextItem'],
12
- /**
13
- * @cfg {String} displayMsg
14
- * The paging status message to display
15
- */
16
- displayMsg : 'Total: {0}',
17
- /**
18
- * @cfg {String} emptyMsg
19
- * The message to display when no records are found (defaults to 'No data to display')
20
- */
21
- emptyMsg : 'No data to display',
22
- /**
23
- * @cfg {String} refreshText
24
- * The quicktip text displayed for the Refresh button (defaults to <tt>'Refresh'</tt>).
25
- * <b>Note</b>: quick tips must be initialized for the quicktip to show.
26
- */
27
- refreshText : 'Refresh',
28
- /**
29
- * @cfg {boolean} displayReload
30
- * add reload button to toolbar
31
- */
32
- displayReload: false,
33
-
34
- initComponent : function(){
35
- var me = this;
36
- me.items = [];
37
-
38
- if (me.displayReload) {
39
- me.items.push({
40
- tooltip: 'Refresh',
41
- iconCls: 'x-tbar-loading',
42
- scope: me,
43
- handler: me.reload
44
- });
45
- }
46
-
47
- if (me.displayInfo) {
48
- me.items.push('->');
49
- me.items.push({xtype: 'tbtext', itemId: 'displayItem'});
50
- }
51
-
52
- me.callParent();
53
-
54
- me.on('afterlayout', me.onLoad, me, {single: true});
55
-
56
- me.bindStore(me.store || 'ext-empty-store', true);
57
- },
58
-
59
- // private
60
- updateInfo : function(){
61
- var me = this,
62
- displayItem = me.child('#displayItem'),
63
- store = me.store,
64
- totalCount = store.getTotalCount();
65
-
66
- if (displayItem) {
67
- count = store.getCount();
68
- if (count === 0) {
69
- msg = me.emptyMsg;
70
- } else {
71
- msg = Ext.String.format(
72
- me.displayMsg,
73
- totalCount
74
- );
75
- }
76
- displayItem.setText(msg);
77
- me.doComponentLayout();
78
- }
79
- },
80
-
81
- // private
82
- onLoad : function(){
83
- var me = this;
84
-
85
- if (!me.rendered) {
86
- return;
87
- }
88
- me.updateInfo();
89
- },
90
-
91
- // private
92
- onLoadError : function(){
93
- if (!this.rendered) {
94
- return;
95
- }
96
- this.child('#refresh').enable();
97
- },
98
-
99
- /**
100
- * Refresh the current page, has the same effect as clicking the 'refresh' button.
101
- */
102
- // doRefresh : function(){
103
- // var me = this,
104
- // current = me.store.currentPage;
105
- //
106
- // if (me.fireEvent('beforechange', me, current) !== false) {
107
- // me.store.loadPage(current);
108
- // }
109
- // },
110
-
111
- /**
112
- * Binds the paging toolbar to the specified {@link Ext.data.Store}
113
- * @param {Ext.data.Store} store The store to bind to this toolbar
114
- * @param {Boolean} initial (Optional) true to not remove listeners
115
- */
116
- bindStore : function(store, initial){
117
- var me = this;
118
-
119
- if (!initial && me.store) {
120
- if (store !== me.store && me.store.autoDestroy) {
121
- me.store.destroy();
122
- } else {
123
- me.store.un('load', me.onLoad, me);
124
- me.store.un('exception', me.onLoadError, me);
125
- }
126
- if (!store) {
127
- me.store = null;
128
- }
129
- }
130
- if (store) {
131
- store = Ext.data.StoreManager.lookup(store);
132
- store.on({
133
- scope: me,
134
- load: me.onLoad,
135
- exception: me.onLoadError
136
- });
137
- }
138
- me.store = store;
139
- },
140
-
141
- // private
142
- onDestroy : function(){
143
- this.bindStore(null);
144
- this.callParent();
145
- },
146
-
147
- updateTotal: function(total){
148
- var me = this,
149
- displayItem = me.child('#displayItem');
150
-
151
- if (displayItem) {
152
- count = total;
153
- if (count === 0) {
154
- msg = me.emptyMsg;
155
- } else {
156
- msg = Ext.String.format(
157
- me.displayMsg,
158
- count
159
- );
160
- }
161
- displayItem.setText(msg);
162
- me.doComponentLayout();
163
- }
164
- },
165
-
166
- reload: function() {
167
- var me = this;
168
- me.store.load();
169
- }
170
- });