Skip to content

Commit 407f12a

Browse files
committed
PRESIDECMS-3017 Update to render and handle form page submit.
1 parent 204fb6f commit 407f12a

File tree

6 files changed

+143
-39
lines changed

6 files changed

+143
-39
lines changed

system/handlers/formbuilder/Core.cfc

+41-7
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,34 @@ component {
4646
setNextEvent( url=cgi.http_referer, persistStruct=persistData );
4747
}
4848

49-
var validationResult = formBuilderService.saveFormSubmission(
50-
formId = formId
51-
, requestData = submission
52-
, instanceId = ( rc.instanceId ?: "" )
53-
, instanceSite = ( rc.instanceSite ?: "" )
54-
, instanceUrl = ( rc.instanceUrl ?: "" )
55-
);
49+
var validationResult = validationEngine.newValidationResult();
50+
51+
if ( submission.formPageNumber ?: 0 ) {
52+
var validationResult = formBuilderValidationService.validateFormSubmission(
53+
formItems = formBuilderService.getFormItems( id=formId, pageNumber=submission.formPageNumber )
54+
, submissionData = submission
55+
);
56+
57+
if ( validationResult.validated() ) {
58+
var savedData = formBuilderService.getTempStoredSubmission( formId );
59+
60+
submission.formPageNumber += submission._formNextPage ?: 1;
61+
62+
StructAppend( savedData, submission );
63+
64+
formBuilderService.setTempStoredSubmission( formId, savedData );
65+
66+
setNextEvent( url=cgi.http_referer );
67+
}
68+
} else {
69+
validationResult = formBuilderService.saveFormSubmission(
70+
formId = formId
71+
, requestData = submission
72+
, instanceId = ( rc.instanceId ?: "" )
73+
, instanceSite = ( rc.instanceSite ?: "" )
74+
, instanceUrl = ( rc.instanceUrl ?: "" )
75+
);
76+
}
5677

5778
if ( event.isAjax() ) {
5879
if ( validationResult.validated() ) {
@@ -93,11 +114,24 @@ component {
93114
);
94115
}
95116

117+
args.renderedButtons = renderViewlet( event="formbuilder.core.formButtons", args=args );
118+
96119
event.include( assetId="/js/frontend/formbuilder/" );
97120

98121
return renderView( view="/formbuilder/layouts/core/formLayout", args=args );
99122
}
100123

