netzke-basepack 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +27 -2
- data/TODO.rdoc +1 -5
- data/app/models/netzke_persistent_array_auto_model.rb +0 -1
- data/features/components_in_view.feature +11 -0
- data/features/form_panel.feature +49 -0
- data/features/grid_panel.feature +32 -1
- data/features/i18n.feature +18 -0
- data/features/nested_attributes.feature +23 -0
- data/features/search_in_grid.feature +9 -9
- data/features/simple_app.feature +10 -0
- data/features/step_definitions/grid_panel_steps.rb +23 -0
- data/features/support/paths.rb +6 -0
- data/features/support/pickle.rb +0 -1
- data/features/virtual_attributes.feature +20 -0
- data/javascripts/basepack.js +166 -243
- data/lib/netzke-basepack.rb +3 -3
- data/lib/netzke/active_record.rb +6 -7
- data/lib/netzke/active_record/attributes.rb +214 -143
- data/lib/netzke/active_record/combobox_options.rb +12 -10
- data/lib/netzke/basepack.rb +6 -3
- data/lib/netzke/basepack/accordion_panel.rb +4 -2
- data/lib/netzke/basepack/auth_app.rb +152 -0
- data/lib/netzke/basepack/basic_app.rb +2 -262
- data/lib/netzke/basepack/form_panel.rb +35 -27
- data/lib/netzke/basepack/form_panel/fields.rb +35 -17
- data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +59 -0
- data/lib/netzke/basepack/form_panel/javascripts/display_mode.js +62 -0
- data/lib/netzke/basepack/form_panel/javascripts/main.js +138 -0
- data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +25 -0
- data/lib/netzke/basepack/form_panel/services.rb +12 -9
- data/lib/netzke/basepack/grid_panel.rb +87 -53
- data/lib/netzke/basepack/grid_panel/columns.rb +60 -15
- data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +2 -64
- data/lib/netzke/basepack/grid_panel/javascripts/edit_in_form.js +2 -2
- data/lib/netzke/basepack/grid_panel/javascripts/{pre.js → main.js} +35 -17
- data/lib/netzke/basepack/grid_panel/javascripts/misc.js +4 -0
- data/lib/netzke/basepack/grid_panel/services.rb +17 -14
- data/lib/netzke/basepack/paging_form_panel.rb +92 -0
- data/lib/netzke/basepack/simple_app.rb +71 -0
- data/lib/netzke/basepack/simple_app/javascripts/main.js +53 -0
- data/lib/netzke/basepack/{basic_app → simple_app/javascripts}/statusbar_ext.js +0 -0
- data/lib/netzke/basepack/tab_panel.rb +2 -12
- data/lib/netzke/basepack/tab_panel/javascripts/main.js +11 -0
- data/lib/netzke/basepack/version.rb +2 -2
- data/lib/netzke/basepack/window.rb +6 -7
- data/lib/netzke/basepack/wrap_lazy_loaded.rb +3 -1
- data/lib/netzke/data_accessor.rb +25 -14
- data/lib/netzke/ext.rb +1 -1
- data/locales/en.yml +22 -0
- data/netzke-basepack.gemspec +66 -12
- data/spec/active_record/attributes_spec.rb +31 -2
- data/spec/factories.rb +16 -1
- data/test/rails_app/Gemfile +2 -2
- data/test/rails_app/Gemfile.lock +76 -77
- data/test/rails_app/app/components/author_grid.rb +7 -0
- data/test/rails_app/app/components/book_form.rb +24 -0
- data/test/rails_app/app/components/book_grid.rb +6 -1
- data/test/rails_app/app/components/book_grid_with_default_values.rb +11 -0
- data/test/rails_app/app/components/book_grid_with_nested_attributes.rb +13 -0
- data/test/rails_app/app/components/book_grid_with_virtual_attributes.rb +22 -0
- data/test/rails_app/app/components/book_paging_form_panel.rb +20 -0
- data/test/rails_app/app/components/book_presentation.rb +18 -0
- data/test/rails_app/app/components/books_bound_to_author.rb +10 -0
- data/test/rails_app/app/components/form_without_model.rb +19 -0
- data/test/rails_app/app/components/lockable_book_form.rb +17 -0
- data/test/rails_app/app/components/lockable_user_form.rb +7 -0
- data/test/rails_app/app/components/simple_window.rb +10 -0
- data/test/rails_app/app/components/some_accordion_panel.rb +22 -0
- data/test/rails_app/app/components/{simple_basic_app.rb → some_auth_app.rb} +3 -3
- data/test/rails_app/app/components/some_border_layout.rb +10 -7
- data/test/rails_app/app/components/some_simple_app.rb +34 -0
- data/test/rails_app/app/components/some_tab_panel.rb +16 -11
- data/test/rails_app/app/components/user_form.rb +11 -4
- data/test/rails_app/app/components/user_grid.rb +7 -1
- data/test/rails_app/app/components/window_component_loader.rb +1 -0
- data/test/rails_app/app/controllers/application_controller.rb +6 -0
- data/test/rails_app/app/controllers/components_controller.rb +3 -3
- data/test/rails_app/app/controllers/welcome_controller.rb +2 -2
- data/test/rails_app/app/helpers/embedded_components_helper.rb +2 -0
- data/test/rails_app/app/models/address.rb +3 -0
- data/test/rails_app/app/models/author.rb +2 -0
- data/test/rails_app/app/models/book.rb +1 -0
- data/test/rails_app/app/models/user.rb +1 -2
- data/test/rails_app/app/views/components/simple_panel.html.erb +1 -0
- data/test/rails_app/app/views/layouts/nested.html.erb +5 -0
- data/test/rails_app/config/application.rb +1 -1
- data/test/rails_app/config/initializers/netzke.rb +0 -4
- data/test/rails_app/config/locales/es.yml +16 -0
- data/test/rails_app/config/routes.rb +4 -1
- data/test/rails_app/db/development_structure.sql +33 -4
- data/test/rails_app/db/migrate/20101026190021_create_books.rb +2 -0
- data/test/rails_app/db/migrate/20110101143818_create_addresses.rb +17 -0
- data/test/rails_app/db/schema.rb +33 -1
- data/test/rails_app/spec/controllers/embedded_components_controller_spec.rb +12 -0
- data/test/rails_app/spec/helpers/embedded_components_helper_spec.rb +15 -0
- data/test/rails_app/spec/models/address_spec.rb +5 -0
- data/test/rails_app/spec/views/embedded_components/index.html.erb_spec.rb +5 -0
- metadata +67 -13
- data/features/basic_app.feature +0 -12
- data/lib/netzke/active_record/association_attributes.rb +0 -102
- data/lib/netzke/basepack/form_panel/javascripts/pre.js +0 -76
- data/lib/netzke/basepack/form_panel/javascripts/xcheckbox.js +0 -82
- data/lib/netzke/basepack/grid_panel/javascript.rb +0 -69
- data/locale/en.yml +0 -16
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
= v0.6.3 - 2011-01-14
|
2
|
+
* compatibility with netzke-core 0.6.5
|
3
|
+
|
4
|
+
* refactoring
|
5
|
+
* GridPanel code restructured, using the new +js_mixin+ method
|
6
|
+
|
7
|
+
* bug fix
|
8
|
+
* GridPanel respects strong_default_attrs
|
9
|
+
* TabPanel doesn't fire multiple load requests per tab in case of lazy-loaded tabs and fast clicking
|
10
|
+
* Filtering/sorting on virtual columns is now disabled by default
|
11
|
+
* Filtering on date columns
|
12
|
+
|
13
|
+
* enhancements
|
14
|
+
* I18n for Grid/FormPanel
|
15
|
+
* new +getter+ config option for columns/fields, a lambda receiving the record as parameter
|
16
|
+
* new +setter+ config option for columns/fields, a lambda receiving the record as first parameter, new value as the second
|
17
|
+
* GridPanel passes columns' default values to the "Add in form" form
|
18
|
+
* FormPanel can now be used without specifying a model
|
19
|
+
* New +commalistcbg+ form field for checkboxes, where boxLabels of selected checkboxes are serialized into comma-separated string (the separator is configurable)
|
20
|
+
* New +nradiogroup+ form field for radio buttons, where the value is defined by the boxLabel of the selected radio button
|
21
|
+
* New +no_binding+ option for configuring a form field. Set it to "true" when you don't want Netzke to expand the field configuration based on the +name+ property. May be needed in some cases, e.g. when using checkboxes/radio buttons in the form.
|
22
|
+
* New +nested_attribute+ option for configuring data attributes (thus applicable for a column, a field, or a +netzke_attribute+ in the model). When set to true for an association attribute (e.g. author__name), assigning a value to it will change the association's attribute, *not* trying to find an association by name and reassign it if found (default behavior).
|
23
|
+
* FormPanel shows the "Updating..." mask while sending values to the server (configurable with updateMask option/property)
|
24
|
+
* FormPanel now can be used in the "lockable" mode (:config => :lockable), which makes it load initially in "display mode", then "unlock" it, change the values, and "lock" it again (updating the values on the server)
|
25
|
+
|
1
26
|
= v0.6.2 - 2010-11-05
|
2
27
|
* compatibility with netzke-core 0.6.4
|
3
28
|
* bug fix
|
@@ -7,7 +32,7 @@
|
|
7
32
|
* enhancements
|
8
33
|
* BorderLayoutPanel persistence: remembers region sizes and collapsed/expanded states
|
9
34
|
* tooltips for grid buttons
|
10
|
-
|
35
|
+
|
11
36
|
* bug fix
|
12
37
|
* auto-detection of association's method when the latter is virtual was broken in 1.9.2
|
13
38
|
|
@@ -321,4 +346,4 @@
|
|
321
346
|
* Meta work: replacing underscore with dash in the name
|
322
347
|
|
323
348
|
= v0.1.0 - 2008-12-20
|
324
|
-
* Initial release
|
349
|
+
* Initial release
|
data/TODO.rdoc
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
== Priority
|
2
|
-
*
|
3
|
-
* On grid refresh, reset the dirty fields, so that the "Apply" button doesn't do anything
|
2
|
+
* Make GridPanel show the mask straight after pressing "Apply"
|
4
3
|
* DataAccessor#to_array should not rescue exceptions, but rather check the availability of the attributes; `respond_to_with_basepack?` should be extended to also return true for association columns
|
5
4
|
* GridPanel's read_only vs editable (doesn't work now) options
|
6
5
|
* Find a way to print the grid nicely (along with the column and rows that don't fit on the screen)
|
@@ -10,6 +9,3 @@
|
|
10
9
|
|
11
10
|
== Optimizations
|
12
11
|
* Check persistent_config-related queries (aren't they too many?)
|
13
|
-
|
14
|
-
== One day
|
15
|
-
* Replace xcheckbox with checkbox in FormPanel
|
@@ -41,7 +41,6 @@ class NetzkePersistentArrayAutoModel < ActiveRecord::Base
|
|
41
41
|
# only select those attributes that were provided to us as columns. The rest is ignored.
|
42
42
|
column_names = config[:columns].map{ |c| c[:name] }
|
43
43
|
clean_data = data.collect{ |c| c.reject{ |k,v| !column_names.include?(k.to_s) } }
|
44
|
-
Rails.logger.debug "!!! clean_data: #{clean_data.inspect}\n"
|
45
44
|
self.delete_all
|
46
45
|
self.create(clean_data)
|
47
46
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Components in view
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: Components configured in the view should render properly
|
8
|
+
When I go to the "simple panel" view
|
9
|
+
Then I should see "Simple Panel content"
|
10
|
+
When I press "Update html"
|
11
|
+
Then I should see "HTML received from server"
|
data/features/form_panel.feature
CHANGED
@@ -38,3 +38,52 @@ Scenario: UserFormWithDefaultFields should render properly
|
|
38
38
|
And I should see "Castaneda"
|
39
39
|
And I should see "writer"
|
40
40
|
|
41
|
+
@javascript
|
42
|
+
Scenario: FormPanel should be functional without model provided
|
43
|
+
Given I am on the FormWithoutModel test page
|
44
|
+
When I fill in "Text field:" with "Some text"
|
45
|
+
And I fill in "Number field:" with "42"
|
46
|
+
And I check "Boolean field:"
|
47
|
+
And I press "Apply"
|
48
|
+
|
49
|
+
Then I should see "Text field: Some text"
|
50
|
+
And I should see "Number field: 42"
|
51
|
+
And I should see "Boolean field: true"
|
52
|
+
|
53
|
+
@javascript
|
54
|
+
Scenario: Checkbox field should work properly
|
55
|
+
Given an author exists with first_name: "Carlos"
|
56
|
+
And a book exists with author: that author, digitized: false, exemplars: 2, title: "Some Title"
|
57
|
+
When I go to the BookForm test page
|
58
|
+
And I fill in "Exemplars:" with "4"
|
59
|
+
And I check "Digitized:"
|
60
|
+
And I press "Apply"
|
61
|
+
Then I should see "YES"
|
62
|
+
And a book should exist with digitized: true, author: that author, exemplars: 4
|
63
|
+
And a book should not exist with digitized: false, author: that author
|
64
|
+
|
65
|
+
@javascript
|
66
|
+
Scenario: Checkbox group for tags should work properly
|
67
|
+
Given a book exists with title: "Some Title"
|
68
|
+
When I go to the BookForm test page
|
69
|
+
And I check "recommend"
|
70
|
+
And I check "cool"
|
71
|
+
And I press "Apply"
|
72
|
+
Then the "cool" checkbox should be checked
|
73
|
+
And the "recommend" checkbox should be checked
|
74
|
+
But the "read" checkbox should not be checked
|
75
|
+
And a book should exist with tags: "cool,recommend"
|
76
|
+
|
77
|
+
# Needs cleaner check whether AJAX request was completed
|
78
|
+
# @javascript
|
79
|
+
# Scenario: Validations
|
80
|
+
# Given a book exists with title: "Some Title"
|
81
|
+
# When I go to the BookForm test page
|
82
|
+
# And I fill in "Title:" with ""
|
83
|
+
# And I press "Apply"
|
84
|
+
# And I sleep 1 second
|
85
|
+
# Then I should see "Title can't be blank"
|
86
|
+
# When I fill in "Title:" with ""
|
87
|
+
# And I press "Apply"
|
88
|
+
# And I sleep 1 second
|
89
|
+
# Then I should not see "Title can't be blank"
|
data/features/grid_panel.feature
CHANGED
@@ -57,7 +57,8 @@ Scenario: Multi-editing records
|
|
57
57
|
And I press "Edit in form"
|
58
58
|
And I fill in "First name:" with "Maxim"
|
59
59
|
And I press "OK"
|
60
|
-
Then
|
60
|
+
Then I should see "Updated 2 records."
|
61
|
+
And the following users should exist:
|
61
62
|
| first_name | last_name |
|
62
63
|
| Maxim | Castaneda |
|
63
64
|
| Maxim | Hesse |
|
@@ -71,4 +72,34 @@ Scenario: Filling out association column with association's virtual method
|
|
71
72
|
Then I should see "Nabokov, Vladimir"
|
72
73
|
And I should see "Lolita"
|
73
74
|
|
75
|
+
@javascript
|
76
|
+
Scenario: Grid with strong_default_attrs
|
77
|
+
Given an author exists with first_name: "Vladimir", last_name: "Nabokov"
|
78
|
+
And a book exists with title: "Lolita", author: that author
|
79
|
+
And a book exists with title: "Unknown"
|
80
|
+
When I go to the BooksBoundToAuthor test page
|
81
|
+
And I press "Add in form"
|
82
|
+
And I fill in "Title:" with "The Luzhin Defence"
|
83
|
+
And I press "OK"
|
84
|
+
And I should see "The Luzhin Defence"
|
85
|
+
And I should see "Lolita"
|
86
|
+
But I should not see "Unknown"
|
74
87
|
|
88
|
+
@javascript
|
89
|
+
Scenario: Grid with columns with default values
|
90
|
+
Given I am on the BookGridWithDefaultValues test page
|
91
|
+
When I press "Add in form"
|
92
|
+
And I press "OK"
|
93
|
+
And I sleep 1 second
|
94
|
+
Then a book should exist with title: "Lolita", exemplars: 100
|
95
|
+
|
96
|
+
@javascript
|
97
|
+
Scenario: Inline editing
|
98
|
+
Given a book exists with title: "Magus", exemplars: 100
|
99
|
+
When I go to the BookGrid test page
|
100
|
+
And I edit row 1 of the grid with title: "Collector", exemplars: 200
|
101
|
+
And I press "Apply"
|
102
|
+
And I sleep 1 second
|
103
|
+
Then the grid should have 0 modified records
|
104
|
+
And a book should exist with title: "Collector", exemplars: 200
|
105
|
+
But a book should not exist with title: "Magus"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: I18n
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
Scenario: A grid with localized column headers
|
7
|
+
When I go to the "es" version of the BookGrid page
|
8
|
+
Then I should see "Autor"
|
9
|
+
And I should see "Creado en"
|
10
|
+
But I should not see "Author"
|
11
|
+
And I should not see "Created at"
|
12
|
+
|
13
|
+
Scenario: A form with localized field labels
|
14
|
+
When I go to the "es" version of the BookForm page
|
15
|
+
Then I should see "Autor"
|
16
|
+
And I should see "En abundancia"
|
17
|
+
But I should not see "Author"
|
18
|
+
And I should not see "In abundance"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Nested attributes
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: Grid with nested attributes
|
8
|
+
Given an author exists with first_name: "Vlad", last_name: "Nabokoff"
|
9
|
+
And a book exists with title: "Lola", author: that author
|
10
|
+
When I go to the BookGridWithNestedAttributes test page
|
11
|
+
And I select first row in the grid
|
12
|
+
And I press "Edit in form"
|
13
|
+
And I fill in "Author first name:" with "Vladimir"
|
14
|
+
And I fill in "Author last name:" with "Nabokov"
|
15
|
+
And I fill in "Title:" with "Lolita"
|
16
|
+
And I press "OK"
|
17
|
+
|
18
|
+
Then I should see "Nabokov"
|
19
|
+
Then an author should exist with first_name: "Vladimir", last_name: "Nabokov"
|
20
|
+
And a book should exist with title: "Lolita", author: that author
|
21
|
+
|
22
|
+
But an author should not exist with first_name: "Vlad"
|
23
|
+
And a book should not exist with title: "Lola"
|
@@ -6,17 +6,17 @@ Feature: Search
|
|
6
6
|
@javascript
|
7
7
|
Scenario: Search via Search window
|
8
8
|
Given the following roles exist:
|
9
|
-
|
|
10
|
-
| admin
|
11
|
-
| superadmin |
|
12
|
-
| user
|
9
|
+
| id | name |
|
10
|
+
| 1 | admin |
|
11
|
+
| 2 | superadmin |
|
12
|
+
| 3 | user |
|
13
13
|
|
14
14
|
And the following users exist:
|
15
|
-
| first_name | last_name |
|
16
|
-
| Paul
|
17
|
-
| Dalai
|
18
|
-
| Taisha
|
19
|
-
| Florinda
|
15
|
+
| first_name | last_name | role_id |
|
16
|
+
| Paul | Bley | 1 |
|
17
|
+
| Dalai | Lama | 3 |
|
18
|
+
| Taisha | Abelar | 2 |
|
19
|
+
| Florinda | Donner | 1 |
|
20
20
|
|
21
21
|
When I go to the UserGrid test page
|
22
22
|
Then the grid should show 4 records
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Basic application
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: SimpleApp should load its components dynamically
|
8
|
+
Given I am on the SomeSimpleApp test page
|
9
|
+
When I press "Simple accordion"
|
10
|
+
Then I should see "Some simple app simple accordion"
|
@@ -24,3 +24,26 @@ Then /^the grid should show (\d+) records$/ do |arg1|
|
|
24
24
|
return grid.getStore().getCount();
|
25
25
|
JS
|
26
26
|
end
|
27
|
+
|
28
|
+
When /^I edit row (\d+) of the grid with #{capture_fields}$/ do |rowIndex, fields|
|
29
|
+
fields = ActiveSupport::JSON.decode("{#{fields}}")
|
30
|
+
js_set_fields = fields.each_pair.map do |k,v|
|
31
|
+
"r.set('#{k}', '#{v}');"
|
32
|
+
end.join
|
33
|
+
page.driver.browser.execute_script <<-JS
|
34
|
+
var components = [];
|
35
|
+
for (var cmp in Netzke.page) { components.push(cmp); }
|
36
|
+
var grid = Netzke.page[components[0]];
|
37
|
+
var r = grid.getStore().getAt(#{rowIndex.to_i-1});
|
38
|
+
#{js_set_fields}
|
39
|
+
JS
|
40
|
+
end
|
41
|
+
|
42
|
+
Then /^the grid should have (\d+) modified records$/ do |n|
|
43
|
+
page.driver.browser.execute_script(<<-JS).should == n.to_i
|
44
|
+
var components = [];
|
45
|
+
for (var cmp in Netzke.page) { components.push(cmp); }
|
46
|
+
var grid = Netzke.page[components[0]];
|
47
|
+
return grid.getStore().getModifiedRecords().length;
|
48
|
+
JS
|
49
|
+
end
|
data/features/support/paths.rb
CHANGED
@@ -40,9 +40,15 @@ module NavigationHelpers
|
|
40
40
|
when /the component loader page/
|
41
41
|
'/panel/component_loader'
|
42
42
|
|
43
|
+
when /the "(.*)" view/
|
44
|
+
embedded_components_path(:action => $1.gsub(" ", "_"))
|
45
|
+
|
43
46
|
when /the (.*) test page/
|
44
47
|
components_path(:component => $1)
|
45
48
|
|
49
|
+
when /the "(.+)" version of the (.*) page/
|
50
|
+
components_path(:component => $2, :locale => $1)
|
51
|
+
|
46
52
|
else
|
47
53
|
begin
|
48
54
|
page_name =~ /the (.*) page/
|
data/features/support/pickle.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Window component loader
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: Columns and fields with custom setter/getter methods should work as expected
|
8
|
+
Given an author exists with first_name: "Victor"
|
9
|
+
And a book exists with title: "Lolita", exemplars: "5", author: that author
|
10
|
+
And I am on the BookGridWithVirtualAttributes test page
|
11
|
+
Then I should see "Victor"
|
12
|
+
And I should see "YES"
|
13
|
+
|
14
|
+
When I select first row in the grid
|
15
|
+
And I press "Edit in form"
|
16
|
+
And I fill in "Author first name" with "Vladimir"
|
17
|
+
And I fill in "Exemplars" with "3"
|
18
|
+
And I press "OK"
|
19
|
+
Then I should see "Vladimir"
|
20
|
+
And I should see "NO"
|
data/javascripts/basepack.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
Ext.ns("Netzke.pre");
|
2
|
+
Ext.ns("Netzke.pre.Basepack");
|
2
3
|
Ext.ns("Ext.ux.grid");
|
3
4
|
|
4
5
|
Ext.apply(Ext.History, new Ext.util.Observable());
|
@@ -38,12 +39,12 @@ Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
|
|
38
39
|
});
|
39
40
|
|
40
41
|
var parent = Ext.getCmp(this.parentId);
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
// Is parent a grid?
|
43
|
+
if (parent.getSelectionModel) {
|
44
|
+
this.on('beforequery',function(qe) {
|
45
|
+
delete qe.combo.lastQuery;
|
46
|
+
},this);
|
47
|
+
}
|
47
48
|
|
48
49
|
// A not-so-clean approach to submit the current record id
|
49
50
|
store.on('beforeload',function(store, options){
|
@@ -53,7 +54,7 @@ Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
|
|
53
54
|
} else {
|
54
55
|
// TODO: also for the FormPanel
|
55
56
|
}
|
56
|
-
},this)
|
57
|
+
}, this);
|
57
58
|
}
|
58
59
|
});
|
59
60
|
|
@@ -63,65 +64,6 @@ Ext.util.Format.mask = function(v){
|
|
63
64
|
return "********";
|
64
65
|
};
|
65
66
|
|
66
|
-
// Implementation of totalProperty, successProperty and root configuration options for ArrayReader
|
67
|
-
Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
|
68
|
-
readRecords : function(o){
|
69
|
-
var sid = this.meta ? this.meta.id : null;
|
70
|
-
var recordType = this.recordType, fields = recordType.prototype.fields;
|
71
|
-
var records = [];
|
72
|
-
var root = o[this.meta.root] || o, totalRecords = o[this.meta.totalProperty], success = o[this.meta.successProperty];
|
73
|
-
for(var i = 0; i < root.length; i++){
|
74
|
-
var n = root[i];
|
75
|
-
var values = {};
|
76
|
-
var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
|
77
|
-
for(var j = 0, jlen = fields.length; j < jlen; j++){
|
78
|
-
var f = fields.items[j];
|
79
|
-
var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
|
80
|
-
var v = n[k] !== undefined ? n[k] : f.defaultValue;
|
81
|
-
v = f.convert(v, n);
|
82
|
-
values[f.name] = v;
|
83
|
-
}
|
84
|
-
var record = new recordType(values, id);
|
85
|
-
record.json = n;
|
86
|
-
records[records.length] = record;
|
87
|
-
}
|
88
|
-
return {
|
89
|
-
records : records,
|
90
|
-
totalRecords : totalRecords,
|
91
|
-
success : success
|
92
|
-
};
|
93
|
-
}
|
94
|
-
});
|
95
|
-
|
96
|
-
|
97
|
-
Ext.data.RecordArrayReader = Ext.extend(Ext.data.JsonReader, {
|
98
|
-
/**
|
99
|
-
* Create a data block containing Ext.data.Records from an Array.
|
100
|
-
* @param {Object} o An Array of row objects which represents the dataset.
|
101
|
-
* @return {Object} data A data block which is used by an Ext.data.Store object as
|
102
|
-
* a cache of Ext.data.Records.
|
103
|
-
*/
|
104
|
-
readRecord : function(o){
|
105
|
-
var sid = this.meta ? this.meta.id : null;
|
106
|
-
var recordType = this.recordType, fields = recordType.prototype.fields;
|
107
|
-
var records = [];
|
108
|
-
var root = o;
|
109
|
-
var n = root;
|
110
|
-
var values = {};
|
111
|
-
var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
|
112
|
-
for(var j = 0, jlen = fields.length; j < jlen; j++){
|
113
|
-
var f = fields.items[j];
|
114
|
-
var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
|
115
|
-
var v = n[k] !== undefined ? n[k] : f.defaultValue;
|
116
|
-
v = f.convert(v, n);
|
117
|
-
values[f.name] = v;
|
118
|
-
}
|
119
|
-
var record = new recordType(values, id);
|
120
|
-
record.json = n;
|
121
|
-
return record;
|
122
|
-
}
|
123
|
-
});
|
124
|
-
|
125
67
|
Ext.netzke.JsonField = Ext.extend(Ext.form.TextField, {
|
126
68
|
validator: function(value) {
|
127
69
|
try{
|
@@ -794,185 +736,166 @@ Ext.grid.HeaderDropZone.prototype.onNodeDrop = function(n, dd, e, data){
|
|
794
736
|
return false;
|
795
737
|
};
|
796
738
|
|
797
|
-
|
798
|
-
Ext.
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
739
|
+
Ext.ns('Ext.ux.form');
|
740
|
+
Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.Checkbox, {
|
741
|
+
checked: null,
|
742
|
+
valueList: [null, false, true],
|
743
|
+
stateClassList: ['x-checkbox-undef', null, 'x-checkbox-checked'],
|
744
|
+
overClass: 'x-form-check-over',
|
745
|
+
clickClass: 'x-form-check-down',
|
746
|
+
triState: true,
|
747
|
+
defaultAutoCreate: {tag: 'input', type: 'hidden', autocomplete: 'off'},
|
748
|
+
initComponent: function() {
|
749
|
+
this.value = this.checked;
|
750
|
+
Ext.ux.form.TriCheckbox.superclass.initComponent.apply(this, arguments);
|
751
|
+
// make a copy before modifying valueList and stateClassList arrays
|
752
|
+
this.vList = this.valueList.slice(0);
|
753
|
+
this.cList = this.stateClassList.slice(0);
|
754
|
+
if(this.triState !== true) {
|
755
|
+
// consider 'undefined' value and its class go first in arrays
|
756
|
+
this.vList.shift();
|
757
|
+
this.cList.shift();
|
758
|
+
}
|
759
|
+
if(this.overCls !== undefined) {
|
760
|
+
this.overClass = this.overCls;
|
761
|
+
delete this.overCls;
|
762
|
+
}
|
763
|
+
this.value = this.normalizeValue(this.value);
|
764
|
+
},
|
765
|
+
onRender : function(ct, position){
|
766
|
+
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
|
767
|
+
|
768
|
+
this.innerWrap = this.el.wrap({tag: 'span', cls: 'x-form-check-innerwrap'});
|
769
|
+
this.wrap = this.innerWrap.wrap({cls: 'x-form-check-wrap'});
|
770
|
+
|
771
|
+
this.currCls = this.getCls(this.value);
|
772
|
+
this.wrap.addClass(this.currCls);
|
773
|
+
if(this.clickClass && !this.disabled && !this.readOnly)
|
774
|
+
this.innerWrap.addClassOnClick(this.clickClass);
|
775
|
+
if(this.overClass && !this.disabled && !this.readOnly)
|
776
|
+
this.innerWrap.addClassOnOver(this.overClass);
|
777
|
+
|
778
|
+
this.imageEl = this.innerWrap.createChild({
|
779
|
+
tag: 'img',
|
780
|
+
src: Ext.BLANK_IMAGE_URL,
|
781
|
+
cls: 'x-form-tscheckbox'
|
782
|
+
}, this.el);
|
783
|
+
if(this.fieldClass) this.imageEl.addClass(this.fieldClass);
|
784
|
+
|
785
|
+
if(this.boxLabel){
|
786
|
+
this.innerWrap.createChild({
|
787
|
+
tag: 'label',
|
788
|
+
htmlFor: this.el.id,
|
789
|
+
cls: 'x-form-cb-label',
|
790
|
+
html: this.boxLabel
|
791
|
+
});
|
792
|
+
}
|
815
793
|
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
794
|
+
// Need to repaint for IE, otherwise positioning is broken
|
795
|
+
if(Ext.isIE){
|
796
|
+
this.wrap.repaint();
|
797
|
+
}
|
798
|
+
this.resizeEl = this.positionEl = this.wrap;
|
799
|
+
},
|
800
|
+
onResize : function(){
|
801
|
+
Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
|
802
|
+
if(!this.boxLabel && !this.fieldLabel && this.imageEl){
|
803
|
+
this.imageEl.alignTo(this.wrap, 'c-c');
|
804
|
+
}
|
805
|
+
},
|
806
|
+
initEvents : function(){
|
807
|
+
Ext.form.Checkbox.superclass.initEvents.call(this);
|
808
|
+
this.mon(this.innerWrap, {
|
809
|
+
scope: this,
|
810
|
+
click: this.onClick
|
811
|
+
});
|
812
|
+
},
|
813
|
+
onClick : function(){
|
814
|
+
if (!this.disabled && !this.readOnly) {
|
815
|
+
this.setValue(this.vList[(this.vList.indexOf(this.value) + 1) % this.vList.length]);
|
816
|
+
}
|
817
|
+
},
|
818
|
+
getValue : function(){
|
819
|
+
return this.value;
|
820
|
+
},
|
821
|
+
setValue : function(v){
|
822
|
+
var value = this.value;
|
823
|
+
this.value = this.normalizeValue(v);
|
824
|
+
if(this.rendered) this.el.dom.value = this.value;
|
825
|
+
|
826
|
+
if(value !== this.value){
|
827
|
+
this.updateView();
|
828
|
+
this.fireEvent('check', this, this.value);
|
829
|
+
if(this.handler) this.handler.call(this.scope || this, this, this.value);
|
830
|
+
}
|
831
|
+
return this;
|
832
|
+
},
|
833
|
+
normalizeValue: function(v) {
|
834
|
+
return (v === null || v === undefined) && this.triState ? null :
|
835
|
+
(v === true || (['true', 'yes', 'on', '1']).indexOf(String(v).toLowerCase()) != -1);
|
836
|
+
},
|
837
|
+
getCls: function(v) {
|
838
|
+
var idx = this.vList.indexOf(this.value);
|
839
|
+
return idx > -1 ? this.cList[idx] : undefined;
|
840
|
+
},
|
841
|
+
updateView: function() {
|
842
|
+
var cls = this.getCls(this.value);
|
843
|
+
if (!this.wrap || cls === undefined) return;
|
844
|
+
|
845
|
+
this.wrap.replaceClass(this.currCls, cls);
|
846
|
+
this.currCls = cls;
|
847
|
+
}
|
848
|
+
});
|
849
|
+
Ext.reg('tricheckbox', Ext.ux.form.TriCheckbox);
|
839
850
|
|
840
|
-
// At this point, the Toolbars must be layed out for getFrameHeight to find a result.
|
841
|
-
if(Ext.isNumber(h)){
|
842
|
-
h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));
|
843
|
-
this.body.setHeight(h);
|
844
|
-
}else if(h == 'auto'){
|
845
|
-
this.body.setHeight(h);
|
846
|
-
}
|
847
851
|
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
852
|
+
// Enabling checkbox submission when unchecked
|
853
|
+
(function() {
|
854
|
+
origCheckboxRender = Ext.form.Checkbox.prototype.onRender;
|
855
|
+
origCheckboxSetValue = Ext.form.Checkbox.prototype.setValue;
|
856
|
+
|
857
|
+
Ext.override(Ext.form.Checkbox, {
|
858
|
+
onRender: function() {
|
859
|
+
// call the original onRender() function
|
860
|
+
origCheckboxRender.apply(this, arguments);
|
861
|
+
|
862
|
+
if (this.getXType() === 'radio') return;
|
863
|
+
|
864
|
+
// Handle initial case based on this.checked
|
865
|
+
if (this.checked == false) {
|
866
|
+
this.noValEl = Ext.DomHelper.insertAfter(this.el, {
|
867
|
+
tag: 'input',
|
868
|
+
type: 'hidden',
|
869
|
+
value: false,
|
870
|
+
name: this.getName()
|
871
|
+
}, true);
|
872
|
+
}
|
873
|
+
else {
|
874
|
+
this.noValEl = null;
|
875
|
+
}
|
876
|
+
},
|
877
|
+
setValue: function() {
|
878
|
+
// call original setValue() function
|
879
|
+
origCheckboxSetValue.apply(this, arguments);
|
880
|
+
|
881
|
+
if (this.getXType() === 'radio') return;
|
882
|
+
|
883
|
+
if (this.checked) {
|
884
|
+
if (this.noValEl != null) {
|
885
|
+
// Remove the extra hidden element
|
886
|
+
this.noValEl.remove();
|
887
|
+
this.noValEl = null;
|
862
888
|
}
|
863
|
-
|
864
|
-
|
889
|
+
}
|
890
|
+
else {
|
891
|
+
// Add our hidden element for (unchecked) value
|
892
|
+
if (this.noValEl == null) this.noValEl = Ext.DomHelper.insertAfter(this.el, {
|
893
|
+
tag: 'input',
|
894
|
+
type: 'hidden',
|
895
|
+
value: false,
|
896
|
+
name: this.getName()
|
897
|
+
}, true);
|
898
|
+
}
|
865
899
|
}
|
866
|
-
});
|
867
|
-
|
868
|
-
Ext.ns('Ext.ux.form');
|
869
|
-
Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.Checkbox, {
|
870
|
-
checked: null,
|
871
|
-
valueList: [null, false, true],
|
872
|
-
stateClassList: ['x-checkbox-undef', null, 'x-checkbox-checked'],
|
873
|
-
overClass: 'x-form-check-over',
|
874
|
-
clickClass: 'x-form-check-down',
|
875
|
-
triState: true,
|
876
|
-
defaultAutoCreate: {tag: 'input', type: 'hidden', autocomplete: 'off'},
|
877
|
-
initComponent: function() {
|
878
|
-
this.value = this.checked;
|
879
|
-
Ext.ux.form.TriCheckbox.superclass.initComponent.apply(this, arguments);
|
880
|
-
// make a copy before modifying valueList and stateClassList arrays
|
881
|
-
this.vList = this.valueList.slice(0);
|
882
|
-
this.cList = this.stateClassList.slice(0);
|
883
|
-
if(this.triState !== true) {
|
884
|
-
// consider 'undefined' value and its class go first in arrays
|
885
|
-
this.vList.shift();
|
886
|
-
this.cList.shift();
|
887
|
-
}
|
888
|
-
if(this.overCls !== undefined) {
|
889
|
-
this.overClass = this.overCls;
|
890
|
-
delete this.overCls;
|
891
|
-
}
|
892
|
-
this.value = this.normalizeValue(this.value);
|
893
|
-
},
|
894
|
-
onRender : function(ct, position){
|
895
|
-
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
|
896
|
-
|
897
|
-
this.innerWrap = this.el.wrap({tag: 'span', cls: 'x-form-check-innerwrap'});
|
898
|
-
this.wrap = this.innerWrap.wrap({cls: 'x-form-check-wrap'});
|
899
|
-
|
900
|
-
this.currCls = this.getCls(this.value);
|
901
|
-
this.wrap.addClass(this.currCls);
|
902
|
-
if(this.clickClass && !this.disabled && !this.readOnly)
|
903
|
-
this.innerWrap.addClassOnClick(this.clickClass);
|
904
|
-
if(this.overClass && !this.disabled && !this.readOnly)
|
905
|
-
this.innerWrap.addClassOnOver(this.overClass);
|
906
|
-
|
907
|
-
this.imageEl = this.innerWrap.createChild({
|
908
|
-
tag: 'img',
|
909
|
-
src: Ext.BLANK_IMAGE_URL,
|
910
|
-
cls: 'x-form-tscheckbox'
|
911
|
-
}, this.el);
|
912
|
-
if(this.fieldClass) this.imageEl.addClass(this.fieldClass);
|
913
|
-
|
914
|
-
if(this.boxLabel){
|
915
|
-
this.innerWrap.createChild({
|
916
|
-
tag: 'label',
|
917
|
-
htmlFor: this.el.id,
|
918
|
-
cls: 'x-form-cb-label',
|
919
|
-
html: this.boxLabel
|
920
|
-
});
|
921
|
-
}
|
922
|
-
|
923
|
-
// Need to repaint for IE, otherwise positioning is broken
|
924
|
-
if(Ext.isIE){
|
925
|
-
this.wrap.repaint();
|
926
|
-
}
|
927
|
-
this.resizeEl = this.positionEl = this.wrap;
|
928
|
-
},
|
929
|
-
onResize : function(){
|
930
|
-
Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
|
931
|
-
if(!this.boxLabel && !this.fieldLabel && this.imageEl){
|
932
|
-
this.imageEl.alignTo(this.wrap, 'c-c');
|
933
|
-
}
|
934
|
-
},
|
935
|
-
initEvents : function(){
|
936
|
-
Ext.form.Checkbox.superclass.initEvents.call(this);
|
937
|
-
this.mon(this.innerWrap, {
|
938
|
-
scope: this,
|
939
|
-
click: this.onClick
|
940
|
-
});
|
941
|
-
},
|
942
|
-
onClick : function(){
|
943
|
-
if (!this.disabled && !this.readOnly) {
|
944
|
-
this.setValue(this.vList[(this.vList.indexOf(this.value) + 1) % this.vList.length]);
|
945
|
-
}
|
946
|
-
},
|
947
|
-
getValue : function(){
|
948
|
-
return this.value;
|
949
|
-
},
|
950
|
-
setValue : function(v){
|
951
|
-
var value = this.value;
|
952
|
-
this.value = this.normalizeValue(v);
|
953
|
-
if(this.rendered) this.el.dom.value = this.value;
|
954
|
-
|
955
|
-
if(value !== this.value){
|
956
|
-
this.updateView();
|
957
|
-
this.fireEvent('check', this, this.value);
|
958
|
-
if(this.handler) this.handler.call(this.scope || this, this, this.value);
|
959
|
-
}
|
960
|
-
return this;
|
961
|
-
},
|
962
|
-
normalizeValue: function(v) {
|
963
|
-
return (v === null || v === undefined) && this.triState ? null :
|
964
|
-
(v === true || (['true', 'yes', 'on', '1']).indexOf(String(v).toLowerCase()) != -1);
|
965
|
-
},
|
966
|
-
getCls: function(v) {
|
967
|
-
var idx = this.vList.indexOf(this.value);
|
968
|
-
return idx > -1 ? this.cList[idx] : undefined;
|
969
|
-
},
|
970
|
-
updateView: function() {
|
971
|
-
var cls = this.getCls(this.value);
|
972
|
-
if (!this.wrap || cls === undefined) return;
|
973
|
-
|
974
|
-
this.wrap.replaceClass(this.currCls, cls);
|
975
|
-
this.currCls = cls;
|
976
|
-
}
|
977
|
-
});
|
978
|
-
Ext.reg('tricheckbox', Ext.ux.form.TriCheckbox);
|
900
|
+
});
|
901
|
+
})();
|