netzke-basepack 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -4
- data/README.md +63 -0
- data/Rakefile +4 -4
- data/javascripts/basepack.js +113 -133
- data/lib/netzke-basepack.rb +9 -2
- data/lib/netzke/basepack.rb +9 -6
- data/lib/netzke/basepack/accordion_panel.rb +1 -1
- data/lib/netzke/basepack/auth_app.rb +28 -21
- data/lib/netzke/basepack/border_layout_panel.rb +9 -57
- data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +40 -0
- data/lib/netzke/basepack/data_accessor.rb +3 -5
- data/lib/netzke/basepack/form_panel.rb +55 -52
- data/lib/netzke/basepack/form_panel/fields.rb +4 -2
- data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +13 -28
- data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +61 -34
- data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +4 -3
- data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +10 -10
- data/lib/netzke/basepack/form_panel/services.rb +1 -1
- data/lib/netzke/basepack/grid_panel.rb +23 -17
- data/lib/netzke/basepack/grid_panel/columns.rb +116 -71
- data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +5 -7
- data/lib/netzke/basepack/grid_panel/javascripts/check_column_fix.js +6 -0
- data/lib/netzke/basepack/grid_panel/javascripts/edit_in_form.js +18 -15
- data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +178 -0
- data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +230 -454
- data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +1 -0
- data/lib/netzke/basepack/grid_panel/record_form_window.rb +8 -8
- data/lib/netzke/basepack/grid_panel/services.rb +12 -15
- data/lib/netzke/basepack/paging_form_panel.rb +1 -82
- data/lib/netzke/basepack/paging_form_panel/javascripts/paging_form_panel.js +76 -0
- data/lib/netzke/basepack/query_builder.rb +4 -4
- data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +7 -4
- data/lib/netzke/basepack/search_panel.rb +1 -1
- data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +27 -20
- data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +4 -4
- data/lib/netzke/basepack/search_window.rb +4 -4
- data/lib/netzke/basepack/simple_app.rb +36 -8
- data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +27 -16
- data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +1 -1
- data/lib/netzke/basepack/version.rb +2 -2
- data/lib/netzke/basepack/window.rb +2 -45
- data/lib/netzke/basepack/window/javascripts/window.js +18 -0
- data/lib/netzke/basepack/wrap_lazy_loaded.rb +1 -1
- data/locales/de.yml +79 -0
- data/locales/en.yml +0 -10
- data/netzke-basepack.gemspec +32 -19
- data/stylesheets/basepack.css +16 -16
- data/test/rails_app/.gitignore +1 -0
- data/test/rails_app/Gemfile +9 -5
- data/test/rails_app/Gemfile.lock +51 -49
- data/test/rails_app/app/components/author_form.rb +32 -0
- data/test/rails_app/app/components/book_form.rb +6 -4
- data/test/rails_app/app/components/book_grid.rb +4 -3
- data/test/rails_app/app/components/book_grid_loader.rb +2 -2
- data/test/rails_app/app/components/book_grid_with_custom_columns.rb +11 -5
- data/test/rails_app/app/components/book_grid_with_default_values.rb +1 -1
- data/test/rails_app/app/components/book_grid_with_extra_feedback.rb +11 -0
- data/test/rails_app/app/components/book_grid_with_extra_filters.rb +14 -0
- data/test/rails_app/app/components/book_grid_with_paging.rb +10 -0
- data/test/rails_app/app/components/book_grid_with_persistence.rb +6 -0
- data/test/rails_app/app/components/book_paging_form_panel.rb +3 -3
- data/test/rails_app/app/components/book_with_custom_primary_key_grid.rb +10 -0
- data/test/rails_app/app/components/form_without_model.rb +5 -4
- data/test/rails_app/app/components/paging_form_with_search.rb +3 -2
- data/test/rails_app/app/components/some_auth_app.rb +3 -3
- data/test/rails_app/app/components/some_border_layout.rb +2 -2
- data/test/rails_app/app/components/some_simple_app.rb +6 -5
- data/test/rails_app/app/components/window_component_loader.rb +11 -2
- data/test/rails_app/app/controllers/components_controller.rb +1 -1
- data/test/rails_app/app/models/book_with_custom_primary_key.rb +4 -0
- data/test/rails_app/config/initializers/netzke.rb +6 -0
- data/test/rails_app/config/locales/es.yml +0 -10
- data/test/rails_app/db/migrate/20110701070052_create_book_with_custom_primary_keys.rb +15 -0
- data/test/rails_app/db/schema.rb +12 -2
- data/test/rails_app/db/seeds.rb +21 -1
- data/test/rails_app/features/form_panel.feature +17 -17
- data/test/rails_app/features/grid_panel.feature +20 -4
- data/test/rails_app/features/grid_panel_with_custom_primary_key.feature +15 -0
- data/test/rails_app/features/paging_form_panel.feature +14 -0
- data/test/rails_app/features/search_in_grid.feature +2 -1
- data/test/rails_app/features/simple_app.feature +5 -0
- data/test/rails_app/features/step_definitions/accordion_steps.rb +1 -5
- data/test/rails_app/features/step_definitions/ext_steps.rb +16 -0
- data/test/rails_app/features/step_definitions/form_panel_steps.rb +10 -12
- data/test/rails_app/features/step_definitions/generic_steps.rb +12 -4
- data/test/rails_app/features/step_definitions/grid_panel_steps.rb +47 -32
- data/test/rails_app/features/tab_panel.feature +2 -2
- data/test/rails_app/spec/factories.rb +4 -0
- metadata +26 -13
- data/README.rdoc +0 -67
- data/from_05_to_06.rdoc +0 -2
- data/javascripts/feedback_ghost.js +0 -34
- data/test/rails_app/public/netzke/basepack/ts-checkbox.gif +0 -0
@@ -3,12 +3,9 @@
|
|
3
3
|
if (this.searchWindow) {
|
4
4
|
this.searchWindow.show();
|
5
5
|
} else {
|
6
|
-
this.
|
6
|
+
this.loadNetzkeComponent({name: 'search_form', callback: function(win){
|
7
7
|
this.searchWindow = win;
|
8
|
-
|
9
|
-
if (currentConditionsString) {
|
10
|
-
win.items.first().getForm().setValues(Ext.decode(currentConditionsString));
|
11
|
-
}
|
8
|
+
win.show();
|
12
9
|
|
13
10
|
win.items.first().on('apply', function(){
|
14
11
|
win.onSearch();
|
@@ -18,8 +15,9 @@
|
|
18
15
|
win.on('hide', function(){
|
19
16
|
var query = win.getQuery();
|
20
17
|
if (win.closeRes == 'search'){
|
21
|
-
this.getStore()
|
22
|
-
|
18
|
+
var store = this.getStore(), proxy = store.getProxy();
|
19
|
+
proxy.extraParams.query = Ext.encode(query);
|
20
|
+
store.load();
|
23
21
|
}
|
24
22
|
el.toggle(query.length > 0); // toggle based on the state
|
25
23
|
}, this);
|
@@ -2,15 +2,16 @@
|
|
2
2
|
onEditInForm: function(){
|
3
3
|
var selModel = this.getSelectionModel();
|
4
4
|
if (selModel.getCount() > 1) {
|
5
|
-
var recordId = selModel.
|
6
|
-
this.
|
5
|
+
var recordId = selModel.selected.first().getId();
|
6
|
+
this.loadNetzkeComponent({name: "multi_edit_form",
|
7
7
|
params: {record_id: recordId},
|
8
8
|
callback: function(w){
|
9
|
+
w.show();
|
9
10
|
var form = w.items.first();
|
10
11
|
form.on('apply', function(){
|
11
12
|
var ids = [];
|
12
|
-
selModel.each(function(r){
|
13
|
-
ids.push(r.
|
13
|
+
selModel.selected.each(function(r){
|
14
|
+
ids.push(r.getId());
|
14
15
|
});
|
15
16
|
if (!form.baseParams) form.baseParams = {};
|
16
17
|
form.baseParams.ids = Ext.encode(ids);
|
@@ -18,18 +19,19 @@
|
|
18
19
|
|
19
20
|
w.on('close', function(){
|
20
21
|
if (w.closeRes === "ok") {
|
21
|
-
this.store.
|
22
|
+
this.store.load();
|
22
23
|
}
|
23
24
|
}, this);
|
24
25
|
}, scope: this});
|
25
26
|
} else {
|
26
|
-
var recordId = selModel.
|
27
|
-
this.
|
27
|
+
var recordId = selModel.selected.first().getId();
|
28
|
+
this.loadNetzkeComponent({name: "edit_form",
|
28
29
|
params: {record_id: recordId},
|
29
|
-
callback: function(
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
callback: function(w){
|
31
|
+
w.show();
|
32
|
+
w.on('close', function(){
|
33
|
+
if (w.closeRes === "ok") {
|
34
|
+
this.store.load();
|
33
35
|
}
|
34
36
|
}, this);
|
35
37
|
}, scope: this});
|
@@ -37,10 +39,11 @@
|
|
37
39
|
},
|
38
40
|
|
39
41
|
onAddInForm: function(){
|
40
|
-
this.
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
this.loadNetzkeComponent({name: "add_form", callback: function(w){
|
43
|
+
w.show();
|
44
|
+
w.on('close', function(){
|
45
|
+
if (w.closeRes === "ok") {
|
46
|
+
this.store.load();
|
44
47
|
}
|
45
48
|
}, this);
|
46
49
|
}, scope: this});
|
@@ -0,0 +1,178 @@
|
|
1
|
+
{
|
2
|
+
// Handler for the 'add' button
|
3
|
+
onAddInline: function(){
|
4
|
+
// Note: default values are taken from the model's field's defaultValue property
|
5
|
+
var r = Ext.ModelManager.create({}, this.id);
|
6
|
+
|
7
|
+
r.isNew = true; // to distinguish new records
|
8
|
+
|
9
|
+
this.getStore().add(r);
|
10
|
+
|
11
|
+
this.tryStartEditing(r);
|
12
|
+
},
|
13
|
+
|
14
|
+
onDel: function() {
|
15
|
+
Ext.Msg.confirm(this.i18n.confirmation, this.i18n.areYouSure, function(btn){
|
16
|
+
if (btn == 'yes') {
|
17
|
+
var records = [];
|
18
|
+
var selection = this.getView().getSelectedNodes();
|
19
|
+
this.getSelectionModel().selected.each(function(r){
|
20
|
+
if (r.isNew) {
|
21
|
+
// this record is not know to server - simply remove from store
|
22
|
+
this.store.remove(r);
|
23
|
+
} else {
|
24
|
+
records.push(r.getId());
|
25
|
+
}
|
26
|
+
}, this);
|
27
|
+
|
28
|
+
if (records.length > 0){
|
29
|
+
if (!this.deleteMask) this.deleteMask = new Ext.LoadMask(this.getEl(), {msg: this.deleteMaskMsg});
|
30
|
+
this.deleteMask.show();
|
31
|
+
// call API
|
32
|
+
this.deleteData({records: Ext.encode(records)}, function(){
|
33
|
+
this.deleteMask.hide();
|
34
|
+
}, this);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}, this);
|
38
|
+
},
|
39
|
+
|
40
|
+
onApply: function(){
|
41
|
+
var newRecords = [],
|
42
|
+
updatedRecords = [],
|
43
|
+
store = this.getStore();
|
44
|
+
|
45
|
+
Ext.each(store.getUpdatedRecords().concat(store.getNewRecords()),
|
46
|
+
function(r) {
|
47
|
+
if (r.isNew) {
|
48
|
+
newRecords.push(r.data); // HACK: r.data seems private
|
49
|
+
} else {
|
50
|
+
updatedRecords.push(Ext.apply(r.getChanges(), {id:r.getId()}));
|
51
|
+
}
|
52
|
+
},
|
53
|
+
this);
|
54
|
+
|
55
|
+
if (newRecords.length > 0 || updatedRecords.length > 0) {
|
56
|
+
var params = {};
|
57
|
+
|
58
|
+
if (newRecords.length > 0) {
|
59
|
+
params.created_records = Ext.encode(newRecords);
|
60
|
+
}
|
61
|
+
|
62
|
+
if (updatedRecords.length > 0) {
|
63
|
+
params.updated_records = Ext.encode(updatedRecords);
|
64
|
+
}
|
65
|
+
|
66
|
+
if (this.getStore().getProxy().extraParams !== {}) {
|
67
|
+
params.base_params = Ext.encode(this.getStore().getProxy().extraParams);
|
68
|
+
}
|
69
|
+
|
70
|
+
this.postData(params);
|
71
|
+
}
|
72
|
+
|
73
|
+
},
|
74
|
+
|
75
|
+
// Handlers for tools
|
76
|
+
//
|
77
|
+
|
78
|
+
onRefresh: function() {
|
79
|
+
if (this.fireEvent('refresh', this) !== false) {
|
80
|
+
this.store.load();
|
81
|
+
}
|
82
|
+
},
|
83
|
+
|
84
|
+
// Event handlers
|
85
|
+
//
|
86
|
+
|
87
|
+
onColumnResize: function(ct, cl, width){
|
88
|
+
var index = ct.items.findIndex('id', cl.id);
|
89
|
+
|
90
|
+
this.resizeColumn({
|
91
|
+
index: index,
|
92
|
+
size: width
|
93
|
+
});
|
94
|
+
},
|
95
|
+
|
96
|
+
onColumnHide: function(ct, cl){
|
97
|
+
var index = ct.items.findIndex('id', cl.id);
|
98
|
+
|
99
|
+
this.hideColumn({
|
100
|
+
index:index,
|
101
|
+
hidden:true
|
102
|
+
});
|
103
|
+
},
|
104
|
+
|
105
|
+
onColumnShow: function(ct, cl){
|
106
|
+
var index = ct.items.findIndex('id', cl.id);
|
107
|
+
|
108
|
+
this.hideColumn({
|
109
|
+
index:index,
|
110
|
+
hidden:false
|
111
|
+
});
|
112
|
+
},
|
113
|
+
|
114
|
+
onColumnMove: function(ct, cl, oldIndex, newIndex){
|
115
|
+
this.moveColumn({
|
116
|
+
old_index: oldIndex,
|
117
|
+
new_index: newIndex
|
118
|
+
});
|
119
|
+
},
|
120
|
+
|
121
|
+
onItemContextMenu: function(grid, record, item, rowIndex, e){
|
122
|
+
e.stopEvent();
|
123
|
+
var coords = e.getXY();
|
124
|
+
|
125
|
+
if (!grid.getSelectionModel().isSelected(rowIndex)) {
|
126
|
+
grid.getSelectionModel().selectRow(rowIndex);
|
127
|
+
}
|
128
|
+
|
129
|
+
var menu = new Ext.menu.Menu({
|
130
|
+
items: this.contextMenu
|
131
|
+
});
|
132
|
+
|
133
|
+
menu.showAt(coords);
|
134
|
+
},
|
135
|
+
|
136
|
+
onAfterRowMove: function(dt, oldIndex, newIndex, records){
|
137
|
+
var ids = [];
|
138
|
+
// collect records ids
|
139
|
+
Ext.each(records, function(r){ids.push(r.id)});
|
140
|
+
// call GridPanel's API
|
141
|
+
this.moveRows({ids: Ext.encode(ids), new_index: newIndex});
|
142
|
+
},
|
143
|
+
|
144
|
+
// Other methods. TODO: revise
|
145
|
+
//
|
146
|
+
|
147
|
+
/* Exception handler. TODO: will responses with status 200 land here? */
|
148
|
+
loadExceptionHandler: function(proxy, response, operation){
|
149
|
+
this.netzkeFeedback(response.message);
|
150
|
+
// if (response.status == 200 && (responseObject = Ext.decode(response.responseText)) && responseObject.flash){
|
151
|
+
// this.feedback(responseObject.flash);
|
152
|
+
// } else {
|
153
|
+
// if (error){
|
154
|
+
// this.feedback(error.message);
|
155
|
+
// } else {
|
156
|
+
// this.feedback(response.statusText);
|
157
|
+
// }
|
158
|
+
// }
|
159
|
+
},
|
160
|
+
|
161
|
+
// Inline editing of 1 row
|
162
|
+
onEdit: function(){
|
163
|
+
var row = this.getSelectionModel().selected.first();
|
164
|
+
if (row){
|
165
|
+
this.tryStartEditing(row);
|
166
|
+
}
|
167
|
+
},
|
168
|
+
|
169
|
+
// Not a very clean approach to clean-up. The problem is that this way the advanced search functionality stops being really pluggable. With Ext JS 4 find the way to make it truely so.
|
170
|
+
onDestroy: function(){
|
171
|
+
Netzke.classes.Basepack.GridPanel.superclass.onDestroy.call(this);
|
172
|
+
|
173
|
+
// Destroy the search window (here's the problem: we are not supposed to know it exists)
|
174
|
+
if (this.searchWindow) {
|
175
|
+
this.searchWindow.destroy();
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
@@ -5,116 +5,89 @@
|
|
5
5
|
|
6
6
|
componentLoadMask: {msg: "Loading..."},
|
7
7
|
deleteMaskMsg: "Deleting...",
|
8
|
+
multiSelect: true,
|
8
9
|
|
9
10
|
initComponent: function(){
|
10
|
-
this.plugins = []; // checkbox colums is a special case, being a plugin
|
11
|
-
|
12
|
-
var filters = [];
|
13
11
|
var metaColumn;
|
12
|
+
var fields = []; // field configs for the underlying data model
|
13
|
+
|
14
|
+
this.plugins = this.plugins || [];
|
15
|
+
this.features = this.features || [];
|
16
|
+
|
17
|
+
// Enable filters feature
|
18
|
+
this.features.push({
|
19
|
+
encode: true,
|
20
|
+
ftype: 'filters'
|
21
|
+
});
|
14
22
|
|
15
23
|
// Run through columns and set up different configuration for each
|
16
24
|
Ext.each(this.columns, function(c, i){
|
17
|
-
// We will not use meta columns as actual columns (not even hidden) - only to create the records
|
18
|
-
if (c.meta) {
|
19
|
-
metaColumn = c;
|
20
|
-
return;
|
21
|
-
}
|
22
25
|
|
23
|
-
//
|
24
|
-
|
26
|
+
// Build the field configuration for this column
|
27
|
+
var fieldConfig = {name: c.name, defaultValue: c.defaultValue};
|
25
28
|
|
26
|
-
//
|
27
|
-
c.dataIndex = c.name;
|
29
|
+
if (c.name !== '_meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
+
if (c.attrType == 'datetime') {
|
32
|
+
fieldConfig.dateFormat = 'Y-m-d g:i:s'; // in this format we receive dates from the server
|
33
|
+
};
|
31
34
|
|
32
|
-
|
33
|
-
if (this.inlineData) {
|
34
|
-
this.associationValues = this.inlineData.setAssociationValues;
|
35
|
-
}
|
35
|
+
fields.push(fieldConfig);
|
36
36
|
|
37
|
-
//
|
38
|
-
|
37
|
+
// We will not use meta columns as actual columns (not even hidden) - only to create the records
|
38
|
+
if (c.meta) {
|
39
|
+
metaColumn = c;
|
40
|
+
return;
|
41
|
+
}
|
39
42
|
|
40
43
|
// if comboboxOptions are provided, we render a combobox instead of textfield
|
41
|
-
if (c.comboboxOptions && c.editor.xtype === "textfield") {
|
42
|
-
|
44
|
+
// if (c.comboboxOptions && c.editor.xtype === "textfield") {
|
45
|
+
// c.editor = {xtype: "combobox", options: c.comboboxOptions.split('\\n')}
|
46
|
+
// }
|
47
|
+
|
48
|
+
this.normalizeRenderer(c);
|
49
|
+
|
50
|
+
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
51
|
+
if (c.assoc) {
|
52
|
+
// Editor for association column
|
53
|
+
c.editor = Ext.apply({
|
54
|
+
parentId: this.id,
|
55
|
+
name: c.name,
|
56
|
+
selectOnFocus: true // ?
|
57
|
+
}, c.editor);
|
58
|
+
|
59
|
+
// Renderer for association column
|
60
|
+
this.normalizeAssociationRenderer(c);
|
43
61
|
}
|
44
62
|
|
45
|
-
|
46
|
-
|
47
|
-
filters.push({type: this.filterTypeForAttrType(c.attrType), dataIndex: c.name});
|
63
|
+
if (c.editor) {
|
64
|
+
Ext.applyIf(c.editor, {selectOnFocus: true});
|
48
65
|
}
|
49
66
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
this.columns[i] = plugin;
|
55
|
-
} else {
|
56
|
-
// a "normal" column, not a plugin
|
57
|
-
if (!c.readOnly && !this.prohibitUpdate) {
|
58
|
-
// c.editor contains complete config of the editor
|
59
|
-
c.editor = Ext.apply({
|
60
|
-
parentId: this.id,
|
61
|
-
name: c.name,
|
62
|
-
selectOnFocus: true
|
63
|
-
}, c.editor);
|
64
|
-
} else {
|
65
|
-
c.editor = null;
|
66
|
-
}
|
67
|
-
|
68
|
-
this.normalizeRenderer(c);
|
69
|
-
|
70
|
-
this.setDefaultColumnType(c);
|
71
|
-
|
72
|
-
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
73
|
-
if (c.assoc) {
|
74
|
-
c.scope = this;
|
75
|
-
var passedRenderer = c.renderer; // renderer we got from normalizeRenderer
|
76
|
-
c.renderer = function(value, a, r, ri, ci){
|
77
|
-
var editor = this.getColumnModel().getColumnAt(ci).getEditor();
|
78
|
-
var recordFromStore = editor && editor.getStore && editor.getStore().getById(value);
|
79
|
-
var renderedValue;
|
80
|
-
if (recordFromStore) {
|
81
|
-
renderedValue = recordFromStore.get('field2');
|
82
|
-
} else if (c.assoc && r.get('_meta')) {
|
83
|
-
renderedValue = r.get('_meta').associationValues[c.name] || value;
|
84
|
-
} else {
|
85
|
-
renderedValue = value;
|
86
|
-
}
|
67
|
+
// Setting the default filter type
|
68
|
+
if (c.filterable && !c.filter) {
|
69
|
+
c.filter = {type: this.fieldTypeForAttrType(c.attrType)};
|
70
|
+
}
|
87
71
|
|
88
|
-
|
89
|
-
|
90
|
-
}
|
72
|
+
// setting dataIndex
|
73
|
+
c.dataIndex = c.name;
|
91
74
|
|
92
|
-
|
75
|
+
// HACK: somehow this is not set by Ext (while it should be)
|
76
|
+
if (c.xtype == 'datecolumn') c.format = c.format || Ext.util.Format.dateFormat;
|
93
77
|
|
94
78
|
}, this);
|
95
79
|
|
96
|
-
/* ... and done with columns */
|
80
|
+
/* ... and done with the columns */
|
97
81
|
|
98
|
-
//
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
// Create Ext.data.Record constructor specific for our particular column configuration
|
105
|
-
this.recordConfig = [];
|
106
|
-
Ext.each(this.columns, function(column){
|
107
|
-
var extraConfig = {};
|
108
|
-
if (column.attrType == 'datetime') {
|
109
|
-
extraConfig.type = 'date';
|
110
|
-
extraConfig.dateFormat = 'Y-m-d g:i:s';
|
111
|
-
};
|
112
|
-
this.recordConfig.push(Ext.apply({name: column.name, defaultValue: column.defaultValue}, extraConfig));
|
113
|
-
}, this);
|
114
|
-
this.Row = Ext.data.Record.create(this.recordConfig);
|
82
|
+
// Define the model
|
83
|
+
Ext.define(this.id, {
|
84
|
+
extend: 'Ext.data.Model',
|
85
|
+
idProperty: this.pri, // Primary key
|
86
|
+
fields: fields
|
87
|
+
});
|
115
88
|
|
116
89
|
// After we created the record (model), we can get rid of the meta column
|
117
|
-
|
90
|
+
Ext.Array.remove(this.columns, metaColumn);
|
118
91
|
|
119
92
|
// Prepare column model config with columns in the correct order; columns out of order go to the end.
|
120
93
|
var colModelConfig = [];
|
@@ -125,7 +98,6 @@
|
|
125
98
|
Ext.each(this.columns, function(oc) {
|
126
99
|
if (c.name === oc.name) {
|
127
100
|
mainColConfig = Ext.apply({}, oc);
|
128
|
-
// oc.inOrder = true;
|
129
101
|
return false;
|
130
102
|
}
|
131
103
|
});
|
@@ -136,100 +108,98 @@
|
|
136
108
|
// We don't need original columns any longer
|
137
109
|
delete this.columns;
|
138
110
|
|
139
|
-
// ... instead
|
140
|
-
this.
|
111
|
+
// ... instead, define own column model
|
112
|
+
this.columns = colModelConfig;
|
113
|
+
|
114
|
+
// DirectProxy that uses our Ext.direct provider
|
115
|
+
var proxy = {
|
116
|
+
type: 'direct',
|
117
|
+
directFn: Netzke.providers[this.id].getData,
|
118
|
+
reader: {
|
119
|
+
type: 'array',
|
120
|
+
root: 'data'
|
121
|
+
},
|
122
|
+
listeners: {
|
123
|
+
exception: {
|
124
|
+
fn: this.loadExceptionHandler,
|
125
|
+
scope: this
|
126
|
+
},
|
127
|
+
load: { // Netzke-introduced event; this will also be fired when an exception occurs.
|
128
|
+
fn: function(proxy, response, operation) {
|
129
|
+
// besides getting data into the store, we may also get commands to execute
|
130
|
+
response = response.result;
|
131
|
+
if (response) { // or did we have an exception?
|
132
|
+
Ext.each(['data', 'total', 'success'], function(property){delete response[property];});
|
133
|
+
this.bulkExecute(response);
|
134
|
+
}
|
135
|
+
},
|
136
|
+
scope: this
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
this.store = Ext.create('store.store', {
|
142
|
+
model: this.id,
|
143
|
+
proxy: proxy,
|
144
|
+
data: this.inlineData && [this.inlineData.data] || [], // TODO: Inline data *might* contain commands to execute
|
145
|
+
pruneModifiedRecords: true,
|
146
|
+
remoteSort: true,
|
147
|
+
pageSize: this.rowsPerPage
|
148
|
+
});
|
149
|
+
|
150
|
+
// HACK: we must let the store now totalCount, but this property is not public (yet?)
|
151
|
+
this.store.totalCount = this.inlineData && this.inlineData[this.store.getProxy().getReader().totalProperty];
|
141
152
|
|
142
153
|
// Drag'n'Drop
|
143
154
|
if (this.enableRowsReordering){
|
144
155
|
this.ddPlugin = new Ext.ux.dd.GridDragDropRowOrder({
|
145
|
-
|
156
|
+
scrollable: true // enable scrolling support (default is false)
|
146
157
|
});
|
147
158
|
this.plugins.push(this.ddPlugin);
|
148
159
|
}
|
149
160
|
|
150
|
-
//
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
// besides getting data into the store, we may also get commands to execute
|
155
|
-
var response = t.result;
|
156
|
-
|
157
|
-
// delete data-related properties
|
158
|
-
Ext.each(['data', 'total', 'success'], function(property){delete response[property];});
|
159
|
-
this.bulkExecute(response);
|
160
|
-
}, this);
|
161
|
-
|
162
|
-
// Data store
|
163
|
-
this.store = this.buildStore();
|
164
|
-
|
165
|
-
// Normalize bottom bar
|
166
|
-
this.bbar = (this.enablePagination) ? new Ext.PagingToolbar(Ext.copyTo({
|
167
|
-
pageSize : this.rowsPerPage,
|
168
|
-
items : this.bbar ? ["-"].concat(this.bbar) : [],
|
169
|
-
store : this.store,
|
170
|
-
emptyMsg: this.i18n.empty,
|
171
|
-
displayInfo: true,
|
172
|
-
plugins: this.gridFilters ? [this.gridFilters] : []
|
173
|
-
}, this.i18n, 'emptyMsg,firstText,prevText,nextText,lastText,beforePageText,afterPageText,refreshText,displayMsg')) : this.bbar;
|
161
|
+
// Cell editing
|
162
|
+
if (!this.prohibitUpdate) {
|
163
|
+
this.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {pluginId: 'celleditor'}));
|
164
|
+
}
|
174
165
|
|
175
|
-
//
|
176
|
-
|
166
|
+
// Paging toolbar
|
167
|
+
this.dockedItems = this.dockedItems || [];
|
168
|
+
this.dockedItems.push({
|
169
|
+
xtype: 'pagingtoolbar',
|
170
|
+
dock: 'bottom',
|
171
|
+
store: this.store,
|
172
|
+
items: ["-"].concat(this.bbar) // append the old bbar. TODO: get rid of it.
|
173
|
+
});
|
177
174
|
|
178
|
-
|
175
|
+
delete this.bbar;
|
179
176
|
|
180
177
|
// Now let Ext.grid.EditorGridPanel do the rest (original initComponent)
|
181
|
-
|
182
|
-
|
183
|
-
// Persistence-related events
|
184
|
-
if (this.persistence) {
|
185
|
-
// Hidden change event
|
186
|
-
this.getColumnModel().on('hiddenchange', this.onColumnHiddenChange, this);
|
187
|
-
|
188
|
-
// Inform the server part about column operations
|
189
|
-
this.on('columnresize', this.onColumnResize, this);
|
190
|
-
this.on('columnmove', this.onColumnMove, this);
|
191
|
-
}
|
178
|
+
this.callParent();
|
192
179
|
|
193
180
|
// Context menu
|
194
181
|
if (this.contextMenu) {
|
195
|
-
this.on('
|
182
|
+
this.on('itemcontextmenu', this.onItemContextMenu, this);
|
196
183
|
}
|
197
184
|
|
198
185
|
// Disabling/enabling editInForm button according to current selection
|
199
|
-
if (this.enableEditInForm) {
|
200
|
-
this.getSelectionModel().on('selectionchange', function(selModel){
|
186
|
+
if (this.enableEditInForm && !this.prohibitUpdate) {
|
187
|
+
this.getSelectionModel().on('selectionchange', function(selModel, selected){
|
201
188
|
var disabled;
|
202
|
-
if (
|
189
|
+
if (selected.length === 0) { // empty?
|
203
190
|
disabled = true;
|
204
191
|
} else {
|
205
192
|
// Disable "edit in form" button if new record is present in selection
|
206
|
-
|
207
|
-
if (r.isNew) { return false; }
|
193
|
+
Ext.each(selected, function(r){
|
194
|
+
if (r.isNew) { disabled = true; return false; }
|
208
195
|
});
|
209
196
|
};
|
210
197
|
this.actions.editInForm.setDisabled(disabled);
|
211
198
|
}, this);
|
212
199
|
}
|
213
200
|
|
214
|
-
//
|
215
|
-
if (this.loadInlineData) {
|
216
|
-
this.getStore().loadData(this.inlineData);
|
217
|
-
|
218
|
-
// If rows per page specified, fake store.lastOptions as if the data was loaded
|
219
|
-
// by PagingToolbar (for correct functionning of refresh tool and extended search)
|
220
|
-
if (this.rowsPerPage) {
|
221
|
-
this.getStore().lastOptions = {params:{limit:this.rowsPerPage, start:0}}; // this is how PagingToolbar does it...
|
222
|
-
}
|
223
|
-
|
224
|
-
// inlineData may also contain commands (TODO: make it DRY, as this code repeats in multiple places...)
|
225
|
-
// delete data-related properties
|
226
|
-
Ext.each(['data', 'total', 'success'], function(property){ delete this.inlineData[property]; }, this);
|
227
|
-
this.bulkExecute(this.inlineData);
|
228
|
-
}
|
229
|
-
|
230
|
-
// Process selectionchange event
|
201
|
+
// Process selectionchange event to enable/disable actions
|
231
202
|
this.getSelectionModel().on('selectionchange', function(selModel){
|
232
|
-
// enable/disable actions
|
233
203
|
if (this.actions.del) this.actions.del.setDisabled(!selModel.hasSelection() || this.prohibitDelete);
|
234
204
|
if (this.actions.edit) this.actions.edit.setDisabled(selModel.getCount() != 1 || this.prohibitUpdate);
|
235
205
|
}, this);
|
@@ -239,246 +209,79 @@
|
|
239
209
|
this.ddPlugin.on('afterrowmove', this.onAfterRowMove, this);
|
240
210
|
}
|
241
211
|
|
242
|
-
// GridView
|
212
|
+
// WIP: GridView
|
243
213
|
this.getView().getRowClass = this.defaultGetRowClass;
|
244
214
|
|
245
215
|
// When starting editing as assocition column, pre-load the combobox store from the meta column, so that we don't see the real value of this cell (the id of the associated record), but rather the associated record by the configured method.
|
246
216
|
this.on('beforeedit', function(e){
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
217
|
+
if (e.column.assoc && e.record.get('_meta')) {
|
218
|
+
var data = [e.record.get(e.field), e.record.get('_meta').associationValues[e.field]],
|
219
|
+
store = e.column.getEditor().store;
|
220
|
+
if (store.getCount() === 0) {
|
221
|
+
store.loadData([data]);
|
222
|
+
}
|
252
223
|
}
|
253
224
|
}, this);
|
254
|
-
},
|
255
|
-
|
256
|
-
buildStore: function() {
|
257
|
-
return new Ext.data.Store({
|
258
|
-
pruneModifiedRecords: true,
|
259
|
-
proxy: this.proxy,
|
260
|
-
reader: new Ext.data.ArrayReader({root: "data", totalProperty: "total", successProperty: "success", id:0}, this.Row),
|
261
|
-
remoteSort: true,
|
262
|
-
listeners:{'loadexception':{
|
263
|
-
fn:this.loadExceptionHandler,
|
264
|
-
scope:this
|
265
|
-
}}
|
266
|
-
});
|
267
|
-
},
|
268
225
|
|
269
|
-
|
270
|
-
|
226
|
+
this.on('afterrender', function() {
|
227
|
+
// Persistence-related events (afterrender to avoid blank event firing on render)
|
228
|
+
if (this.persistence) {
|
229
|
+
// Inform the server part about column operations
|
230
|
+
this.on('columnresize', this.onColumnResize, this);
|
231
|
+
this.on('columnmove', this.onColumnMove, this);
|
232
|
+
this.on('columnhide', this.onColumnHide, this);
|
233
|
+
this.on('columnshow', this.onColumnShow, this);
|
234
|
+
}
|
235
|
+
}, this);
|
271
236
|
},
|
272
237
|
|
273
|
-
|
238
|
+
fieldTypeForAttrType: function(attrType){
|
274
239
|
var map = {
|
275
|
-
integer
|
276
|
-
decimal
|
277
|
-
datetime:'
|
278
|
-
date
|
279
|
-
string
|
280
|
-
|
240
|
+
integer : 'int',
|
241
|
+
decimal : 'float',
|
242
|
+
datetime : 'date',
|
243
|
+
date : 'date',
|
244
|
+
string : 'string',
|
245
|
+
text : 'string',
|
246
|
+
'boolean' : 'boolean'
|
281
247
|
};
|
282
|
-
return map[attrType] || '
|
248
|
+
return map[attrType] || 'string';
|
283
249
|
},
|
284
250
|
|
285
|
-
|
286
|
-
|
287
|
-
"float" : "numberfield",
|
288
|
-
"boolean": "checkbox",
|
289
|
-
decimal : "numberfield",
|
290
|
-
datetime : "datetimefield",
|
291
|
-
date : "datefield",
|
292
|
-
string : "textfield"
|
251
|
+
update: function(){
|
252
|
+
this.store.load();
|
293
253
|
},
|
294
254
|
|
295
|
-
|
296
|
-
|
255
|
+
loadStoreData: function(data){
|
256
|
+
var dataRecords = this.getStore().getProxy().getReader().read(data);
|
257
|
+
this.getStore().loadData(dataRecords.records);
|
258
|
+
Ext.each(['data', 'total', 'success'], function(property){delete data[property];}, this);
|
259
|
+
this.bulkExecute(data);
|
297
260
|
},
|
298
261
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
// Set default values
|
307
|
-
this.getStore().fields.each(function(field){
|
308
|
-
r.set(field.name, field.defaultValue);
|
309
|
-
});
|
310
|
-
|
311
|
-
this.tryStartEditing(this.store.indexOf(r));
|
312
|
-
},
|
313
|
-
|
314
|
-
onDel: function() {
|
315
|
-
Ext.Msg.confirm(this.i18n.confirmation, this.i18n.areYouSure, function(btn){
|
316
|
-
if (btn == 'yes') {
|
317
|
-
var records = [];
|
318
|
-
this.getSelectionModel().each(function(r){
|
319
|
-
if (r.isNew) {
|
320
|
-
// this record is not know to server - simply remove from store
|
321
|
-
this.store.remove(r);
|
322
|
-
} else {
|
323
|
-
records.push(r.id);
|
324
|
-
}
|
325
|
-
}, this);
|
326
|
-
|
327
|
-
if (records.length > 0){
|
328
|
-
if (!this.deleteMask) this.deleteMask = new Ext.LoadMask(this.bwrap, {msg: this.deleteMaskMsg});
|
329
|
-
this.deleteMask.show();
|
330
|
-
// call API
|
331
|
-
this.deleteData({records: Ext.encode(records)}, function(){
|
332
|
-
this.deleteMask.hide();
|
333
|
-
}, this);
|
334
|
-
}
|
335
|
-
}
|
336
|
-
}, this);
|
337
|
-
},
|
338
|
-
|
339
|
-
onApply: function(){
|
340
|
-
var newRecords = [];
|
341
|
-
var updatedRecords = [];
|
342
|
-
Ext.each(this.store.getModifiedRecords(),
|
343
|
-
function(r) {
|
344
|
-
if (r.isNew) {
|
345
|
-
newRecords.push(Ext.apply(r.getChanges(), {id:r.id}));
|
346
|
-
} else {
|
347
|
-
updatedRecords.push(Ext.apply(r.getChanges(), {id:r.id}));
|
348
|
-
}
|
349
|
-
},
|
350
|
-
this);
|
351
|
-
|
352
|
-
if (newRecords.length > 0 || updatedRecords.length > 0) {
|
353
|
-
var params = {};
|
354
|
-
|
355
|
-
if (newRecords.length > 0) {
|
356
|
-
params.created_records = Ext.encode(newRecords);
|
357
|
-
}
|
358
|
-
|
359
|
-
if (updatedRecords.length > 0) {
|
360
|
-
params.updated_records = Ext.encode(updatedRecords);
|
361
|
-
}
|
362
|
-
|
363
|
-
if (this.store.baseParams !== {}) {
|
364
|
-
params.base_params = Ext.encode(this.store.baseParams);
|
365
|
-
}
|
366
|
-
|
367
|
-
this.postData(params);
|
368
|
-
}
|
369
|
-
|
370
|
-
},
|
371
|
-
|
372
|
-
// Handlers for tools
|
373
|
-
//
|
374
|
-
|
375
|
-
onRefresh: function() {
|
376
|
-
if (this.fireEvent('refresh', this) !== false) {
|
377
|
-
this.store.reload();
|
262
|
+
// Tries editing the first editable (i.e. not hidden, not read-only) sell
|
263
|
+
tryStartEditing: function(r){
|
264
|
+
var editableIndex = 0;
|
265
|
+
Ext.each(this.initialConfig.columns, function(c){
|
266
|
+
// skip columns that cannot be edited
|
267
|
+
if (!(c.hidden == true || c.editable == false || !c.editor || c.attrType == 'boolean')) {
|
268
|
+
return false;
|
378
269
|
}
|
379
|
-
|
380
|
-
|
381
|
-
// Event handlers
|
382
|
-
//
|
383
|
-
|
384
|
-
onColumnResize: function(index, size){
|
385
|
-
this.resizeColumn({
|
386
|
-
index:index,
|
387
|
-
size:size
|
388
|
-
});
|
389
|
-
},
|
390
|
-
|
391
|
-
onColumnHiddenChange: function(cm, index, hidden){
|
392
|
-
this.hideColumn({
|
393
|
-
index:index,
|
394
|
-
hidden:hidden
|
395
|
-
});
|
396
|
-
},
|
397
|
-
|
398
|
-
onColumnMove: function(oldIndex, newIndex){
|
399
|
-
this.moveColumn({
|
400
|
-
old_index:oldIndex,
|
401
|
-
new_index:newIndex
|
402
|
-
});
|
403
|
-
|
404
|
-
var newRecordConfig = [];
|
405
|
-
Ext.each(this.getColumnModel().config, function(c){newRecordConfig.push({name: c.name})});
|
406
|
-
delete this.Row; // old record constructor
|
407
|
-
this.Row = Ext.data.Record.create(newRecordConfig);
|
408
|
-
this.getStore().reader.recordType = this.Row;
|
409
|
-
},
|
410
|
-
|
411
|
-
onRowContextMenu: function(grid, rowIndex, e){
|
412
|
-
e.stopEvent();
|
413
|
-
var coords = e.getXY();
|
414
|
-
|
415
|
-
if (!grid.getSelectionModel().isSelected(rowIndex)) {
|
416
|
-
grid.getSelectionModel().selectRow(rowIndex);
|
417
|
-
}
|
418
|
-
|
419
|
-
var menu = new Ext.menu.Menu({
|
420
|
-
items: this.contextMenu
|
421
|
-
});
|
422
|
-
|
423
|
-
menu.showAt(coords);
|
424
|
-
},
|
425
|
-
|
426
|
-
onAfterRowMove: function(dt, oldIndex, newIndex, records){
|
427
|
-
var ids = [];
|
428
|
-
// collect records ids
|
429
|
-
Ext.each(records, function(r){ids.push(r.id)});
|
430
|
-
// call GridPanel's API
|
431
|
-
this.moveRows({ids:Ext.encode(ids), new_index: newIndex});
|
432
|
-
},
|
433
|
-
|
434
|
-
// Other methods
|
435
|
-
//
|
270
|
+
editableIndex++;
|
271
|
+
});
|
436
272
|
|
437
|
-
|
438
|
-
if (response.status == 200 && (responseObject = Ext.decode(response.responseText)) && responseObject.flash){
|
439
|
-
this.feedback(responseObject.flash);
|
440
|
-
} else {
|
441
|
-
if (error){
|
442
|
-
this.feedback(error.message);
|
443
|
-
} else {
|
444
|
-
this.feedback(response.statusText);
|
445
|
-
}
|
446
|
-
}
|
273
|
+
if (editableIndex < this.initialConfig.columns.length) {this.getPlugin('celleditor').startEdit(r, this.columns[editableIndex]);}
|
447
274
|
},
|
448
275
|
|
449
|
-
update: function(){
|
450
|
-
this.store.reload();
|
451
|
-
},
|
452
|
-
|
453
|
-
loadStoreData: function(data){
|
454
|
-
this.store.loadData(data);
|
455
|
-
Ext.each(['data', 'total', 'success'], function(property){delete data[property];}, this);
|
456
|
-
this.bulkExecute(data);
|
457
|
-
},
|
458
|
-
|
459
|
-
// try editing the first editable (i.e. not hidden, not read-only) sell
|
460
|
-
tryStartEditing: function(row){
|
461
|
-
var editableIndex = 0;
|
462
|
-
Ext.each(this.getColumnModel().config, function(c){
|
463
|
-
// skip columns that cannot be edited
|
464
|
-
if (!(c.hidden == true || c.editable == false || !c.editor || c.attrType == 'boolean')) {
|
465
|
-
return false;
|
466
|
-
}
|
467
|
-
editableIndex++;
|
468
|
-
});
|
469
|
-
|
470
|
-
if (editableIndex < this.getColumnModel().config.length) {this.startEditing(row, editableIndex);}
|
471
|
-
},
|
472
|
-
|
473
276
|
// Called by the server side to update newly created records
|
474
277
|
updateNewRecords: function(records){
|
475
|
-
|
476
|
-
|
278
|
+
this.updateRecords(records);
|
279
|
+
},
|
477
280
|
|
478
281
|
// Called by the server side to update modified records
|
479
282
|
updateModRecords: function(records){
|
480
|
-
|
481
|
-
|
283
|
+
this.updateRecords(records, true);
|
284
|
+
},
|
482
285
|
|
483
286
|
// Updates modified or newly created records, by record ID
|
484
287
|
// Example of the records argument (updated columns):
|
@@ -486,52 +289,52 @@
|
|
486
289
|
// Example of the records argument (new columns, id autogenerated by Ext):
|
487
290
|
// {"ext-record-200" => [1, 'value1', 'value2']}
|
488
291
|
updateRecords: function(records, mod){
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
}
|
507
|
-
|
508
|
-
recordInGrid.isNew = false;
|
509
|
-
recordInGrid.commit();
|
292
|
+
if (!mod) {mod = false;}
|
293
|
+
var modRecordsInGrid = [].concat(this.store.getUpdatedRecords()); // there must be a better way to clone an array...
|
294
|
+
// replace arrays of data in the args object with Ext.data.Record objects
|
295
|
+
for (var k in records){
|
296
|
+
records[k] = this.getStore().getProxy().getReader().read({data:[records[k]]}).records[0];
|
297
|
+
}
|
298
|
+
// for each new record write the data returned by the server, and commit the record
|
299
|
+
Ext.each(modRecordsInGrid, function(recordInGrid){
|
300
|
+
if (mod ^ recordInGrid.isNew) {
|
301
|
+
// if record is new, we access its id by "id", otherwise, the id is in the primary key column
|
302
|
+
var recordId = recordInGrid.getId();
|
303
|
+
// new data that the server sent us to update this record (identified by the id)
|
304
|
+
var newData = records[recordId];
|
305
|
+
|
306
|
+
if (newData){
|
307
|
+
for (var k in newData.data){
|
308
|
+
recordInGrid.set(k, newData.get(k));
|
510
309
|
}
|
511
310
|
|
311
|
+
recordInGrid.isNew = false;
|
312
|
+
recordInGrid.commit();
|
512
313
|
}
|
513
|
-
}, this);
|
514
314
|
|
515
|
-
|
516
|
-
|
315
|
+
}
|
316
|
+
}, this);
|
517
317
|
|
518
|
-
|
519
|
-
|
520
|
-
if (modRecords.length == 0) {
|
521
|
-
// if all records are accepted, reload the grid (so that eventual order/filtering is correct)
|
522
|
-
this.store.reload();
|
318
|
+
// clear the selections
|
319
|
+
this.getSelectionModel().clearSelections();
|
523
320
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
321
|
+
// check if there are still records with errors
|
322
|
+
var modRecords = this.store.getUpdatedRecords();
|
323
|
+
if (modRecords.length == 0) {
|
324
|
+
// if all records are accepted, reload the grid (so that eventual order/filtering is correct)
|
325
|
+
this.store.load();
|
326
|
+
|
327
|
+
// ... and set default getRowClass function
|
328
|
+
this.getView().getRowClass = this.defaultGetRowClass;
|
329
|
+
} else {
|
330
|
+
this.getView().getRowClass = function(r){
|
331
|
+
return r.dirty ? "grid-dirty-record" : ""
|
530
332
|
}
|
333
|
+
}
|
531
334
|
|
532
|
-
|
533
|
-
|
534
|
-
|
335
|
+
this.getView().refresh();
|
336
|
+
this.getSelectionModel().fireEvent('selectionchange', this.getSelectionModel());
|
337
|
+
},
|
535
338
|
|
536
339
|
defaultGetRowClass: function(r){
|
537
340
|
return r.isNew ? "grid-dirty-record" : ""
|
@@ -543,18 +346,6 @@
|
|
543
346
|
this.getSelectionModel().resumeEvents();
|
544
347
|
},
|
545
348
|
|
546
|
-
setDefaultColumnType: function(c) {
|
547
|
-
if (c.xtype || c.renderer) return;
|
548
|
-
|
549
|
-
switch (c.attrType) {
|
550
|
-
case 'datetime': {
|
551
|
-
c.xtype = 'datecolumn';
|
552
|
-
c.format = c.format || "Y-m-d g:i:s";
|
553
|
-
break;
|
554
|
-
}
|
555
|
-
}
|
556
|
-
},
|
557
|
-
|
558
349
|
// Normalizes the renderer for a column.
|
559
350
|
// Renderer may be:
|
560
351
|
// 1) a string that contains the name of the function to be used as renderer.
|
@@ -576,7 +367,7 @@
|
|
576
367
|
var name, args = [];
|
577
368
|
|
578
369
|
if ('string' === typeof c.renderer) {
|
579
|
-
name = c.renderer;
|
370
|
+
name = c.renderer.camelize(true);
|
580
371
|
} else {
|
581
372
|
name = c.renderer[0];
|
582
373
|
args = c.renderer.slice(1);
|
@@ -584,54 +375,39 @@
|
|
584
375
|
|
585
376
|
// First check whether Ext.util.Format has it
|
586
377
|
if (Ext.isFunction(Ext.util.Format[name])) {
|
587
|
-
c.renderer = Ext.util.Format[name]
|
378
|
+
c.renderer = Ext.Function.bind(Ext.util.Format[name], this, args, 1);
|
588
379
|
} else if (Ext.isFunction(this[name])) {
|
589
380
|
// ... then if our own class has it
|
590
|
-
c.renderer = this[name]
|
381
|
+
c.renderer = Ext.Function.bind(this[name], this, args, 1);
|
591
382
|
} else {
|
592
383
|
// ... and, as last resort, evaluate it (allows passing inline javascript function as renderer)
|
593
384
|
eval("c.renderer = " + c.renderer + ";");
|
594
385
|
}
|
595
386
|
},
|
596
387
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
388
|
+
/*
|
389
|
+
Set a renderer that displayes association values instead of association record ID.
|
390
|
+
The association values are passed in the meta-column under associationValues hash.
|
391
|
+
*/
|
392
|
+
normalizeAssociationRenderer: function(c) {
|
393
|
+
c.scope = this;
|
394
|
+
var passedRenderer = c.renderer; // renderer we got from normalizeRenderer
|
395
|
+
c.renderer = function(value, a, r, ri, ci){
|
396
|
+
var column = this.headerCt.items.getAt(ci),
|
397
|
+
editor = column.getEditor && column.getEditor(),
|
398
|
+
// HACK: using private property 'store'
|
399
|
+
recordFromStore = editor && editor.isXType('combobox') && editor.store.findRecord('field1', value),
|
400
|
+
renderedValue;
|
401
|
+
|
402
|
+
if (recordFromStore) {
|
403
|
+
renderedValue = recordFromStore.get('field2');
|
404
|
+
} else if (c.assoc && r.get('_meta')) {
|
405
|
+
renderedValue = r.get('_meta').associationValues[c.name] || value;
|
602
406
|
} else {
|
603
|
-
|
407
|
+
renderedValue = value;
|
604
408
|
}
|
605
|
-
}
|
606
409
|
|
607
|
-
|
608
|
-
|
609
|
-
onEdit: function(){
|
610
|
-
var row = this.getSelectionModel().getSelected();
|
611
|
-
if (row){
|
612
|
-
this.tryStartEditing(this.store.indexOf(row));
|
613
|
-
}
|
614
|
-
},
|
615
|
-
|
616
|
-
// Not a very clean approach to clean-up. The problem is that this way the advanced search functionality stops being really pluggable. With Ext JS 4 find the way to make it truely so.
|
617
|
-
onDestroy: function(){
|
618
|
-
Netzke.classes.Basepack.GridPanel.superclass.onDestroy.call(this);
|
619
|
-
|
620
|
-
// Destroy the search window (here's the problem: we are not supposed to know it exists)
|
621
|
-
if (this.searchWindow) {
|
622
|
-
this.searchWindow.destroy();
|
623
|
-
}
|
410
|
+
return passedRenderer ? passedRenderer.call(this, renderedValue) : renderedValue;
|
411
|
+
};
|
624
412
|
}
|
625
|
-
|
626
|
-
// :reorder_columns => <<-END_OF_JAVASCRIPT.l,
|
627
|
-
// function(columns){
|
628
|
-
// columnsInNewShipment = [];
|
629
|
-
// Ext.each(columns, function(c){
|
630
|
-
// columnsInNewShipment.push({name:c});
|
631
|
-
// });
|
632
|
-
// newRecordType = Ext.data.Record.create(columnsInNewShipment);
|
633
|
-
// this.store.reader.recordType = newRecordType; // yes, recordType is a protected property, but that's the only way we can do it, and it seems to work for now
|
634
|
-
// }
|
635
|
-
// END_OF_JAVASCRIPT
|
636
|
-
|
637
413
|
}
|