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