124+
private string function formButtons( event, rc, prc, args={} ) {
125+
var formPageNumber = args.formPageNumber ?: 0;
126+
var formPagesTotal = args.formPagesTotal ?: 0;
127+
128+
args.isFormPage = formPageNumber > 0;
129+
args.isFirstPage = formPageNumber == 1;
130+
args.isLastPage = formPagesTotal == formPagesTotal;
131+
132+
return renderView( view="/formbuilder/layouts/core/formButtons", args=args );
133+
}
134+
101135
private string function successMessage( event, rc, prc, args ) {
102136
args.successMessage = formBuilderService.getSubmissionSuccessMessage( args.formId ?: "" );
103137
args.successMessage = renderContent( renderer="richeditor", data=args.successMessage );

system/i18n/formbuilder.properties

+5-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ view.questionresponse.modal.title=View question submission
7171
spreadsheet.main.sheet.title=All data
7272
excel.download.link=Export submissions to excel
7373
74-
7574
actions.breadcrumb.title=POST actions
7675
action.picker.actions.title=Available actions
7776
empty.form.actions.notice=No actions have been configured for this form. Drag and drop available actions here to configure them.
@@ -96,4 +95,8 @@ cloneForm.page.title=Clone form
9695
cloneForm.save=Save
9796
cloned.success.message=Form has been cloned successfully.
9897
99-
task.form.delete.title=Delete form and all its data
98+
task.form.delete.title=Delete form and all its data
99+
100+
button.submit.label=Submit
101+
button.back.label=Back
102+
button.continue.label=Continue

system/services/formbuilder/FormBuilderService.cfc

+38-15
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,20 @@ component {
7676
* @autodoc true
7777
* @id.hint ID of the form item's form you wish to get
7878
*/
79-
public array function getFormItemDefaultFields( required string id ) {
79+
public array function getFormItemDefaultFields(
80+
required string id
81+
, boolean withPageNumber = false
82+
) {
8083
var fields = [ "id", "item_type", "configuration", "form" ];
84+
8185
if ( isV2Form( formid=arguments.id ) ) {
8286
ArrayAppend( fields, "question" );
8387
}
8488

89+
if ( arguments.withPageNumber ) {
90+
ArrayAppend( fields, "count( case when item_type = 'page' then 1 end) over ( order by sort_order rows between unbounded preceding and current row ) as page_number" );
91+
}
92+
8593
return fields;
8694
}
8795

@@ -92,16 +100,20 @@ component {
92100
* @id.hint ID of the form whose sections and items you wish to get
93101
* @itemTypes.hint Optional array of item types with which to filter the returned form items
94102
*/
95-
public array function getFormItems( required string id, array itemTypes=[] ) {
103+
public array function getFormItems(
104+
required string id
105+
, array itemTypes = []
106+
, numeric pageNumber = 0
107+
) {
96108
var result = [];
97109
var items = $getPresideObject( "formbuilder_formitem" ).selectData(
98-
filter = { form=arguments.id }
110+
selectFields = getFormItemDefaultFields( id=arguments.id, withPageNumber=$helpers.isTrue( arguments.pageNumber ) )
111+
, filter = { form=arguments.id }
99112
, orderBy = "sort_order"
100-
, selectFields = getFormItemDefaultFields( id=arguments.id )
101113
);
102114

103-
for( var item in items ) {
104-
if ( !itemTypes.len() || itemTypes.findNoCase( item.item_type ) ) {
115+
for ( var item in items ) {
116+
if ( ( arguments.pageNumber == 0 || arguments.pageNumber == item.page_number ) && ( !ArrayLen( itemTypes ) || ArrayFindNoCase( itemTypes, item.item_type ) ) ) {
105117
var preparedItem = {
106118
id = item.id
107119
, formId = item.form
@@ -687,13 +699,13 @@ component {
687699
* @formId.hint The ID of the form you wish to retrieve stored values for
688700
*
689701
*/
690-
public struct function getTempStoredSubmission( required string formId ) {
702+
public struct function getTempStoredSubmission( required string formId, boolean clearSubmission=false ) {
691703
var tempStorageKey = "temp_formbuilder_submission_#formId#";
692704
var submission = _getSessionStorage().getVar( tempStorageKey, StructNew() );
693705

694-
695-
_getSessionStorage().deleteVar( tempStorageKey );
696-
706+
if ( arguments.clearSubmission ) {
707+
_getSessionStorage().deleteVar( tempStorageKey );
708+
}
697709

698710
return submission;
699711
}
@@ -714,18 +726,22 @@ component {
714726
, struct configuration = {}
715727
, any validationResult = ""
716728
) {
729+
var formPersistData = $getRequestContext().getCollectionWithoutSystemVars();
730+
arguments.configuration.formPagesCount = countFormPages( formId=arguments.formId );
731+
arguments.configuration.formPageNumber = arguments.configuration.formPagesCount ? ( formPersistData.formPageNumber ?: 1 ) : 0;
732+
717733
var formConfiguration = getForm( id=arguments.formId );
718-
var items = getFormItems( id=arguments.formId );
734+
var items = getFormItems( id=arguments.formId, pageNumber=arguments.configuration.formPageNumber );
719735
var renderedItems = CreateObject( "java", "java.lang.StringBuffer" );
720736
var coreLayoutArgs = Duplicate( arguments.configuration );
721737
var coreLayoutViewlet = "formbuilder.core.formLayout";
722738
var formLayoutArgs = Duplicate( arguments.configuration );
723739
var formLayoutViewlet = _getFormBuilderRenderingService().getFormLayoutViewlet( layout=arguments.layout );
724740
var idPrefixForFields = _createIdPrefix( formId=arguments.formId );
725741

726-
for( var item in items ) {
742+
for ( var item in items ) {
727743
var config = Duplicate( item.configuration );
728-
var fieldName = config.name ?: CreateUUId();
744+
var fieldName = config.name ?: CreateUUID();
729745

730746
config.id = idPrefixForFields & fieldName;
731747

@@ -745,16 +761,16 @@ component {
745761
coreLayoutArgs.renderedItems = renderedItems.toString();
746762
coreLayoutArgs.id = idPrefixForFields;
747763
coreLayoutArgs.formItems = items;
764+
748765
for( var f in formConfiguration ) {
749766
coreLayoutArgs.configuration = f;
750767
}
751768

752-
formLayoutArgs.renderedForm = $renderViewlet(
769+
formLayoutArgs.renderedForm = $renderViewlet(
753770
event = coreLayoutViewlet
754771
, args = coreLayoutArgs
755772
);
756773

757-
758774
return $renderViewlet(
759775
event = formLayoutViewlet
760776
, args = formLayoutArgs
@@ -2163,6 +2179,13 @@ component {
21632179
);
21642180
}
21652181

2182+
public numeric function countFormPages( required string formId ) {
2183+
return $getPresideObject( "formbuilder_formitem" ).selectData(
2184+
filter = { form=arguments.formId, item_type="page" }
2185+
, recordCountOnly = true
2186+
);
2187+
}
2188+
21662189
public boolean function updateUsesGlobalQuestions() {
21672190
try {
21682191
if ( $isFeatureEnabled( "formbuilder2" ) ) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!---@feature formbuilder--->
2+
<cfscript>
3+
label = args.label ?: "";
4+
pageNumber = args.pageNumber ?: 1;
5+
pageTotal = args.pageTotal ?: 1;
6+
</cfscript>
7+
8+
<cfoutput>
9+
<cfif pageNumber eq 1>
10+
<div class="formbuilder-page">
11+
<cfelse>
12+
<div>
13+
<button type="button">Prev</button>
14+
<button type="button">Next</button>
15+
</div>
16+
</div>
17+
18+
<div class="formbuilder-page">
19+
</cfif>
20+
21+
<cfif not isEmptyString( label )>
22+
<h2 class="formbuilder-page-heading">#pageNumber# #label#</h2>
23+
</cfif>
24+
</cfoutput>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!---@feature formbuilder--->
2+
<cfscript>
3+
submitLabel = args.configuration.button_label ?: translateResource( uri="formbuilder:button.submit.label" );
4+
backLabel = args.configuration.back_label ?: translateResource( uri="formbuilder:button.back.label" );
5+
continueLabel = args.configuration.continue_label ?: translateResource( uri="formbuilder:button.continue.label" );
6+
7+
isFormPage = args.isFormPage ?: false;
8+
isFirstPage = args.isFirstPage ?: false;
9+
isLastPage = args.isFirstPage ?: false;
10+
</cfscript>
11+
12+
<cfoutput>
13+
<div class="form-group">
14+
<div class="col-md-offset-3 col-md-12">
15+
<cfif isFormPage>
16+
<cfif not isFirstPage>
17+
<button tabindex="#getNextTabIndex()#" class="btn btn-bordered" type="submit" name="_formNextPage" value="-1">#backLabel#</button>
18+
</cfif>
19+
<button tabindex="#getNextTabIndex()#" class="btn" type="submit" name="_formNextPage" value="1">#continueLabel#</button>
20+
<cfelse>
21+
<button tabindex="#getNextTabIndex()#" class="btn" type="submit">#submitLabel#</button>
22+
</cfif>
23+
</div>
24+
</div>
25+
</cfoutput>
26+

system/views/formbuilder/layouts/core/formLayout.cfm

+9-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<!---@feature formbuilder--->
2-
<cfparam name="args.renderedItems" type="string" />
3-
<cfparam name="args.id" type="string" />
4-
<cfparam name="args.validationJs" type="string" default="" />
5-
<cfparam name="args.configuration" type="struct" />
2+
<cfparam name="args.renderedItems" type="string" />
3+
<cfparam name="args.renderedButtons" type="string" />
4+
<cfparam name="args.id" type="string" />
5+
<cfparam name="args.validationJs" type="string" default="" />
6+
<cfparam name="args.configuration" type="struct" />
67

78
<cfoutput>
8-
99
<cfif Len( Trim( rc.errorMessage ?: "" ) ) >
1010
<div class="alert alert-danger">#rc.errorMessage#</div>
1111
</cfif>
1212

13-
<form action="#event.buildLink( linkTo='formbuilder.core.submitAction' )#" id="#args.id#" method="post" enctype="multipart/form-data">
13+
<form action="#event.buildLink( linkTo="formbuilder.core.submitAction" )#" id="#args.id#" method="post" enctype="multipart/form-data">
1414
<input type="hidden" name="csrfToken" value="#event.getCsrfToken()#">
1515
<cfloop collection="#args#" item="argName">
16-
<cfif !( [ "id", "validationJs","renderedItems", "context", "layout" ].findNoCase( argName ) ) && IsSimpleValue( args[ argName ] )>
16+
<cfif not ArrayFindNoCase( [ "id", "validationJs", "renderedItems", "renderedButtons", "context", "layout", "formAction" ], argName ) && IsSimpleValue( args[ argName ] )>
1717
<input type="hidden" name="#argName#" value="#HtmlEditFormat( args[ argName ] )#">
1818
</cfif>
1919
</cfloop>
@@ -24,19 +24,13 @@
2424
#renderView( '/formbuilder/general/captcha' )#
2525
</cfif>
2626

27-
<div class="form-group">
28-
<div class="col-md-offset-3">
29-
<div class="col-md-9">
30-
<button class="btn" tabindex="#getNextTabIndex()#">#( args.configuration.button_label ?: 'Submit' )#</button>
31-
</div>
32-
</div>
33-
</div>
27+
#args.renderedButtons#
3428
</form>
3529

3630
<cfif Len( Trim( args.validationJs ) )>
3731
<cfsavecontent variable="formJs">
3832
if ( typeof executeWithFormBuilderDependencies !== 'undefined' ) {
39-
executeWithFormBuilderDependencies( function( $ ){
33+
executeWithFormBuilderDependencies( function( $ ) {
4034
$( '###args.id#' ).validate( $.extend( #args.validationJs#, {
4135
highlight: function( element, errorClass ) {
4236
$( element ).closest( '.form-group' ).addClass( 'has-error' );

0 commit comments

Comments
 (0)