]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - window/Edit.js
better default focus selection
[proxmox-widget-toolkit.git] / window / Edit.js
CommitLineData
06694509
DM
1// fixme: how can we avoid those lint errors?
2/*jslint confusion: true */
3Ext.define('Proxmox.window.Edit', {
4 extend: 'Ext.window.Window',
5 alias: 'widget.proxmoxWindowEdit',
1b07a95a 6
a33ba257
DM
7 // autoLoad trigger a load() after component creation
8 autoLoad: false,
9
06694509
DM
10 resizable: false,
11
12 // use this tio atimatically generate a title like
13 // Create: <subject>
14 subject: undefined,
15
b33f451f 16 // set isCreate to true if you want a Create button (instead
1b07a95a 17 // OK and RESET)
b33f451f 18 isCreate: false,
06694509
DM
19
20 // set to true if you want an Add button (instead of Create)
21 isAdd: false,
22
23 // set to true if you want an Remove button (instead of Create)
24 isRemove: false,
25
ffea05ec
DC
26 // custom submitText
27 submitText: undefined,
28
06694509
DM
29 backgroundDelay: 0,
30
a7dcbdeb
DM
31 // needed for finding the reference to submitbutton
32 // because we do not have a controller
33 referenceHolder: true,
34 defaultButton: 'submitbutton',
35
36 // finds the first form field
5d3089cd 37 defaultFocus: 'field[disabled=false][hidden=false]',
a7dcbdeb 38
06694509
DM
39 showProgress: false,
40
8d8dbfc5
TL
41 showTaskViewer: false,
42
fde8e8bb
TL
43 // gets called if we have a progress bar or taskview and it detected that
44 // the task finished. function(success)
45 taskDone: Ext.emptyFn,
46
42a9df8b
DC
47 // assign a reference from docs, to add a help button docked to the
48 // bottom of the window. If undefined we magically fall back to the
49 // onlineHelp of our first item, if set.
50 onlineHelp: undefined,
51
06694509
DM
52 isValid: function() {
53 var me = this;
54
55 var form = me.formPanel.getForm();
56 return form.isValid();
57 },
58
59 getValues: function(dirtyOnly) {
60 var me = this;
61
62 var values = {};
63
64 var form = me.formPanel.getForm();
65
66 form.getFields().each(function(field) {
67 if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) {
68 Proxmox.Utils.assemble_field_data(values, field.getSubmitData());
69 }
70 });
71
72 Ext.Array.each(me.query('inputpanel'), function(panel) {
73 Proxmox.Utils.assemble_field_data(values, panel.getValues(dirtyOnly));
74 });
75
76 return values;
77 },
78
79 setValues: function(values) {
80 var me = this;
81
82 var form = me.formPanel.getForm();
83
84 Ext.iterate(values, function(fieldId, val) {
85 var field = form.findField(fieldId);
86 if (field && !field.up('inputpanel')) {
87 field.setValue(val);
88 if (form.trackResetOnLoad) {
89 field.resetOriginalValue();
90 }
91 }
92 });
1b07a95a 93
06694509
DM
94 Ext.Array.each(me.query('inputpanel'), function(panel) {
95 panel.setValues(values);
96 });
97 },
98
99 submit: function() {
100 var me = this;
101
102 var form = me.formPanel.getForm();
103
104 var values = me.getValues();
105 Ext.Object.each(values, function(name, val) {
106 if (values.hasOwnProperty(name)) {
107 if (Ext.isArray(val) && !val.length) {
108 values[name] = '';
109 }
110 }
111 });
112
113 if (me.digest) {
114 values.digest = me.digest;
115 }
116
117 if (me.backgroundDelay) {
118 values.background_delay = me.backgroundDelay;
119 }
120
121 var url = me.url;
122 if (me.method === 'DELETE') {
123 url = url + "?" + Ext.Object.toQueryString(values);
124 values = undefined;
125 }
126
127 Proxmox.Utils.API2Request({
128 url: url,
129 waitMsgTarget: me,
130 method: me.method || (me.backgroundDelay ? 'POST' : 'PUT'),
131 params: values,
132 failure: function(response, options) {
133 if (response.result && response.result.errors) {
134 form.markInvalid(response.result.errors);
135 }
136 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
137 },
138 success: function(response, options) {
8d8dbfc5 139 var hasProgressBar = (me.backgroundDelay || me.showProgress || me.showTaskViewer) &&
06694509
DM
140 response.result.data ? true : false;
141
142 if (hasProgressBar) {
143 // stay around so we can trigger our close events
144 // when background action is completed
145 me.hide();
146
147 var upid = response.result.data;
8d8dbfc5
TL
148 var viewerClass = me.showTaskViewer ? 'Viewer' : 'Progress';
149 var win = Ext.create('Proxmox.window.Task' + viewerClass, {
06694509 150 upid: upid,
fde8e8bb 151 taskDone: me.taskDone,
06694509
DM
152 listeners: {
153 destroy: function () {
154 me.close();
155 }
156 }
157 });
158 win.show();
159 } else {
160 me.close();
161 }
162 }
163 });
164 },
165
166 load: function(options) {
167 var me = this;
168
169 var form = me.formPanel.getForm();
170
171 options = options || {};
172
173 var newopts = Ext.apply({
174 waitMsgTarget: me
175 }, options);
176
177 var createWrapper = function(successFn) {
178 Ext.apply(newopts, {
179 url: me.url,
180 method: 'GET',
181 success: function(response, opts) {
182 form.clearInvalid();
183 me.digest = response.result.data.digest;
184 if (successFn) {
185 successFn(response, opts);
186 } else {
187 me.setValues(response.result.data);
188 }
189 // hack: fix ExtJS bug
190 Ext.Array.each(me.query('radiofield'), function(f) {
191 f.resetOriginalValue();
192 });
193 },
194 failure: function(response, opts) {
195 Ext.Msg.alert(gettext('Error'), response.htmlStatus, function() {
196 me.close();
197 });
198 }
199 });
200 };
201
202 createWrapper(options.success);
203
204 Proxmox.Utils.API2Request(newopts);
205 },
206
207 initComponent : function() {
208 var me = this;
209
210 if (!me.url) {
211 throw "no url specified";
212 }
213
b33f451f
DC
214 if (me.create) {throw "deprecated parameter, use isCreate";}
215
06694509
DM
216 var items = Ext.isArray(me.items) ? me.items : [ me.items ];
217
218 me.items = undefined;
219
220 me.formPanel = Ext.create('Ext.form.Panel', {
221 url: me.url,
222 method: me.method || 'PUT',
223 trackResetOnLoad: true,
224 bodyPadding: 10,
225 border: false,
31a50251 226 defaults: Ext.apply({}, me.defaults, {
06694509 227 border: false
31a50251 228 }),
06694509
DM
229 fieldDefaults: Ext.apply({}, me.fieldDefaults, {
230 labelWidth: 100,
231 anchor: '100%'
232 }),
233 items: items
234 });
235
1b07a95a
DM
236 var inputPanel = me.formPanel.down('inputpanel');
237
06694509
DM
238 var form = me.formPanel.getForm();
239
240 var submitText;
b33f451f 241 if (me.isCreate) {
ffea05ec
DC
242 if (me.submitText) {
243 submitText = me.submitText;
244 } else if (me.isAdd) {
06694509
DM
245 submitText = gettext('Add');
246 } else if (me.isRemove) {
247 submitText = gettext('Remove');
248 } else {
249 submitText = gettext('Create');
250 }
251 } else {
ffea05ec 252 submitText = me.submitText || gettext('OK');
06694509
DM
253 }
254
255 var submitBtn = Ext.create('Ext.Button', {
a7dcbdeb 256 reference: 'submitbutton',
06694509 257 text: submitText,
b33f451f 258 disabled: !me.isCreate,
06694509
DM
259 handler: function() {
260 me.submit();
261 }
262 });
263
264 var resetBtn = Ext.create('Ext.Button', {
265 text: 'Reset',
266 disabled: true,
267 handler: function(){
268 form.reset();
269 }
270 });
271
272 var set_button_status = function() {
273 var valid = form.isValid();
274 var dirty = form.isDirty();
b33f451f 275 submitBtn.setDisabled(!valid || !(dirty || me.isCreate));
06694509 276 resetBtn.setDisabled(!dirty);
880df5d5
DC
277
278 if (inputPanel && inputPanel.hasAdvanced) {
279 // we want to show the advanced options
280 // as soon as some of it is not valid
281 var advancedItems = me.down('#advancedContainer').query('field');
282 var valid = true;
283 advancedItems.forEach(function(field) {
284 if (!field.isValid()) {
285 valid = false;
286 }
287 });
288
289 if (!valid) {
290 inputPanel.setAdvancedVisible(true);
291 me.down('#advancedcb').setValue(true);
292 }
293 }
06694509
DM
294 };
295
296 form.on('dirtychange', set_button_status);
297 form.on('validitychange', set_button_status);
298
299 var colwidth = 300;
300 if (me.fieldDefaults && me.fieldDefaults.labelWidth) {
301 colwidth += me.fieldDefaults.labelWidth - 100;
302 }
06694509 303
1b07a95a
DM
304 var twoColumn = inputPanel &&
305 (inputPanel.column1 || inputPanel.column2);
06694509
DM
306
307 if (me.subject && !me.title) {
b33f451f 308 me.title = Proxmox.Utils.dialog_title(me.subject, me.isCreate, me.isAdd);
06694509
DM
309 }
310
b33f451f 311 if (me.isCreate) {
06694509
DM
312 me.buttons = [ submitBtn ] ;
313 } else {
314 me.buttons = [ submitBtn, resetBtn ];
315 }
316
880df5d5
DC
317 if (inputPanel && inputPanel.hasAdvanced) {
318 var sp = Ext.state.Manager.getProvider();
319 var advchecked = sp.get('proxmox-advanced-cb');
320 inputPanel.setAdvancedVisible(advchecked);
321 me.buttons.unshift(
322 {
323 xtype: 'proxmoxcheckbox',
324 itemId: 'advancedcb',
325 boxLabelAlign: 'before',
326 boxLabel: gettext('Advanced'),
327 stateId: 'proxmox-advanced-cb',
328 value: advchecked,
329 listeners: {
330 change: function(cb, val) {
331 inputPanel.setAdvancedVisible(val);
332 sp.set('proxmox-advanced-cb', val);
333 }
334 }
335 }
336 );
337 }
338
c3457485
DM
339 var onlineHelp = me.onlineHelp;
340 if (!onlineHelp && inputPanel && inputPanel.onlineHelp) {
341 onlineHelp = inputPanel.onlineHelp;
342 }
343
344 if (onlineHelp) {
345 var helpButton = Ext.create('Proxmox.button.Help');
06694509 346 me.buttons.unshift(helpButton, '->');
c3457485 347 Ext.GlobalEvents.fireEvent('proxmoxShowHelp', onlineHelp);
06694509
DM
348 }
349
350 Ext.applyIf(me, {
351 modal: true,
352 width: twoColumn ? colwidth*2 : colwidth,
353 border: false,
354 items: [ me.formPanel ]
355 });
356
357 me.callParent();
358
359 // always mark invalid fields
360 me.on('afterlayout', function() {
361 // on touch devices, the isValid function
362 // triggers a layout, which triggers an isValid
363 // and so on
364 // to prevent this we disable the layouting here
365 // and enable it afterwards
366 me.suspendLayout = true;
367 me.isValid();
368 me.suspendLayout = false;
369 });
a33ba257
DM
370
371 if (me.autoLoad) {
372 me.load();
373 }
06694509
DM
374 }
375});