[pve-devel] [PATCH pve-manager v2] ext6migrate: Update our ComboGrid component to work with ExtJS6
Emmanuel Kasper
e.kasper at proxmox.com
Wed Jan 13 11:24:34 CET 2016
Instead of extending the framework ComboBox, we extend the abstract
parent class Picker, so we don't rely on private methods ( and hopefull survive the
next ExtJS upgrade )
Usability improvement:
The selection model is now a checkboxmodel, which makes more clear to the user that
we can select more than one element in the list.
---
www/manager6/form/ComboGrid.js | 152 +++++++++++++++++++++++------------------
1 file changed, 86 insertions(+), 66 deletions(-)
diff --git a/www/manager6/form/ComboGrid.js b/www/manager6/form/ComboGrid.js
index a226cb5..6bbb7cc 100644
--- a/www/manager6/form/ComboGrid.js
+++ b/www/manager6/form/ComboGrid.js
@@ -1,84 +1,104 @@
+/*
+ * ComboGrid component:
+ * a ComboBox where the dropdown menu (the "Picker") is a Grid with Rows and Columns
+ * expects a listConfig object with a columns property
+ * roughly based on the GridPicker from https://www.sencha.com/forum/showthread.php?299909
+ *
+*/
Ext.define('PVE.form.ComboGrid', {
- extend: 'Ext.form.field.ComboBox',
+ extend: 'Ext.form.field.Picker',
alias: ['widget.PVE.form.ComboGrid'],
// this value is used as default value after load()
preferredValue: undefined,
-
- // hack: allow to select empty value
- // seems extjs does not allow that when 'editable == false'
- onKeyUp: function(e, t) {
- var me = this;
- var key = e.getKey();
-
- if (!me.editable && me.allowBlank && !me.multiSelect &&
- (key == e.BACKSPACE || key == e.DELETE)) {
- me.setValue('');
- }
-
- me.callParent(arguments);
+ // If set to `true`, allows the combo field to hold more than one value at a time, and allows selecting multiple
+ // items from the dropdown list.
+ multiSelect: false,
+
+ defaultPickerConfig: {
+ maxHeight: 300,
+ width: 400,
+ scrollable: true,
+ floating: true,
},
- // copied from ComboBox
- createPicker: function() {
- var me = this,
- picker,
- menuCls = Ext.baseCSSPrefix + 'menu',
+ displayField: false,
+ valueField: false,
+ matchFieldWidth: false,
- opts = Ext.apply({
+ createPicker: function() {
+ var me = this;
+ var config = Ext.applyIf({
+ store: me.getStore(),
selModel: {
- mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
+ selType: 'checkboxmodel',
+ mode: me.multiSelect ? 'SIMPLE' : 'SINGLE',
+ showHeaderCheckbox: false // shows a selectAll checkbox, not reliable
},
- floating: true,
- hidden: true,
- ownerCt: me.ownerCt,
- cls: me.el.up('.' + menuCls) ? menuCls : '',
- store: me.store,
- displayField: me.displayField,
- focusOnToFront: false,
- pageSize: me.pageSize
- }, me.listConfig, me.defaultListConfig);
-
- // NOTE: we simply use a grid panel
- //picker = me.picker = Ext.create('Ext.view.BoundList', opts);
- picker = me.picker = Ext.create('Ext.grid.Panel', opts);
-
- // pass getNode() to the view
- picker.getNode = function() {
- picker.getView().getNode(arguments);
- };
-
- me.mon(picker, {
- itemclick: me.onItemClick,
- refresh: me.onListRefresh,
- show: function() {
- me.syncSelection();
- },
- scope: me
- });
-
- me.mon(picker.getSelectionModel(), 'selectionchange', me.onListSelectionChange, me);
-
- return picker;
+ listeners: {
+ selectionchange: {
+ fn: function(grid, selectedRecords) {
+ me.setRecords(selectedRecords);
+ me.fireEvent('select', me, selectedRecords);
+ },
+ scope: me
+ }
+ }
+ }, me.defaultPickerConfig);
+
+ var grid = Ext.create('Ext.grid.Panel', config);
+
+ // update the grid with the field values when loading
+ if (me.getRawValue()){
+ var previousItems = [];
+ Ext.Array.each(me.getRawValue().split(','), function(record) {
+ var previousItem = me.store.findRecord(me.valueField, record);
+ previousItems.push(previousItem);
+ });
+
+ grid.getSelectionModel().select(previousItems);
+
+ }
+
+ return grid;
},
- initComponent: function() {
- var me = this;
+ setRecords: function(records) {
+ if (records && !Ext.isArray(records)) {
+ records = [records];
+ }
+ this.selectedRecords = records;
+ var rawValue = [];
- if (me.initialConfig.editable === undefined) {
- me.editable = false;
- }
+ Ext.Array.each(records, function(record) {
+ rawValue.push(record.get(this.displayField));
+ }, this);
- Ext.apply(me, {
- queryMode: 'local',
- matchFieldWidth: false
- });
+ this.setValue(rawValue);
+ },
+
+ getRecords: function() {
+ return this.selectedRecords;
+ },
- Ext.applyIf(me, { value: ''}); // hack: avoid ExtJS validate() bug
+ beforeReset: function() {
+ if(this.picker) {
+ this.picker.getSelectionModel().deselectAll()
+ }
+ this.callParent(arguments);
+ },
- Ext.applyIf(me.listConfig, { width: 400 });
+ getStore: function() {
+ if (!this.store) {
+ this.store = Ext.create('Ext.data.Store', {});
+ }
+ return this.store;
+ },
- me.callParent();
+ initComponent: function() {
+ var me = this;
+ Ext.apply(me.defaultPickerConfig, me.listConfig);
+ me.callParent(arguments);
me.store.on('beforeload', function() {
if (!me.isDisabled()) {
@@ -126,5 +146,5 @@ Ext.define('PVE.form.ComboGrid', {
}
}
});
- }
-});
+ },
+});
\ No newline at end of file
--
2.1.4
More information about the pve-devel
mailing list