Cuba 7 multiple selections

Hello,

I need a component in my Chart screen in order to select multiple Organization(s) (entity) browse and show them as Bar Chart.
New chart screen is made in Cuba 7 but Organization is made in Cuba 6.
Which component should I use for multiple selections?
I ve tried with tokenList I set lookupScreen (Organization.browse), multiselect checked, but doesn’t work.
The problem is that I cannot set optionsContainer=“organizationsDs” because I have the next error:
IllegalArgumentException: Container ‘organizationsDs’ not found
With a Pickerfield I think I need for a table…

Generally speaking is there any possibility to adapt Cuba7 components proprieties to Cuba 6 (datasaources) or I need to redo Cuba 6 screens?
Please advise.

Hello @neutrino

All components are able to work both with containers and datasources. The limitation is to use only containers for CUBA 7 screens and datasources for CUBA 6 screens.

The TokenList component seems to be the most suitable in your case.

Please share screen XML descriptor if the problem will not be solved.

Regards,
Daniil

I have the next error: RuntimeException: Unable to determine entity class to open lookup
Where should I put datasource because there is no such option.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
        caption="msg://caption"
        messagesPack="com.crm.web.screens">
    <layout>
        <vbox id="chartContainer"/>
        <tokenList id="tokenList">
            <lookup lookupScreen="crm$Organization.browse" multiselect="true" lookup="true" />

        </tokenList>
    </layout>
</window>

You should define datasource or container for TokenList to be able to open lookup screen:

<tokenList dataContainer="organizationsDc"
        ...>
    <lookup ... />
</tokenList>

I told you the (Organization) screen is made in Cuba 6 so I don’t have organizationsDc. Only OrganizationsDs.

It was just an example. You can set a datasource in the same way:

<tokenList datasource="organizationsDs"
        ...>
    <lookup ... />
</tokenList>

I have a null pointer exception when I try to open the screen.

lang.NullPointerException at com.haulmont.cuba.gui.xml.layout.loaders.TokenListLoader.loadDatasource(TokenListLoader.java:247)
at com.haulmont.cuba.gui.xml.layout.loaders.TokenListLoader.loadTokenListItems(TokenListLoader.java:89)

<layout>
        <vbox id="chartContainer" />
        <tokenList id="tokenList" datasource="organizationsDs">
            <lookup lookupScreen="crm$Organization.browse" multiselect="true" lookup="true" />

        </tokenList>

    </layout>

On the other hand the organizationsDs is underline with the next message:
‘Datasources’ works only in legacy cuba screens. In new Cuba screens please use data containers.

On the other hand the organizationsDs is underline with the next message:
‘Datasources’ works only in legacy cuba screens. In new Cuba screens please use data containers.

It means that the screen is based on CUBA 7.

I suppose that NPE is thrown because there is no organisationsDs defined in the screen.

OK. I try to explain in details.

The tokenList is placed into a Cuba 7 screen. I don’t have any datasource here (neither Cuba 7 nor Cuba 6). Let say it’s a blank screen.
The browse screen that I want to access is made (imported from) in Cuba 6.

Now, back to my issue, is it possible to use tokenList in this way?

You can use TokenList without datasource or container, but lookup functionality will not be available

And what could be the solution? To redo the screen where is placed tokenList in Cuba 6?
Can you give me an example?

You can use new API - lookup screen provider:

@Inject
protected TokenList tokenList;
@Inject
private ScreenBuilders screenBuilders;

@Subscribe
private void onInit(InitEvent event) {
    tokenList.setLookupProvider(() ->
            screenBuilders.lookup(Employee.class, this)
                    .withScreenId("sample_Employee.browse")
                    .withLaunchMode(OpenMode.DIALOG)
                    .build());
}
1 Like

Thank you! It works.
However I saw that after loguout/login the selected (Organization) records disappear.

Three question pls:

  1. Where are keep the data in TokenList (because I don’t set any datasource)?
  2. Is there any possibility to make the selection persistent (is mandatory to define a new (Chart) entity in relation many(one)-to-many with Organization)?
  3. How can I have access to Organization.browse tokenlist selection attributes ((let say: “name”) - because I need to put Organization’s attributes into a chart)?

Where are keep the data in TokenList (because I don’t set any datasource)?

Not sure that understand you correctly. Could you clarify the question?

Is there any possibility to make the selection persistent

Create a new entity and just save selection.

How can I have access to Organization.browse tokenlist selection attributes

You can get a value of TokenList via tokenList.getValue() that will return current selection, iterate over collection and get required fields.

Ok, but I suppose this tokenList.getValue() has to stay under some specific handler (or listener) in order to get the selected Organizations names. Unfortunately I don’t have neither datasource nor table. Could you give me an example pls?

   Organization o;
   tokenList.getValue(o.getName());

As I said the TokenList component returns a collection:

Collection<Organisation> selectedOrgs = tokenList.getValue();

for (Organization org : selectedOrgs) {
    String name = org.getName();
}

Unfortunately I get this error:

web/screens/ChartScreen.java:59: error: incompatible types: Object cannot be converted to Collection<Organization>
        Collection<Organization> selectedOrgs = tokenList.getValue();

If I inject instead of

@Inject
    protected TokenList  tokenList;
@Inject
    protected TokenList<Organization> tokenList;

when I open Chartscreen I have null pointer exception

If I use this solution

  Collection<Organization> selectedOrgs = tokenList.getValue();

      if(selectedOrgs !=null) {

          for (Organization org : selectedOrgs) {
              String name = org.getName();
              log.info("ssssssssssssssssssssssssssssssssssssssss...."+ name);
          }

I get rid of null pointer exception but the program doesn’t enter in for loop even I select some Organization records. So I cannot extract names.

If I use instead of onInit onBeforeClose event it works.
However I need these info (name) when the screen is open not when I close the screen.
I could add a button with event.preventWindowClose() onClick but I don’t know if this is the right solution.

Also could be used tokenList.addValueChangeListener…

Yes, you should use generics while injecting component to make things work.

Could you clarify what NPE is thrown?