Ext.define('PVE.window.Wizard', {
extend: 'Ext.window.Window',
-
- getValues: function(dirtyOnly) {
- var me = this;
- var values = {};
+ activeTitle: '', // used for automated testing
- var form = me.down('form').getForm();
+ width: 720,
+ height: 540,
- form.getFields().each(function(field) {
- if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) {
- PVE.Utils.assemble_field_data(values, field.getSubmitData());
- }
- });
+ modal: true,
+ border: false,
- Ext.Array.each(me.query('inputpanel'), function(panel) {
- PVE.Utils.assemble_field_data(values, panel.getValues(dirtyOnly));
+ draggable: true,
+ closable: true,
+ resizable: false,
+
+ layout: 'border',
+
+ getValues: function(dirtyOnly) {
+ let me = this;
+
+ let values = {};
+
+ me.down('form').getForm().getFields().each(field => {
+ if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) {
+ Proxmox.Utils.assemble_field_data(values, field.getSubmitData());
+ }
+ });
+
+ me.query('inputpanel').forEach(panel => {
+ Proxmox.Utils.assemble_field_data(values, panel.getValues(dirtyOnly));
});
return values;
var tabs = me.items || [];
delete me.items;
-
- /*
+
+ /*
* Items may have the following functions:
* validator(): per tab custom validation
* onSubmit(): submit handler
});
tabs[0].disabled = false;
- var check_card = function(card) {
- var valid = true;
- var fields = card.query('field, fieldcontainer');
+ let maxidx = 0, curidx = 0;
+
+ let check_card = function(card) {
+ let fields = card.query('field, fieldcontainer');
if (card.isXType('fieldcontainer')) {
fields.unshift(card);
}
- Ext.Array.each(fields, function(field) {
+ let valid = true;
+ for (const field of fields) {
// Note: not all fielcontainer have isValid()
if (Ext.isFunction(field.isValid) && !field.isValid()) {
valid = false;
}
- });
-
+ }
if (Ext.isFunction(card.validator)) {
return card.validator();
}
-
return valid;
};
-
- var tbar = Ext.create('Ext.toolbar.Toolbar', {
- ui: 'footer',
- region: 'south',
- margins: '0 5 5 5',
- items: [
- '->',
- {
- text: gettext('Back'),
- disabled: true,
- itemId: 'back',
- minWidth: 60,
- handler: function() {
- var tp = me.down('#wizcontent');
- var atab = tp.getActiveTab();
- var prev = tp.items.indexOf(atab) - 1;
- if (prev < 0) {
- return;
- }
- var ntab = tp.items.getAt(prev);
- if (ntab) {
- tp.setActiveTab(ntab);
- }
-
-
- }
- },
- {
- text: gettext('Next'),
- disabled: true,
- itemId: 'next',
- minWidth: 60,
- handler: function() {
-
- var form = me.down('form').getForm();
-
- var tp = me.down('#wizcontent');
- var atab = tp.getActiveTab();
- if (!check_card(atab)) {
- return;
- }
-
- var next = tp.items.indexOf(atab) + 1;
- var ntab = tp.items.getAt(next);
- if (ntab) {
- ntab.enable();
- tp.setActiveTab(ntab);
- }
-
- }
- },
- {
- text: gettext('Finish'),
- minWidth: 60,
- hidden: true,
- itemId: 'submit',
- handler: function() {
- var tp = me.down('#wizcontent');
- var atab = tp.getActiveTab();
- atab.onSubmit();
- }
+ let disableTab = function(card) {
+ let tp = me.down('#wizcontent');
+ for (let idx = tp.items.indexOf(card); idx < tp.items.getCount(); idx++) {
+ let tab = tp.items.getAt(idx);
+ if (tab) {
+ tab.disable();
}
- ]
- });
-
- var display_header = function(newcard) {
- var html = '<h1>' + newcard.title + '</h1>';
- if (newcard.descr) {
- html += newcard.descr;
}
- me.down('#header').update(html);
};
- var disable_at = function(card) {
- var tp = me.down('#wizcontent');
- var idx = tp.items.indexOf(card);
- for(;idx < tp.items.getCount();idx++) {
- var nc = tp.items.getAt(idx);
- if (nc) {
- nc.disable();
- }
- }
- };
-
- var tabchange = function(tp, newcard, oldcard) {
+ let tabchange = function(tp, newcard, oldcard) {
if (newcard.onSubmit) {
me.down('#next').setVisible(false);
- me.down('#submit').setVisible(true);
+ me.down('#submit').setVisible(true);
} else {
me.down('#next').setVisible(true);
- me.down('#submit').setVisible(false);
+ me.down('#submit').setVisible(false);
}
- var valid = check_card(newcard);
- me.down('#next').setDisabled(!valid);
- me.down('#submit').setDisabled(!valid);
- me.down('#back').setDisabled(tp.items.indexOf(newcard) == 0);
-
- if (oldcard && !check_card(oldcard)) {
- disable_at(oldcard);
+ let valid = check_card(newcard);
+ me.down('#next').setDisabled(!valid);
+ me.down('#submit').setDisabled(!valid);
+ me.down('#back').setDisabled(tp.items.indexOf(newcard) === 0);
+
+ let idx = tp.items.indexOf(newcard);
+ if (idx > maxidx) {
+ maxidx = idx;
}
+ curidx = idx;
- var next = tp.items.indexOf(newcard) + 1;
- var ntab = tp.items.getAt(next);
+ let ntab = tp.items.getAt(idx + 1);
if (valid && ntab && !newcard.onSubmit) {
ntab.enable();
}
};
if (me.subject && !me.title) {
- me.title = PVE.Utils.dialog_title(me.subject, true, false);
+ me.title = Proxmox.Utils.dialog_title(me.subject, true, false);
}
+ let sp = Ext.state.Manager.getProvider();
+ let advancedOn = sp.get('proxmox-advanced-cb');
+
Ext.apply(me, {
- width: 620,
- height: 400,
- modal: true,
- border: false,
- draggable: true,
- closable: true,
- resizable: false,
- layout: 'border',
items: [
- {
- // disabled for now - not really needed
- hidden: true,
- region: 'north',
- itemId: 'header',
- layout: 'fit',
- margins: '5 5 0 5',
- bodyPadding: 10,
- html: ''
- },
{
xtype: 'form',
region: 'center',
margins: '5 5 0 5',
fieldDefaults: {
labelWidth: 100,
- anchor: '100%'
+ anchor: '100%',
},
items: [{
itemId: 'wizcontent',
xtype: 'tabpanel',
activeItem: 0,
- bodyPadding: 10,
+ bodyPadding: 0,
listeners: {
afterrender: function(tp) {
- var atab = this.getActiveTab();
- tabchange(tp, atab);
+ tabchange(tp, this.getActiveTab());
},
tabchange: function(tp, newcard, oldcard) {
- display_header(newcard);
tabchange(tp, newcard, oldcard);
- }
+ },
+ },
+ defaults: {
+ padding: 10,
+ },
+ items: tabs,
+ }],
+ },
+ ],
+ fbar: [
+ {
+ xtype: 'proxmoxHelpButton',
+ itemId: 'help',
+ },
+ '->',
+ {
+ xtype: 'proxmoxcheckbox',
+ boxLabelAlign: 'before',
+ boxLabel: gettext('Advanced'),
+ value: advancedOn,
+ listeners: {
+ change: function(_, value) {
+ let tp = me.down('#wizcontent');
+ tp.query('inputpanel').forEach(function(ip) {
+ ip.setAdvancedVisible(value);
+ });
+ sp.set('proxmox-advanced-cb', value);
},
- items: tabs
- }]
+ },
+ },
+ {
+ text: gettext('Back'),
+ disabled: true,
+ itemId: 'back',
+ minWidth: 60,
+ handler: function() {
+ let tp = me.down('#wizcontent');
+ let prev = tp.items.indexOf(tp.getActiveTab()) - 1;
+ if (prev < 0) {
+ return;
+ }
+ let ntab = tp.items.getAt(prev);
+ if (ntab) {
+ tp.setActiveTab(ntab);
+ }
+ },
+ },
+ {
+ text: gettext('Next'),
+ disabled: true,
+ itemId: 'next',
+ minWidth: 60,
+ handler: function() {
+ let tp = me.down('#wizcontent');
+ let activeTab = tp.getActiveTab();
+ if (!check_card(activeTab)) {
+ return;
+ }
+ let next = tp.items.indexOf(activeTab) + 1;
+ let ntab = tp.items.getAt(next);
+ if (ntab) {
+ ntab.enable();
+ tp.setActiveTab(ntab);
+ }
+ },
},
- tbar
- ]
+ {
+ text: gettext('Finish'),
+ minWidth: 60,
+ hidden: true,
+ itemId: 'submit',
+ handler: function() {
+ let tp = me.down('#wizcontent');
+ tp.getActiveTab().onSubmit();
+ },
+ },
+ ],
});
me.callParent();
- display_header(tabs[0]);
+
+ Ext.Array.each(me.query('inputpanel'), function(panel) {
+ panel.setAdvancedVisible(advancedOn);
+ });
Ext.Array.each(me.query('field'), function(field) {
- field.on('validitychange', function(f) {
- var tp = me.down('#wizcontent');
- var atab = tp.getActiveTab();
- var valid = check_card(atab);
- me.down('#next').setDisabled(!valid);
- me.down('#submit').setDisabled(!valid);
- var next = tp.items.indexOf(atab) + 1;
- var ntab = tp.items.getAt(next);
- if (!valid) {
- disable_at(ntab);
- } else if (ntab && !atab.onSubmit) {
- ntab.enable();
+ let validcheck = function() {
+ let tp = me.down('#wizcontent');
+
+ // check validity for current to last enabled tab, as local change may affect validity of a later one
+ for (let i = curidx; i <= maxidx && i < tp.items.getCount(); i++) {
+ let tab = tp.items.getAt(i);
+ let valid = check_card(tab);
+
+ // only set the buttons on the current panel
+ if (i === curidx) {
+ me.down('#next').setDisabled(!valid);
+ me.down('#submit').setDisabled(!valid);
+ }
+ // if a panel is invalid, then disable all following, else enable the next tab
+ let nextTab = tp.items.getAt(i + 1);
+ if (!valid) {
+ disableTab(nextTab);
+ return;
+ } else if (nextTab && !tab.onSubmit) {
+ nextTab.enable();
+ }
}
- });
+ };
+ field.on('change', validcheck);
+ field.on('validitychange', validcheck);
});
- }
+ },
});