Hi guys.
I'm using spring-framework-3.2.0.RELEASE, spring-webflow-2.3.1.RELEASE with Spring Security, Thymleaf template engine + Tiles2 support.
I have sub-flow inside a 'main execution flow' and I'm trying to create 'view/add/edit' functionality in sub-flow for form bean and entity behind it.
The problem I'm facing is following.
I can render entity from formBean on page, I modify DOM tree by JS code and then changed data is posted to webflow. When I try to save that 'updated' formBean after 'POST' made from page, I'm getting 'previous' data rather then data 'POSTED' by browser.
I have following sub-flow definition:
Here is a simplified code for clarity.Code:<input name="venueForm" required="false" type="com.web.form.venue.FormBeanVenueField" /> <on-start> <evaluate expression="venuePlaceController.initializeForm()" result="flowScope.venueForm"/> </on-start> <view-state id="showMap" view="event/registerEvent/selectVenue/showMap" model="venueForm"> <on-render> <evaluate expression=............... /> </on-render> <transition on="create" to="createVenue"/> <transition on="select" to="endVenueFieldOk"/> <transition on="edit" to="editVenue"/> </view-state> <view-state id="createVenue" view="event/registerEvent/selectVenue/addVenue" model="venueForm"> <on-render> </on-render> <transition on="cancel" to="showMap" validate="false"/> <transition on="save" to="showMap"> <evaluate expression="venuePlaceController.saveVenuePlace( externalContext, flowScope.venueForm, messageContext)"/> </transition> </view-state> <view-state id="editVenue" view="event/registerEvent/selectVenue/addVenue" model="venueForm"> <on-entry> <evaluate expression="venuePlaceController.initializeFormByVenueId(flowScope.venueForm)" result="flowScope.venueForm"/> </on-entry> <on-render> ............ </on-render> <transition on="save" to="showMap"> <evaluate expression="venuePlaceController.saveVenuePlace( externalContext, venueForm, messageContext)"/> </transition> </view-state> ..............
HTML code is written by thymeleaf library syntax. Here is simplified: event/registerEvent/selectVenue/addVenue.htmlCode:public class FormBeanVenueField implements Serializable { private String venueId; // selected venue Id private List<String> venueFieldNames = new ArrayList<>(0); ............ // the rest is skipped } @Controller public class VenuePlaceController { public FormBeanVenueField initializeForm() { FormBeanVenueField venueForm = new FormBeanVenueField(); } public FormBeanVenueField initializeFormByVenueId(FormBeanVenueField venueForm) { if (venueForm != null && venueForm.getVenueId() != null && !venueForm.getVenueId().isEmpty()) { // get Entity by Id from database and create form bean venueForm = new FormBeanVenueField(entity); } return venueForm; } public org.springframework.webflow.execution.Event saveVenuePlace( ExternalContext externalContext, @Valid FormBeanVenueField formBean, MessageContext messageContext) { // make form bean validations and return result if (formBean.venueFieldNames.size() <= 0) { // break point HERE to view received data ....... // generate error MessageBuilder errorMessageBuilder = new MessageBuilder().error(); messageContext.addMessage(errorMessageBuilder.build()); return new EventFactorySupport().error(this); } ........ // when all is ok, create Entity from 'form bean' data and save entity to database return new EventFactorySupport().success(this); } }
I use that page for 'create' and 'edit' cases.
Code:<form method="post" th:action="${flowExecutionUrl}" action='' th:object="${venueForm}" id="form"> ............ <input type="text" name="venueFieldNames[0]" value="0" /> <input type="text" name="venueFieldNames[1]" value="1" /> <input type="text" name="venueFieldNames[2]" value="2" /> <button id="cancelBtn" type="submit" name="_eventId_cancel" >Cancel</button> <button id="saveBtn" type="submit" name="_eventId_save" >Save</button> </form>
1. The state <view-state id="createVenue".. works fine. I can render a 'empty' page. Add several 'input controls' to DOM model by JS code and then submit all data by 'onclick' handler on 'Save'. The data comes to saveVenuePlace(.......) method and save to DB.
2. When I try <view-state id="editVenue" .... state I don't get correct data which actually submitted by page AFTER data editing and DOM model modifications.
Say, I have several 'input' controls rendered by <view-state id="editVenue" .... state on page initially.
Then I modify DOM model by JS code and POST changed data, say only ONE input value, to state. I can see only ONE input data (venueFieldNames[1]=1) posted to my 'editVenue' state.
The problem I have... I see ALL three input data values (instead on one) on break point inside method :
public org.springframework.webflow.execution.Event saveVenuePlace(.......) {
if (formBean.venueFieldNames.size() <= 0) {
.......
}
So it looks like... 1) data posted by page is not bind to form bean, 2) binded form bean values are overwritten by webflow and I get 'initial data' instead of 'updated data' from page.
Most probably, there is something I don't know about webflow. Is it possible to make such functionality ? How better to solve that issue?


Reply With Quote


