{
"navigation": "auto"
}
- none
- auto
- static
- wizard
- survey
- tabstrip
The Form Control for navigation and submit can now be optionally included in the Form schema.
const schema = {
model: {
// ...
},
pages: [
// ...
],
controls: [
{
name: "reset",
type: "button",
caption: "Back to page one",
class: "form-reset"
},
{
name: "prev",
type: "button",
caption: "◁ Back",
class: "form-prev"
},
{
name: "next",
type: "button",
class: "form-next"
},
{
name: "send",
type: "button",
caption: "Submit",
class: "form-post"
}
]
}
If you don't have a controls array in your schema, XO form will revert to the default behavior based on the selected navigation type. For instance, if your navigation setting is 'auto' (or not specified in the schema), and your schema consists of one page, the following code will be injected into the runtime schema:
controls = [
{
name: "send",
type: "button",
caption: "Submit",
class: "form-post"
}
]
... while if navigation is set to 'wizard' (or 'auto'/missing with more than one page specified), the following code will be provisioned:
controls = [
{
name: "prev",
type: "button",
caption: "◁ Back",
class: "form-prev"
},
{
name: "next",
type: "button",
caption: "Next ▷",
class: "form-next"
},
{
name: "send",
type: "button",
caption: "Submit",
class: "form-post"
}
];
Apart from having control over button classes and captions, a major benefit of the explicit controls markup is in combination with data binding and logic.
Look at this code for instance:
controls: [
{
name: "reset",
type: "button",
caption: "Back to page one",
class: "form-reset",
disabled: "@bindings.isFirstPage"
},
{
name: "prev",
type: "button",
caption: "◁ Back",
class: "form-prev"
},
{
name: "next",
type: "button",
caption: "Next ▷",
class: "form-next"
},
{
name: "send",
type: "button",
caption: "Submit",
class: "form-post",
disabled: "@bindings.sendDisabled"
}
]
You can see that here, button state is linked to changes that are defined in the model logic:
model: {
instance: {
person: {
name: {
first: "John",
last: "Doe"
},
age: 57,
gender: "male"
},
contract: {
agree: false
}
},
logic: context => {
const model = context.model, person = model.instance.person,
b = model.bindings, nav = context.exo.addins.navigation;
b.isFirstPage = nav.currentPage === 1;
b.sendDisabled = nav.;
}
}
const schema = {
navigation: "tabstrip",
pages: [{
legend: "Details",
intro: "Fill in your details",
fields: [
{
type: "name",
name: "name",
caption: "Enter name",
required: true
},
{
type: "email",
name: "email",
required: true,
placeholder: "[email protected]",
caption: "Enter email address"
},
{
type: "multiline",
name: "msg",
caption: "Message",
placeholder: "My message for you...",
autogrow: true
}
]
},
{
legend: "Extra",
intro: "Add some extra stuff",
fields: [
{
type: "dropdown",
name: "favpet",
caption: "Favorite pet",
items: ["Dog", "Cat", "Bunny", "Hamster", "Bird", "Snake", "Pig"]
},
{
type: "tags",
name: "tags",
caption: "Skills",
value: ["C#", "JavaScript", "Azure", "JSON"]
}
]
}]
}
Result: