Flow UI Editable Datagrid

When I add editable=true I expect the field to be editable, but unfortunately this does not work.
What am I missing?
Do you have a working example?

1 Like

Apart from setting the editable attribute of a column, you should start editing of a row either programmatically as described in the Vaadin docs, or by defining the editorActionsColumn element, for example:

<dataGrid id="departmentsTable"
          width="100%"
          minHeight="20em"
          dataContainer="departmentsDc">
    <columns>
        <column property="name" editable="true"/>
        <column property="hrManager"/>
        <editorActionsColumn width="8em" flexGrow="0">
            <editButton text="Edit" icon="PENCIL"/>
            <closeButton text="Close" icon="CLOSE"/>
        </editorActionsColumn>
    </columns>
</dataGrid>

See more details in the issue.
This information will be included in Jmix docs soon.

Hi Konstantin
Thanks for the code snippets. It is helpful.
I am also interested in editing by double-click like what is explained in Vaadin documentation. However,
as you see below marked in red which is not recognized in Jmix, I am wondering if there is any additional setup necessary.

Editor<AccountSub> editor = accountSubTable.getEditor();
        accountSubTable.addItemDoubleClickListener(e -> {
            editor.editItem(`e.getItem()`);
            Component editorComponent = e.`getColumn`().getEditorComponent();
            if (editorComponent instanceof Focusable) {
                ((Focusable) editorComponent).focus();
            }
        });

Could you give the link to the Vaadin docs which you mentioned?
The code above is not a valid Java code.

Hi Konstantin
Here is where I copied that from:

Scroll to the section: Non-Buffered

and here is the codes, look at the last section of the codes:

Grid<Person> grid = new Grid<>(Person.class, false);
Grid.Column<Person> firstNameColumn = grid
        .addColumn(Person::getFirstName).setHeader("First name")
        .setWidth("120px").setFlexGrow(0);
Grid.Column<Person> lastNameColumn = grid.addColumn(Person::getLastName)
        .setHeader("Last name").setWidth("120px").setFlexGrow(0);
Grid.Column<Person> emailColumn = grid.addColumn(Person::getEmail)
        .setHeader("Email");

Binder<Person> binder = new Binder<>(Person.class);
Editor<Person> editor = grid.getEditor();
editor.setBinder(binder);

TextField firstNameField = new TextField();
firstNameField.setWidthFull();
addCloseHandler(firstNameField, editor);
binder.forField(firstNameField)
        .asRequired("First name must not be empty")
        .withStatusLabel(firstNameValidationMessage)
        .bind(Person::getFirstName, Person::setFirstName);
firstNameColumn.setEditorComponent(firstNameField);

TextField lastNameField = new TextField();
lastNameField.setWidthFull();
addCloseHandler(lastNameField, editor);
binder.forField(lastNameField).asRequired("Last name must not be empty")
        .withStatusLabel(lastNameValidationMessage)
        .bind(Person::getLastName, Person::setLastName);
lastNameColumn.setEditorComponent(lastNameField);

EmailField emailField = new EmailField();
emailField.setWidthFull();
addCloseHandler(emailField, editor);
binder.forField(emailField).asRequired("Email must not be empty")
        .withValidator(
                new EmailValidator("Enter a valid email address"))
        .withStatusLabel(emailValidationMessage)
        .bind(Person::getEmail, Person::setEmail);
emailColumn.setEditorComponent(emailField);

grid.addItemDoubleClickListener(e -> {
    editor.editItem(e.getItem());
    Component editorComponent = e.getColumn().getEditorComponent();
    if (editorComponent instanceof Focusable) {
        ((Focusable) editorComponent).focus();
    }
});

Thanks in advance for your advice/help.

Works for me exactly as described in Vaadin docs:

@ViewComponent
private DataGrid<Department> departmentsTable;

@Subscribe
public void onInit(InitEvent event) {
    DataGridEditor<Department> editor = departmentsTable.getEditor();
    departmentsTable.addItemDoubleClickListener(e -> {
        editor.editItem(e.getItem());
        Component editorComponent = e.getColumn().getEditorComponent();
        if (editorComponent instanceof Focusable) {
            ((Focusable) editorComponent).focus();
        }
    });
}
<dataGrid id="departmentsTable" ...
    <columns>
        <column property="name" editable="true"/>
    </columns>
</dataGrid>

Thank you, it worked for me too.

in Classis-UI we could use

@Autowired
private DataContext dataContext;

to save data.

How to do so in Flow-UI ?

Hi,

for the view infrastructure the @ViewComponent annotation is used to “inject” components, so the correct code is:

@ViewComponent
private DataContext dataContext;

or you can ask studio to inject it for you:

Screenshot 2023-05-29 at 11.07.40

Regards,
Gleb

1 Like

Thank you Gleb !

I am still asking myself, why this code is not automatically generated, if one adds the datagrid as editable ?
@ViewComponent
private DataContext dataContext;

@Subscribe(target = Target.DATA_CONTEXT)
public void onChange(DataContext.ChangeEvent event) {
    dataContext.save();
}

One has to add it manually in all views…

First of all, you don’t add editable DataGrid, you just change its attribute to make it editable. I mean, it’s not like creating an editable DataGrid using a dedicated template.

Second, saving data on every change is just one of the cases. Depending on the task, there may be a button for manual saving, so a user can change several entities and than commit them in a single transaction.

Considering the above, we cannot force users to follow only one pattern, that why you have to choose what behaviour you want to implement.

Regards,
Gleb

Dear Gleb

Thank you for your elaboration.

If you add this little code, you make it workable for everybody at the first hit. You promote Jmix as a RAD. So if people need additional features, they can change that. But you will have less requests “why my edited data is not saved in the list view but in the detail view it is saved”.

So the list-view is working the same like the detail-view, which makes sense in my point of view

Best regards

Felix