Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Table and GroupBox for details on row selection
Table and GroupBox for details on row selection [message #1172004] Tue, 05 November 2013 11:35 Go to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
Assume you have this use case:
A table fields contains some rows. When a row is selected, some detail information are displayed in a Group Box near the table field.

I have used this pattern:
* I extracted my DetailGroupBox in a Template => AbstractDetailGroupBox.
* The SDK generate the AbstractDetailGroupBoxData corresponding to the AbstractDetailGroupBox template.
* In the shared plugin in created a concrete class: MyDetailGroupBoxData (extends AbstractDetailGroupBoxData). [this is an example: in the real world I do not use "My" as suffix]
* In the table, I add a not-displayable column: DetailColumn (extends AbstractColumn<MyDetailGroupBoxData>)
* On the DetailBox I add @FormData(sdkCommand = IGNORE) => Because I want that from the server, the data are put in the TableData of the FormData instead of directly in the formData.

Now I have following Form Tree:

Form
-- MainBox
----TableField
------Table
--------NameColumn: String
--------DetailColumn: Column<MyDetailGroupBoxData>
----DetailBox: GroupBox with FormData IGNORE command


In the execRowsSelected I want to do the DetailBox handling.

I was assuming that is was possible to do:
MyDatailGroupBoxData source = getTable().getDetailColumn().getValue(row);
getDetailGroupBox().importFormFieldData(source, false);


BUT the implementation is empty!!! For my DetailBox the method is:
org.eclipse.scout.rt.client.ui.form.fields.AbstractFormField.importFormFieldData(AbstractFormFieldData, boolean)

This is probably OK in the generic case, but it means that I need to do it by myself.
Override importFormFieldData(..) in DetailBox.

I was thinking: why can't I reuse the logic in org.eclipse.scout.rt.client.ui.form.AbstractForm.importFormData(..)
Re: Table and GroupBox for details on row selection [message #1173662 is a reply to message #1172004] Wed, 06 November 2013 12:24 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
I have copy-pasted and adapted the code I needed to be able to write something like this:

@Order(20.0)
@FormData(sdkCommand = SdkCommand.IGNORE)
public class DetailBox extends AbstractDetailBox {
  @Override
  public void importFormFieldData(AbstractFormFieldData source, boolean valueChangeTriggersEnabled) throws ProcessingException {
    FormDataUtility2.importFormFieldData(this, source, valueChangeTriggersEnabled, null, null);
  }

  @Override
  public void exportFormFieldData(AbstractFormFieldData target) throws ProcessingException {
    FormDataUtility2.exportFormData(this, target);
  }
}


For me this code should goes in the FormDataUtility and should be mutualized between importFormData() on the form and importFormFieldData() in the GroupBox.

The current implementation of importFormFieldData() should stay empty in GroupBox, but for people who needs it, it should be simple to activate import/export in a GroupBox.
Re: Table and GroupBox for details on row selection [message #1288221 is a reply to message #1173662] Tue, 08 April 2014 07:26 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
Related to this pattern, for the Table implementation (NameColumn and DetailColumn) see also this thread about @ColumnData(IGNORE).

The annotation should be used on NameColumn in this example.
Re: Table and GroupBox for details on row selection [message #1295232 is a reply to message #1288221] Mon, 14 April 2014 01:23 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
I had the chance to continue to work on this pattern.

For such a use case, the default Scout approach would be to use an editable table. But if the Details you want to display are too important, I think that this is how you can do it in a scout application.

Here the solution I developed for master table row and detail group box:

By default the "Detail" group box (containing the edition zone for the selected row) is disabled:

index.php/fa/17914/0/

On click, the values are imported:

index.php/fa/17915/0/

It is possible to define a field that will request the focus [in this case getFirstNameField().requestFocus()]

When a value is edited, it is updated in the table when the focus changed (similar to execChangedValue):

index.php/fa/17916/0/

index.php/fa/17917/0/
Re: Table and GroupBox for details on row selection [message #1295233 is a reply to message #1295232] Mon, 14 April 2014 01:25 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
Adding a row is possible with the Empty Space Menu "New":

index.php/fa/17918/0/


Like in the edit case, the first field gets the focus.

index.php/fa/17919/0/

If no value has been set in any of the edit fields when the selection changes in the table, the empty row is removed (because it is also invisible for the user).


There is also a menu to delete a row:

index.php/fa/17920/0/



I have an implementation relying on templates (generic enough to be reusable). If someone is interested I could share the code somewhere.

Do not hesitate to discuss a point or to send feedback...

.
Re: Table and GroupBox for details on row selection [message #1297527 is a reply to message #1295233] Tue, 15 April 2014 14:53 Go to previous message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 529
Registered: October 2011
Senior Member
I was asked to present how this pattern is implemented. If you use it, please give us feedback. Maybe support for this pattern (Scout RT and Scout SDK) will be included in the next release of Eclipse Scout.

Because of the lack of support in the current Scout Version, implementing this pattern is not as easy as other task that you can do with the Scout SDK. You should have some experience with Scout and some Java Knowledge.

I have tested this with Scout Luna M6.


1/ Prepare your form:

Like for any other form, you can use the SDK to make your form (MyMasterDetailForm).

You will need at least:
- A Table Field (that will be the master Table).
- A GroupBox containing the detail that will be displayed.

In your table field, you can already create a column called ContentColumn. For the moment this column can have the type ObjectColumn. (I put this column as first column, but this does not maters).

In my example the other columns are simple String Column because I want to handle string fields (first name and last name). It is possible to imagine other types (SmartColumn, IntegerColumn). It is important that the type match the type of the fields in the detail box.

To keep this example simple, the detail box only contains 3 String fields. Create the detail box (in my example it is named SelectedPersonDetailBox) and add the fields
In the detail box you can imagine the content you want. (Multiple group boxes, other fields, even a table...)


2/ Create a template to obtain the DetailBoxData

We need a java object to hold the content of the detail box for each row.
You can work with a plain Java Bean, but in this case, you will need to write the import/export from the bean into the detail box (SelectedPersonDetailBox).

An easiest way is to use the Scout SDK functionality (exactly like for FormData). This way your java object to hold the Data is keep in sync with the detail box.

Select your GroupBox in the Scout Explorer and create a template: AbstractSelectedPersonDetailBox.

Important is to let following options checked:
- "use Template for 'SelectedPersonDetailBox'
- "create external formData".

This way you obtain an "AbstractSelectedPersonDetailBoxData" in the shared plugin. Because this class is created abstract by the SDK you need to create a child class: PersonBoxData
public class PersonBoxData extends AbstractSelectedPersonDetailBoxData {
  private static final long serialVersionUID = 1L;

}


In the MyFormData (corresponding to MyForm) you do not want to set data in the server for the SelectedPersonDetailBox (because what will be displayed in the fields comes from the selection in the table field). You can add @FormData(sdkCommand = SdkCommand.IGNORE) on the field :
@Order(20.0)
@FormData(sdkCommand = SdkCommand.IGNORE)
public class SelectedPersonDetailBox extends AbstractSelectedPersonDetailBox {

}



3/ Use @ColumnData(Ignore)

The idea of this pattern is that the data are stored in a not-displayable column (the ContentColumn described in step 1). If you have not created this column, do so now.

We do not want somebody to set a value for the column FirstNameColumn and LastNameColumn in the server.

Do what is described in this forum thread:
- Make the 2 getters for the 2 columns (FirstName and LastName) protected instead of public.
- Add @ColumnData(SdkColumnCommand.IGNORE) on the 2 columns
- Change the type of the ContentColumn: AbstractContentColumn<T> where T is PersonBoxData.
- Implement the requested updateTableColumns(ITableRow, PersonBoxData) method. This method is responsible for the update of the columns that are ignored in the formData.

@Order(10.0)
public class ContentColumn extends AbstractContentColumn<PersonBoxData> {

  @Override
  protected boolean getConfiguredDisplayable() {
    return false;
  }

  @Override
  protected void updateTableColumns(ITableRow r, PersonBoxData data) throws ProcessingException {
    getFirstNameColumn().setValue(r, data.getFirstName().getValue());
    getLastNameColumn().setValue(r, data.getLastName().getValue());
  }
}



4a/ Change the type of AbstractSelectedPersonDetailBox to AbstractSelectedGroupBox<PersonBoxData>

We need to change the type of AbstractSelectedPersonDetailBox: instead of AbstractGroupBox set the type to AbstractSelectedGroupBox<PersonBoxData>

In AbstractSelectedPersonDetailBox you need to implement createEmptyBoxData(). It will be used by the framework to clear the selection in the detail box and for new rows:
@Override
public PersonBoxData createEmptyBoxData() {
  PersonBoxData boxData = new PersonBoxData();
  boxData.getFirstName().setValue(null);
  boxData.getLastName().setValue(null);
  boxData.getComments().setValue(null);
  return boxData;
}


Notice that you need to set the value to null (or at least setValueSet() with true as parameter). It is possible to use a Utility function to do so on each fieldData instead of having to call them individually.

In SelectedPersonDetailBox in the form you need to implement provideColumn to link the group box with the column.
@Override
public AbstractDetailBoxColumn<PersonBoxData> provideColumn() {
  return getPersonTableField().getTable().getContentColumn();
}

NB: FormDataClientUtility is the new name of FormDataUtility2 attached in this forum thread.


4b/ Change the type of the content Column to AbstractDetailBoxColumn<PersonBoxData>

Instead of AbstractContentColumn the ContentColumn needs to be from type AbstractDetailBoxColumn<PersonBoxData>.

To link the column with the group box you need to implement provideGroupBox():
@Override
public AbstractSelectedGroupBox<PersonBoxData> provideGroupBox() {
  return getSelectedPersonDetailBox();
}



4c/ Change the type of the Table in the TableField

Instead of AbstractExtensibleTable the Table in the PersonTableField needs tob e from type AbstractTableWithDetailBox. This table will add the new and delete menu and handle the import of the data in the detail GroupBox.

You need to implement provideColumns that need to return the list of the AbstractDetailBoxColumn in the table. These columns will be notified.
@Override
protected List<? extends AbstractDetailBoxColumn<?>> provideColumns() {
  return Collections.singletonList(getTable().getContentColumn());
}



4d/ Change the type of the TableField

In order for the Step 3 to work we need to work with bean based table data.

In the step 1 if your table field has the type AbstractTableField (default) change this to AbstractTableWithDetailBoxField. It contains the appropriate @FormData annotation to use bean based table data.


5/ Advanced configuration:

In AbstractSelectedPersonDetailBox you can implement:

* execStartGroupBoxEdit that will be called when a row is selected and the details data have been imported:

@Override
public void execStartGroupBoxEdit() {
  getFirstNameField().requestFocus();
}


* execUpdateGroupBoxFields: where you can define your own logic to enable or disable the fields. For example:
@Override
public void execUpdateGroupBoxFields(boolean isEditing) {
  getFirstNameField().setEnabled(isEditing);
  getFirstNameField().setMandatory(isEditing);
  
  getLastNameField().setEnabled(isEditing);
  getLastNameField().setMandatory(isEditing);

  getCommentsField().setEnabled(isEditing);
}

NB: you need to have also validation rules on the table. Having them on the field is not enough, because the user can leave the edit mode and the form will be valid even if the values in the different rows are not set.


A/ Appendix: server implementation

I recommend to test step by step your form (between each step). Here is how the server method can looks like at the end:
@Override
public MyMasterDetailFormData load(MyMasterDetailFormData formData) {
  addPersonRow(formData, "Bob", "Johnson", "Lorem ipsum");
  addPersonRow(formData, "Alan", "Smith", "");
  return formData;
}

private void addPersonRow(MyMasterDetailFormData formData, String firstName, String lastName, String comments) {
  PersonBoxData personBoxData = new PersonBoxData();
  personBoxData.getFirstName().setValue(firstName);
  personBoxData.getLastName().setValue(lastName);
  personBoxData.getComments().setValue(comments);

  PersonTableRowData row = formData.getPersonTable().addRow();
  row.setContent(personBoxData);
}


Feel free to ask questions.

[Updated on: Wed, 16 April 2014 03:05]

Report message to a moderator

Previous Topic:problem with AbstractFileChooserField
Next Topic:Logout problem SCOUT+RAP
Goto Forum:
  


Current Time: Fri Apr 18 21:54:25 EDT 2014

Powered by FUDForum. Page generated in 0.01707 seconds