pve-manager/www/manager6/form/ListField.js
Dominik Csapak 56dee217bc ui: fix datacenter tags options inputs
* dont allow blank for tree shape
* allow completely removing registered tags and user-tag-access properties
* correctly check validity for the listfield
* use correct gettexts
* don't inject empty field in the listfield when setting an empty string

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-11-18 12:56:18 +01:00

188 lines
3.4 KiB
JavaScript

Ext.define('PVE.form.ListField', {
extend: 'Ext.container.Container',
alias: 'widget.pveListField',
mixins: [
'Ext.form.field.Field',
],
// override for column header
fieldTitle: gettext('Item'),
// will be applied to the textfields
maskRe: undefined,
allowBlank: true,
selectAll: false,
isFormField: true,
deleteEmpty: false,
config: {
deleteEmpty: false,
},
setValue: function(list) {
let me = this;
list = Ext.isArray(list) ? list : (list ?? '').split(';').filter(t => t !== '');
let store = me.lookup('grid').getStore();
if (list.length > 0) {
store.setData(list.map(item => ({ item })));
} else {
store.removeAll();
}
me.checkChange();
return me;
},
getValue: function() {
let me = this;
let values = [];
me.lookup('grid').getStore().each((rec) => {
if (rec.data.item) {
values.push(rec.data.item);
}
});
return values.join(';');
},
getErrors: function(value) {
let me = this;
let empty = false;
me.lookup('grid').getStore().each((rec) => {
if (!rec.data.item) {
empty = true;
}
});
if (empty) {
return [gettext('Tag must not be empty.')];
}
return [];
},
// override framework function to implement deleteEmpty behaviour
getSubmitData: function() {
let me = this,
data = null,
val;
if (!me.disabled && me.submitValue) {
val = me.getValue();
if (val !== null && val !== '') {
data = {};
data[me.getName()] = val;
} else if (me.getDeleteEmpty()) {
data = {};
data.delete = me.getName();
}
}
return data;
},
controller: {
xclass: 'Ext.app.ViewController',
addLine: function() {
let me = this;
me.lookup('grid').getStore().add({
item: '',
});
},
removeSelection: function(field) {
let me = this;
let view = me.getView();
let grid = me.lookup('grid');
let record = field.getWidgetRecord();
if (record === undefined) {
// this is sometimes called before a record/column is initialized
return;
}
grid.getStore().remove(record);
view.checkChange();
view.validate();
},
itemChange: function(field, newValue) {
let rec = field.getWidgetRecord();
if (!rec) {
return;
}
let column = field.getWidgetColumn();
rec.set(column.dataIndex, newValue);
let list = field.up('pveListField');
list.checkChange();
list.validate();
},
control: {
'grid button': {
click: 'removeSelection',
},
},
},
items: [
{
xtype: 'grid',
reference: 'grid',
viewConfig: {
deferEmptyText: false,
},
store: {
listeners: {
update: function() {
this.commitChanges();
},
},
},
},
{
xtype: 'button',
text: gettext('Add'),
iconCls: 'fa fa-plus-circle',
handler: 'addLine',
},
],
initComponent: function() {
let me = this;
for (const [key, value] of Object.entries(me.gridConfig ?? {})) {
me.items[0][key] = value;
}
me.items[0].columns = [
{
header: me.fieldTtitle,
dataIndex: 'item',
xtype: 'widgetcolumn',
widget: {
xtype: 'textfield',
isFormField: false,
maskRe: me.maskRe,
allowBlank: false,
queryMode: 'local',
listeners: {
change: 'itemChange',
},
},
flex: 1,
},
{
xtype: 'widgetcolumn',
width: 40,
widget: {
xtype: 'button',
iconCls: 'fa fa-trash-o',
},
},
];
me.callParent();
me.initField();
},
});