I have a table EmpCampaigns that is joined to a Creatives table in a many to many relationship via CUBA studio.
The join table is called EmpCampaignCreatives
We would like to reuse this table throughout the application, so we’ve put in a frame that we would like to add whenever it’s needed. So far this is working well.
The issue that I’m having is that when I try to add creatives to the EmpCampaign they are only saved under two conditions:
- The parent model EmpCampaign is new
- I explicitly edit a field on the parent object.
A few things to note:
The UI of our app is a pretty custom in that we are not using the standard Tab panels that CUBA provides and instead using “standalone” windows. This is why we have to do some of this stuff programmatically.
If I create a new screen using standard CUBA UI that includes the table directly instead from within a frame it works as expected.
Here is the method that attempts to do some filtering on the associated objects before saving.
This addBeforeCommitListener only fires when the EmpCampaign instance is new or directly modified.
public class EmpCampaignEdit extends AbstractEditor<EmpCampaign>
...
private void setupPersistenceOnWindowClose() {
getDsContext().addBeforeCommitListener((event) -> {
//These are the creatives that have been added to the table
Collection<Creative> creativesToAssociate = creativesDs.getItems();
// filter out dupes
creativesToAssociate
.stream()
.filter(c -> !existingCreatives.contains(c))
.forEach(existingCreatives::add);
//this works if the
getItem().setCreatives(existingCreatives);
});
}
...
}
Here is the controller XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
caption="msg://editorCaption"
class="com.yieldmo.ymcuba.web.empcampaign.EmpCampaignEdit"
datasource="empCampaignDs"
focusComponent="fieldGroup"
messagesPack="com.yieldmo.ymcuba.web.empcampaign">
<dsContext>
<datasource id="empCampaignDs"
class="com.yieldmo.ymcuba.entity.emp.EmpCampaign"
view="empCampaign-view">
<collectionDatasource id="creativesDs"
property="creatives"/>
</datasource>
</dsContext>
<actions>
<action id="windowCommit"
caption="Ok"
invoke="onCommit"/>
<action id="windowClose"
caption="Cancel"
invoke="onClose"/>
</actions>
<dialogMode height="600"
width="800"/>
<layout expand="windowActions"
spacing="true">
<fieldGroup id="fieldGroup"
datasource="empCampaignDs">
<column width="250px">
<field property="name"/>
<field property="targetKpi"/>
</column>
</fieldGroup>
<button id="addCreativesButton"
caption="Add Creative(s)"/>
<frame id="creativesLookupTable"
screen="cmCreativesLookupTable"/> //FRAME holding table
<frame id="windowActions"
screen="editWindowActions"/>
</layout>
</window>