TokenField in table


I have a Many-TO-Many relation between Payment and Transaction.
In Payment I have a tokenFiled which select Transactions.
Under tokenField I have a table which shows selected Transactions.

The problem is that I have the same information twice (tokenField and table).
My goal is to add a new column to the table and put the selected (x) tokenField transaction list with this column.


 <datasource id="paymentDs"
            <collectionDatasource id="transactionsDs"

 <tokenList id="tokenList"
            <lookup lookup="true"
  <table id="transactionsTable"
                <column id="a"/>
                <column id="b"/>
                <column id="c"/>
            <rows datasource="transactionsDs"/>

I added in Payment Controller a new column but I don’t know how to connect tokenField to this column.

transactionsTable.addGeneratedColumn("token", r -> {

            FlowBoxLayout glist = componentsFactory.createComponent(FlowBoxLayout.class);

            return glist;
        } );

Please advise.

I’ve tried this but I have an error:

private TokenList tokenList;
transactionsTable.addGeneratedColumn(“token”, r -> {

             return tokenList.getValue();
    } );

Basically I should return instance name…


Please, could you clarify the main goal? As I understand, you want to have a dropdown list with transactions and when a transaction is selected add it to the table.

Exactly. Which controller is better for many-to-many relation? Maybe tokenField is not the right option (because the infos is displayed twice).

You can use the default edit template generated by Studio for your payment-with-transaction view. It is a simple table with “Add” and “Remove” actions:

<table id="transactionsTable" width="100%" height="200px">
        <action id="add"/>
        <action id="remove"/>
        <column id="column1"/>
        <column id="column2"/>
    <rows datasource="transactionsDs"/>
        <button action="transactionsTable.add"/>
        <button action="transactionsTable.remove"/>

If you want to do with dropdown list you can do the following:

  1. Add CollectionDatasource with your Transaction class. It will be used as options for LookupField
       <collectionDatasource id="allTransactionsDs"
            <![CDATA[select e from demo$Transaction e]]>
  1. Add LookupField:
<lookupField id="transactionOptionsField"
  1. In the Payment Edit controller add:
private LookupField transactionOptionsField;

private CollectionDatasource<Transaction, UUID> transactionsDs;

private ComponentsFactory factory;

public void init(Map<String, Object> params) {
    transactionOptionsField.addValueChangeListener(event -> {
        if (event.getValue() != null) {
            Transaction transaction = (Transaction) event.getValue();
            if (!transactionsDs.containsItem(transaction.getId())) {

See the attached demo project: (84.1 KB)

Thank you very much, Roman.
I wonder why PickerField controller doesn’t have optionsDatasource feature?

How can I start with an empty table?

Please, could you clarify with more details what problem do you have?

If I remove the query ![CDATA[select e from demo$Transaction e]], the table is still populated.
It’s normal?

“Add” action should automatically add items to the datasource. You can see an example in the above-attached project, just try to create some Transaction instance.
If you still get an issue, attach screen layout and controller or simple demo project where it is reproduced.

Yes, it is the right behavior when query is not defined in a datasource. But it is not recommended to remove such queries, because some functionality will not work properly (e.g. filter).

1 Like

Basically the information goes the first time in datasources and then in database?