I'm trying to make a multi-page form by adding next and previous button types to the different sections of the layout. I thought this might naturally show and hide the different sections out of the box, but its not. Should it?
If so, whats the trick to get it to work?
If not, I assume I need to hook into the button click event and show/hide the different sections manually?
On a different note, I also tried to use the Text Constant field - I thought I would add some static text to the field and then throw that into the layout at the appropriate place. However, when I go to the layout, the field doesn't appear as an unused field - so I can't place it on the page.
Have I misunderstood the purpose of the Text Constant field?
I'm trying to make a multi-page form by adding next and previous button types to the different sections of the layout.
The button kind doesn't actually have any functional impact (you can actually add any kind of button in the ~/Config/Formulate/buttons.config file). It's up to you to implement multi-step forms however you want. The button kind can just help you to that end (you can use the button kind in the AngularJS code).
Essentially, we created a single Formulate form, then we created one layout per step (to include all the fields in that step), then we created a form configuration for each of those layouts. We then created a widget that allowed us to select a number of form configurations, and we created some AngularJS that knew how to manage data and buttons so that as you progress from one form to the next, it will keep all that data and on the last step submit it as if it were a single form submission.
Here's what the widget looks like in the back office (built using Archetype):
On a different note, I also tried to use the Text Constant field
The text constant is a purely server-side field. That is, it will not render on the frontend of the website. I use this field to send data to API's. For example, when using the "Send Data" form submission handler, I sometimes use a text constant field if the API requires some identifier (e.g., a "list ID" when subscribing somebody to an email newsletter list of subscribers).
If you want to display some text on the frontend, you can use the rich text field type.
I should probably create a documentation page explaining each of these field types. I realize some of them aren't very intuitive.
Hi Nic, I got lazy and approached the multi-page form slightly differently.
I created the one form and layout with all the form fields and with prev/next buttons repeated in the appropriate spots throughout the layout (at the bottom of each "page").
I then included this inside the controller to display any validation errors of the visible fields for the current page and set a flag for use in the button event:
$scope.$on("Formulate.buttonClicked", function (event, data) {
areVisbleFormErrors = false;
angular.forEach(event.targetScope.form1.$error, function (field) {
angular.forEach(field, function (errorField) {
if ($('[name="' + errorField.$name + '"]').is(':visible')) {
errorField.$setTouched();
if (!errorField.$valid) {
areVisbleFormErrors = true;
}
}
});
});
})
Then in the button events I simply check of there are any errors and if not, hide the current "page" and show the next page:
aboutYouNextButton.click(function (event) {
if (!areVisbleFormErrors) {
showHidePropertyDetails(true);
}
});
Where the showHide routine is a horrible - but quick and dirty ;-) -hardcoded hack that depends on the rows in the layout.
function showHideAboutYou(show) {
showHide(show, 0, 1, -1, 2);
}
function showHide(show, skip, take, hiderow, showrow) {
var fieldsContainer = $('form[name="form1"]').children().first().children();
fieldsContainer.each(function (index) {
if ((index < skip || index >= skip + take || index == hiderow) && (index != showrow)) {
$(this).hide();
}
else {
if (show || index == showrow ) {
$(this).show();
}
else {
$(this).hide();
}
}
});
}
Oh yes, that is quite horrifying. Can't argue with effective though! Thanks for sharing your code. I'm sure there are at least a few people out there who will be able to make use of it.
Text Constants and Paging
Hey Nic,
I'm trying to make a multi-page form by adding next and previous button types to the different sections of the layout. I thought this might naturally show and hide the different sections out of the box, but its not. Should it?
If so, whats the trick to get it to work?
If not, I assume I need to hook into the button click event and show/hide the different sections manually?
On a different note, I also tried to use the Text Constant field - I thought I would add some static text to the field and then throw that into the layout at the appropriate place. However, when I go to the layout, the field doesn't appear as an unused field - so I can't place it on the page.
Have I misunderstood the purpose of the Text Constant field?
TIA, Trevor BTW, loving Formulate!
The button kind doesn't actually have any functional impact (you can actually add any kind of button in the
~/Config/Formulate/buttons.config
file). It's up to you to implement multi-step forms however you want. The button kind can just help you to that end (you can use the button kind in the AngularJS code).You can see an example of one here: https://www.schreiberfoods.com/en-us/careers/job-openings/positions/job-application-tobacco?jobApplyingFor=Industrial%20Maintenance%20Mechanic&locationApplyingFor=Tempe,%20Arizona,%20USA&sourcePageId=3578
Essentially, we created a single Formulate form, then we created one layout per step (to include all the fields in that step), then we created a form configuration for each of those layouts. We then created a widget that allowed us to select a number of form configurations, and we created some AngularJS that knew how to manage data and buttons so that as you progress from one form to the next, it will keep all that data and on the last step submit it as if it were a single form submission.
Here's what the widget looks like in the back office (built using Archetype):
The text constant is a purely server-side field. That is, it will not render on the frontend of the website. I use this field to send data to API's. For example, when using the "Send Data" form submission handler, I sometimes use a text constant field if the API requires some identifier (e.g., a "list ID" when subscribing somebody to an email newsletter list of subscribers).
If you want to display some text on the frontend, you can use the rich text field type.
I should probably create a documentation page explaining each of these field types. I realize some of them aren't very intuitive.
Happy to hear it!
Thanks Nic. I'll give that a whirl.
Hi Nic, I got lazy and approached the multi-page form slightly differently.
I created the one form and layout with all the form fields and with prev/next buttons repeated in the appropriate spots throughout the layout (at the bottom of each "page").
I then included this inside the controller to display any validation errors of the visible fields for the current page and set a flag for use in the button event:
Then in the button events I simply check of there are any errors and if not, hide the current "page" and show the next page:
Where the showHide routine is a horrible - but quick and dirty ;-) -hardcoded hack that depends on the rows in the layout.
Shitty but effective :-)
Oh yes, that is quite horrifying. Can't argue with effective though! Thanks for sharing your code. I'm sure there are at least a few people out there who will be able to make use of it.
is working on a reply...