Hi,
I need to save the current form into database without form reload.
In the main form with 2 sub forms called in as partial pages at onload of the main form. The form data is stored as one xml, and I created DB stored procedure to insert or update the xml into a column. It all works fine when saveNewForm action occurs for the main form and NewFormDataReceived controller of the main form takes the form data xml and call the SP to stored it to DB.
formtest: main form
formtest_sub1: sub form #1
formtest_sub2: sub form #2
commonutil: common utility project with controllers
Now, I am trying to implement a controller in a separate project (common utility prorojct) to have a controller that has this SQL rule to call the SP, then call this controller (via ajax call on a button click) from the main form in order to perform the data save without form submission. In order to implement the controller, I tried to use partial page and stand alone controller. In both cases, the controller doesn't get the form data in hierarchical structure. They are all under "control" element as unbound elements.
Is there any way to send the proper data xml under /eForm/Data/FORM_DATA/DOCUMENT element when I call the controller in the common project from the main project?
I need to save the current form into database without form reload.
In the main form with 2 sub forms called in as partial pages at onload of the main form. The form data is stored as one xml, and I created DB stored procedure to insert or update the xml into a column. It all works fine when saveNewForm action occurs for the main form and NewFormDataReceived controller of the main form takes the form data xml and call the SP to stored it to DB.
formtest: main form
formtest_sub1: sub form #1
formtest_sub2: sub form #2
commonutil: common utility project with controllers
<eForm xmlns="http://www.hyfinity.com/mvc" xmlns:mvc="http://www.hyfinity.com/mvc">
<Control>
<action />
<Page />
<Controller />
</Control>
<Data>
<formData />
<FORM_DATA xmlns="">
<ID />
<DOCUMENT>
<NAME />
<GENDER />
<DOB />
<WANT_EMAIL />
<Address>
<Street />
<City />
<State />
<Zip />
</Address>
<SUB1>
<SUB_1_TEXT_1 />
<SUB_1_TEXT_2 />
</SUB1>
<SUB2>
<SUB_2_TEXT_1 />
<SUB_2_TEXT_2 />
</SUB2>
</DOCUMENT>
</FORM_DATA>
Now, I am trying to implement a controller in a separate project (common utility prorojct) to have a controller that has this SQL rule to call the SP, then call this controller (via ajax call on a button click) from the main form in order to perform the data save without form submission. In order to implement the controller, I tried to use partial page and stand alone controller. In both cases, the controller doesn't get the form data in hierarchical structure. They are all under "control" element as unbound elements.
<eForm xmlns="http://www.hyfinity.com/mvc" xmlns:mvc="http://www.hyfinity.com/mvc">
<Control>
<NAME>My tester</NAME>
<WANT_EMAIL>false</WANT_EMAIL>
<DOB>2017-01-03</DOB>
<GENDER>M</GENDER>
<SUB_1_TEXT_1>1</SUB_1_TEXT_1>
<SUB_1_TEXT_2>1234</SUB_1_TEXT_2>
<SUB_2_TEXT_1>12</SUB_2_TEXT_1>
<SUB_2_TEXT_2>12345</SUB_2_TEXT_2>
<Page>PartialSave.xsl</Page>
<Controller>mvc-formtest_sub1-PartialSavePP-Controller</Controller>
<action>savePartial</action>
<mvc:CurrentDate>2017-02-01T11:49:53-05:00</mvc:CurrentDate>
</Control>
<Data>
<bizflow_details xmlns="" xmlns:fo="http://www.w3.org/1999/XSL/Format">
...
</bizflow_details>
<WorkitemContext xmlns="">
...
</WorkitemContext>
</Data>
</eForm>
Is there any way to send the proper data xml under /eForm/Data/FORM_DATA/DOCUMENT element when I call the controller in the common project from the main project?
RE: ajax call to controller in other project for db update
Configuring the bindings for calls across multiple projects is unfortunately an area where things can become complicated.
When a form is submitted, either as a standard form submit, or an ajax submission, WebMaker uses binding information to determine how the submitted information is structured. As you will have seen, on the Bindings tab you can configure different bindings for each action going from the page. Unfortunately this only shows actions that it is aware of (from the Application Map), so unfortunately the action that you are calling in the commonutil project will not appear here for the bindings to be configured.
Generally, if you make sure that the binding structure and XPaths specified for each available action are the same (eg by using the 'Set bindings and structure based on another action?' option under 'Advanced Binding Mode Options'), then these settings will apply to all actions, including any calls to other projects.
Unfortunately, when a page has calls to partial pages (that are known about), the structure of the submitted data has to be action specific, as these partial pages can have their own action binding structures that need to be kept distinct.
Given all of this, I think the best solution for you will be to use an Inter Project Proxy controller in the main project. The basic steps to get this working are:
(If needed, you can find the exact value from the Debugger logs, or by accessing the Node Details information for the Controller from the Design - Advanced Project Settings screen.)[/*]
Hopefully this will let you achieve what you are trying to do.
Please let me know if you have any issues, or need any more explanation on this.
Regards,
Gerard
RE: ajax call to controller in other project for db update
Thank you for suggestion. I did the following according to your suggestion.
In the main form:
1. Added PartialSaveCtrl_Proxy controller.
2. Connected action from NewForm to PartialSaveCtrl_Proxy and named savePartialProxy.
3. In NewForm page, added binding for savePartialProxy action. Note, this page has 2 partial pages (_sub1, _sub2), which are not available for binding. So, I specified bindings for the fields that exist on the main form only. Perhaps, I should use "Set bindings and structure based on another action" to use the one for saveNewForm action?
4. Added a new button btnPartialSaveProxy and set ajax action to the controller to call savePartialProxy action. I thought of form submission action but I wanted to avoid page reload so I was hesitant. Perhaps, I should have used form submission action? Otherwise, should I have created custom js function in some way (suggestion?) and call it for the button?
5. Under Test Setting menu, I set the Agent Type for PartialSaveCtrl_Proxy controller to "Inter Project Proxy", and set the target agent to "mvc-formtest_sub1-PartialSaveCtrl-Controller"
6. The sub project (formtest_sub1) has PartialSaveCtrl controller whose action name is savePartialCtrl.
7. After initiating the test, clicked the button and got error.
mvc-formtest_sub1-PartialSaveCtrl(Agent Id: mvc-formtest_sub1-PartialSaveCtrl Timestamp: 02-02-2017 at 11:37:44.513)
java.io.FileNotFoundException: blueprint.xml (The system cannot find the file specified)
Any suggestion?
I appreciate your help.
RE: ajax call to controller in other project for db update
That error generally indicates that the second project cannot be found in the runtime environment.
Can you check that both projects have the same directory name set in the Test Settings - Location Details window?
Also, if you look at the 'Projects in this Environment' section, are both projects listed for each project?
If this all looks correct, I would then try doing a Run Test of both projects again (do the sub project first) and see what happens.
Let me know if you are still having issues and we can investigate further.
Regards,
Gerard
RE: ajax call to controller in other project for db update
The runtime directories are there for all projects as siblings.
I did not change settings from default, so, yes, the Location Details window reflects the project name.
Projects in this Environment section of Test Setting menu has only one entry. Does this reflect the setting done in the same section under Publish menu?
Again, I did not change any setting in "Projects in this Environment" section of Publish menu. So, each project had only itself and not the other. I can still call the actions in other project without adding them in the "Projects in this Environment" section of Publish menu. It's just the parameter is not passed down in hierarchy as mapped that way. Nonetheless, adding other projects in the "Projects in this Environment" section of Publish menu doesn't change the same section under Test Setting menu.
Anyway, I added all related projects in "Projects in this Environment" section of Publish menu and tested, but ended up in the same FileNotFoundException (blueprint.xml). A difference that I noticed was that the proxy controller did get called and it has xml data mapped for the fields from the main form, but the fields from the partial page still appeared to be unbound and placed under "Control" element.
<eForm xmlns="http://www.hyfinity.com/mvc" xmlns:mvc="http://www.hyfinity.com/mvc"> <Control> <is_script_enabled>true</is_script_enabled> <SUB_1_TEXT_1>1aaa</SUB_1_TEXT_1> <Page>NewForm.xsl</Page> <Controller>mvc-formtest-PartialSaveCtrl_Proxy-Controller</Controller> <action>savePartialProxy</action> <mvc:CurrentDate>2017-02-02T12:55:59-05:00</mvc:CurrentDate> </Control> <Data> <formData> <NAME/> <GENDER/> <DOB/> <WANT_EMAIL/> </formData> <FORM_DATA xmlns=""> <ID/> <DOCUMENT> <NAME>Rafael Nadal 22aa</NAME> <GENDER>M</GENDER> <DOB>2017-01-03</DOB> <WANT_EMAIL>false</WANT_EMAIL> <Address> <Street>123 Mathias Road</Street> <City>Alexandria</City> <State>VA</State> <Zip>22004</Zip> </Address> <SUB1> <SUB_1_TEXT_1/> <SUB_1_TEXT_2>1234</SUB_1_TEXT_2> </SUB1> <SUB2> <SUB_2_TEXT_1>12</SUB_2_TEXT_1> <SUB_2_TEXT_2>12345</SUB_2_TEXT_2> </SUB2> </DOCUMENT> </FORM_DATA> <WorkitemContext xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"> ... </WorkitemContext> </Data> </eForm>
Notice above,
a field existing in main form:
/eForm/Data/FORM_DATA/DOCUMENT/NAME
a field existing in sub1 partial page:
/eForm/Control/SUB_1_TEXT_1
, which needs to be populated under
/eForm/Data/FORM_DATA/DOCUMENT/SUB1/SUB_1_TEXT_1
The SUB_1_TEXT_1 under Control element has the updated value whereas the one under Data element is empty.
So, two issues here.
1. FileNotFoundException for blueprint.xml
2. Data from partial page losing xml hierarchy and being placed under Control.
Any thoughts?
RE: ajax call to controller in other project for db update
Sorry if I have confused you a bit. I think it might be worth covering the differences between 'test' and 'publish'.
The basic WebMaker approach is Design - Test - Publish.
When you use the 'Run Test' option in the studio the project is placed into a runnable form on the local machine, in the runtime directory that you have seen for easy testing. Publication instead packages up the project(s) for deploying to a separate server.
The theory being that you test the project locally until it is working, and then publish a version to deploy to a test/QA/Live server.
Although in reality there can be reasons why testing locally is not really possible, and instead publication ends up being used most of the time in these scenarios.
What approach are you using to test your application at the moment?
The steps needed to connect the projects together are different between local testing and publication, and any changes made in publication settings for example will not affect the local testing performed with the 'Run Test' button.
For local testing, to connect multiple projects together you need to ensure that each project is using exactly the same value for the directory name in the Test Settings window. So in your case you will need to change this value for at least your two sub projects.
Once this has been done, and 'Run Test' performed for all three projects, you should find that the 'Projects in this Environment' section of Test Settings now lists all three projects.
Until this is the case, you wont be able to get the projects working together in the local test environment, ie when using 'Run Test' to run the application.
Alternatively, if you are using the publication process to create the application you are testing, then adding all the projects to the publication environment like you have done is all that is needed.
With regards to the second issue on the partial page field binding, where do you have these partial pages located?
Are they in the same project as the main page and connected to it? If so, you should be able to configure the submission bindings for these fields for the new savePartialProxy action in the normal way.
If these are contained in the sub projects, then it will depend on what other submission bindings you have defined for them. As long as you make sure that all the submission binding XPaths for each control are the same for every action listed, then these should apply when being submitted to savePartialProxy.
I hope this is helpful.
If you are still having trouble getting this working, I am happy to look at your projects in more detail if you are able to provide exports of them.
If you feel this would be useful you can either upload them to the forum or email them to support@hyfinity.com if you need to keep them private.
Regards,
Gerard
RE: ajax call to controller in other project for db update
Thank you for help. I finally got it working. It is interesting solution, but quite laborious. The motivation of this setting was to break up logic in multiple projects so that multiple developers can work simultaneously.
I created whole new set of practice projects for proof of concept of calling external controller to save data partially. Here's what I did.
1. Data xml to be used for the whole combined data.
<eForm> <Control> ... </Control> <Data> <formData> ... </formData> <FORM_DATA xmlns=""> <ID /> <DOCUMENT> <NAME /> <DOB /> <GENDER /> <WANT_NOTIF /> <SUB1> <SUB_1_TEXT_1 /> <SUB_1_TEXT_2 /> </SUB1> <SUB2> <SUB_2_TEXT_1 /> <SUB_2_TEXT_2 /> </SUB2> </DOCUMENT> </FORM_DATA> </Data> </eForm>
2. Created 4 separate projects.
The main page (in particlsave_main project) has the following fields in NewForm page. The data mapping for all actions as done as the following.
Binding Actions:
PrepareForm controller has one SQL rule to load the xml data (or it can be done by inserting hard-coded test data xml fragment).
The sub1 partial page (in particlsave_sub1 project) has the following fields for all actions.
Binding Actions:
Partial page controller has one SQL rule to load the xml data (or it can be done by inserting hard-coded test data xml fragment) as the same way as the main page.
The second sub form project (particlsave_sub2) is created the same way as the first sub form.
The util project has one partial page (Util), whose controller has the same name, which has a SQL rule to update database with the FORM_DATA/DOCUMENT as xml data. The partial page action name = savePartialRemote, whose action binding has the full FORM_DATA xml structure.
3. Special setting for main project.
3.1. Added a controller for proxy (PartialSave_Proxy) with action (savePartialProxy) from NewForm page.
3.2. In Test Setting menu > Agent Typs section, change the agent type for the proxy controller.
Inter Project Proxy: mvc-particlsave_util-Util-Controller
3.3. In Test Setting menu > Location Details section, change the directory name for this project for test environment to: partialsave_test
3.4. Data binding for the proxy controller action in NewForm page.
savePartialProxy (checked: Set bindings and structure based on another action = saveNewForm)
3.5. Add new button to NewForm page to invoke the proxy controller.
id = btnPartialSaveProxy
Events: onclick
=>
condition = Form Submission
action = savePartialProxy
4. Special setting for utility project
In Test Setting menu > Location Details section, change the directory name for this project for test environment to: partialsave_test
This matches exactly the change done for the main project's Test Setting > Location Details.
After all settings are done, I ran "Run Test" for all 4 projects, which created runtime folders under WebMaker runtime tomcat directory.
WebMaker\runtime\tomcat-runtime\webapps\partialsave_sub1
WebMaker\runtime\tomcat-runtime\webapps\partialsave_sub2
WebMaker\runtime\tomcat-runtime\webapps\partialsave_test
Then, from the main project, I started testing, and verified the xml data was transferred from the main project to utility project as expected in the debugger.
I assume in the published environment, we will see 4 runtime directories with slight different structure, but it should work the same way.
publishedruntime\tomcat7\webapps\bizflowwebmaker\partialsave_main
publishedruntime\tomcat7\webapps\bizflowwebmaker\partialsave_sub1
publishedruntime\tomcat7\webapps\bizflowwebmaker\partialsave_sub2
publishedruntime\tomcat7\webapps\bizflowwebmaker\partialsave_util
RE: ajax call to controller in other project for db update
I'm glad you have managed to get it working.
I agree it can take a bit of setup initially, but hopefully you will now find it easier going forward.
I did want to clarify your last couple of points though.
When you are using multiple projects to create a single application this will only use one directory in the runtime server.
With the local testing option, you set each of your 4 projects to the same directory name in Test Settings, and it is then this directory that will be use to run the application. (partialsave_test in your case)
With regards to publishing to BizFlow, you will only get one directory under the bizflowwebmaker location, which contains all the included projects. The name of this directory will be the value set for 'application.name' in Publish Settings, or the name of the project against which the publication environment is configured if this is not set.
Please let me know if you have any further questions.
Regards,
Gerard