[pve-devel] [PATCH proxmox-widget-toolkit] form: add Proxmox.form.field.DisplayEdit

Dominik Csapak d.csapak at proxmox.com
Thu Apr 2 10:14:16 CEST 2020


one nit inline, high level comment here:

one thing did come to mind what may be 'dangerous' is
if the caller of this uses a change listener, since
it suddenly would trigger for both fields i guess?
(e.g. in an edit window, but did not test)
or validator? but i guess a displayfield does not
validate anyway...

also how about setting the value?
the inputpanel for example does:
---8<---
query('[isFormField][name='+id+']')[0]
--->8---
so it only sets the first field it finds.
can that be a problem?

On 3/31/20 6:38 PM, Thomas Lamprecht wrote:
> This allows to write our often used:
> 
>> {
>>      xtype: me.isCreate ? 'someEditableField' : 'displayfield',
>>      ...
>> }
> 
> In a more schematic way, as it can now be controlled by either our
> CBind mixin or ExtJS native data binding.
> 
> Use a Field container to add both, they editable and they display,
> variants of a form field. As default use "textfield" for the editable
> and "displayfield" xtype for the read only one.
> 
> Pass all but the editConfig and editable members of our initial
> config to the display field, allow further to configure the editable
> field with an editConfig object, which overwrites the config
> properties inherited from the displayConfig/parent config.
> 
> This gives full control while not enforcing to specify anything extra
> for most default cases.
> 
> Enforce initial state of the fields even if the databinding would
> handle it to avoid glitches after first render for simple boolean expression
> cases.
> 
>> {
>>      xtype: 'pmxDisplayEditField',
>>      cbind: {
>>          editable: '{isCreate}',
>>      },
>>      name: 'tokenid',
>>      fieldLabel: gettext('Token ID'),
>>      value: me.tokenid,
>>      allowBlank: false,
>> }
> 
> Here, cbind could also be a bind or a native boolean expression.
> 
> For something else than a texfield one would use the editConfig, e.g.:
>> {
>>      ....
>>      editConfig: {
>>          xtype: 'pveUserSelector',
>>          allowBlank: false,
>>      },
>> },
> 
> Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
> ---
> 
> Naming is the first somewhat sensible comming into my mind, so..
> I head some other ideas for more general or less general implementations, this
> seemed to strike some balance.
> 
> I have some changes to this here locally, but most are in Fabians Token series.
> Tested the live change over viewModel change or setEditable calls initially
> using the developer view, e.g.:
> 
>> let el = Ext.ComponentQuery.query('pmxDisplayEditField')[0];
>> el.setEditable(true);
>> let vm = el.getViewModel();
>> vm.set('editable', false);
> 
>   Makefile            |  1 +
>   form/DisplayEdit.js | 71 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 72 insertions(+)
>   create mode 100644 form/DisplayEdit.js
> 
> diff --git a/Makefile b/Makefile
> index 703b570..a729b95 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -15,6 +15,7 @@ JSSRC=					\
>   	data/ObjectStore.js		\
>   	data/RRDStore.js		\
>   	data/TimezoneStore.js		\
> +	form/DisplayEdit.js		\
>   	form/ExpireDate.js		\
>   	form/IntegerField.js		\
>   	form/TextField.js		\
> diff --git a/form/DisplayEdit.js b/form/DisplayEdit.js
> new file mode 100644
> index 0000000..9b3f1c0
> --- /dev/null
> +++ b/form/DisplayEdit.js
> @@ -0,0 +1,71 @@
> +Ext.define('Proxmox.form.field.DisplayEdit', {
> +    extend: 'Ext.form.FieldContainer',
> +    alias: ['widget.pmxDisplayEditField'],
> +    mixins: ['Proxmox.Mixin.CBind' ],
> +
> +    viewModel: {
> +	data: {
> +	    editable: false,
> +	},
> +    },
> +
> +    displayType: 'displayfield',
> +
> +    editConfig: {},
> +    editable: false,
> +    setEditable: function(editable) {
> +	let me = this;
> +	let vm = me.getViewModel();
> +
> +	me.editable = editable;
> +	vm.set('editable', editable);
> +    },
> +
> +    layout: 'hbox',
> +    defaults: {
> +	hideLabel: true
> +    },
> +
> +    initComponent: function() {
> +	let me = this;
> +
> +	let displayConfig = {
> +	    xtype: me.displayType,
> +	    bind: {
> +		hidden: '{editable}',
> +		disabled: '{editable}',
> +	    },
> +	};
> +	Ext.applyIf(displayConfig, me.initialConfig);
> +	delete displayConfig.editConfig;
> +	delete displayConfig.editable;
> +
> +	let editConfig = me.editConfig;
> +	Ext.applyIf(editConfig, {
> +	    xtype: 'textfield',
> +	    bind: {
> +		hidden: '{!editable}',
> +		disabled: '{!editable}',
> +	    },
> +	});
> +	Ext.applyIf(editConfig, displayConfig);
> +
> +	// avoid glitch, start off correct even before viewmodel fixes it
> +	editConfig.disabled = editConfig.hidden = !me.editable;
> +	displayConfig.disabled = displayConfig.hidden = !!me.editable;
> +
> +	editConfig.name = displayConfig.name = me.name;
> +
> +	Ext.apply(me, {
> +	    items: [
> +		displayConfig,
> +		editConfig,
> +	    ],
> +	});
> +
> +	me.callParent();
> +
> +	me.getViewModel().set('editable', me.editable);
> +    },
> +
> +});
> 




More information about the pve-devel mailing list