VueForms (StatCan.OrchardCore.VueForms
)¶
The VueForms module aims to simplify the creation of client side forms in OrchardCore.
Content definitions¶
VueForm¶
The VueForm content type is used to create forms that use VueJs and VeeValidate client side libraries. The form submission is handled via an ajax call to a generic controller that returns json to the client for seamless server side validation.
VueForm Part¶
Field | Definition |
---|---|
Disabled | If disabled, the DisabledHtml field value will be displayed instead of the form |
RenderAs | Render the Form as a Vue Component, a Vue App or Vuetify app |
DisabledHtml | Html displayed when the form is disabled. |
SuccessMessage | The success message returned to the client when the form is valid and no redirect is specified after submission. With Liquid support. |
Template | The component template. With Liquid support. |
Debug mode | Enables debug mode on the form. |
Note about RenderAs: When rendering the Form as a VueComponent
, you need to define a Zone in your layout called DynamicComponentZone
. This zone must be rendered anywhere before the FootScript
resource zone.
This is required because the div that defines the VueForm component needs to be defined outside of the Vue App. Please look at our open source VuetifyTheme layout for an example.
{% render_section "DynamicComponentZone", required: false %}
{% resources type: "FootScript" %}
Template¶
The template of the vue component
Example:
<v-container >
<v-card-text>
<v-row justify="center">
<v-col cols="8">
<validation-provider name="{{ "nameLabel" | localize | downcase }}" rules="required" v-slot="{ errors }">
<v-text-field v-model="name" :error-messages="errors" filled="filled" label="{{ "nameLabel" | localize }}"></v-text-field>
</validation-provider>
</v-col>
<v-col cols="8">
<validation-provider name="{{ "emailLabel" | localize | downcase }}" rules="required|email" v-slot="{ errors }">
<v-text-field v-model="email" :error-messages="errors" filled="filled" label="{{ "emailLabel" | localize }}"></v-text-field>
</validation-provider>
</v-col>
<v-col cols="8">
<validation-provider name="{{ "messageLabel" | localize | downcase }}" rules="required" v-slot="{ errors }">
<v-textarea v-model="message" :error-messages="errors" counter="true" filled="filled" label="{{ "messageLabel" | localize }}" rows="5">
</v-textarea>
</validation-provider>
</v-col>
<v-col cols="8">
<v-alert type="success" v-if="form.successMessage">
{% raw %}{{ form.successMessage }}{% endraw %}
</v-alert>
<v-alert type="error" v-if="form.errorMessage">
{% raw %}{{ form.errorMessage }}{% endraw %}
</v-alert>
</v-col>
<v-col cols="8">
<v-btn type="submit" depressed block @click="formHandleSubmit" :disabled="form.submitting">{{ "submitLabel" | localize }}</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-container>
Available Props¶
The VueForm component has some default properties and methods.
You can access these properties in your templates or in the component options object.
Name | Definition |
---|---|
obs.* | All props available on the v-slot of the ValidationObserver are available. |
formReset | A method that resets the form.* properties to the initial state. Does not reset your component's data. () => void |
formHandleSubmit | A method that calls the validate() method and then, if valid, sends an ajax request to our controller () => void |
form.submitting | Set to true when the form is being submitted. |
form.submitSuccess | Set to true when no redirect is specified and the submission was a success. |
form.successMessage | The success message returned from the server as specified in the VueForm |
form.submitValidationError | Set to true when a server validation error occus. |
form.serverValidationMessage | Array of errors set by the server with the addError('serverValidationMessage', 'Message') scripting method. |
form.responseData | The raw response data recieved from the server. Useful if you want to return additional data to the form via a workflow. |
form.submitError | Set to true when a server error, ajax error or unhandled error occurs. |
form.serverErrorMessage | An error message set with the ajax error status code and text. Only set when a server errors occur. |
Debug mode¶
Debug mode is typically used when developping a form. Additional information is returned by the server and any data output by the debug()
scripting method is also output and returned with the HttpResponse. This mode does not work when previewing the form.
VueFormScripts Part¶
Field | Definition |
---|---|
ClientInit | A client side script that is executed prior to instanciating the VueJs app. |
ComponentOptions | The VueJS component options object for your VueForm component. |
OnValidation | Server side validation script that allows us to validate the form. |
OnSubmitted | Server side script that runs if the form is valid |
ClientInit script¶
The ClientInit script is executed client side prior to instanciating the form component. This script has access to the client's global scope variables.
This was added to support hooking into some global options for VeeValidate.
For example, setting the VeeValidate.setInteractionMode('passive') option or the Localization option.
VeeValidate.setInteractionMode("passive");
OnValidation script¶
The OnValidation script is used to specify the server side validation script. We are planning to implement components with integrated validation in the future. This module adds some scripting methods to facilitate handling form data and errors.
Here is an example OnValidation script that validates that the name is required.
Note: the first parameter of addError must be your input name that must also match the VeeValidate ValidationProvider name.
var data = requestFormAsJsonObject();
if (data.name == "") {
addError("name", "The name is required");
}
All errors are also available to the client Vue component via the form.responseData.errors
property
OnSubmitted script¶
The OnSubmitted script is executed after the OnValidation script, only if the form is valid. This is where you would typically create a contentItem from the form data or redirect the user to another page.
Here is an example OnSubmitted script that redirects the user to a success page after having created the PersonInfo content item.
var data = requestFormAsJsonObject();
createContentItem("PersonInfo", true, {
PersonInfo: {
Name: {
Text: data.name
},
Email: {
Text: data.email
},
Gender: {
Text: data.gender
}
}
});
// redirects to the success page
httpRedirect("~/success");
Component Options object¶
This is where you write theVueJS component options object for the form component. At a minimum, you must define the data object. By default, the entire data object is serialized and sent to the server when the form is submitted.
{
data: () => ({
items: ["Female", "Male", "Other"],
name: "",
email: "",
gender: undefined
});
}
You can also overwrite the submitData()
method to customize what is sent to the server. This can be very useful when your data
object contains list of items for a dropdown.
{
data: () => ({
items: ["Female", "Male", "Other"],
name: "",
email: "",
gender: undefined
}),
submitData() {
return { name: this.name, email: this.email, gender: this.gender };
},
}
Custom Form Components¶
The sections below decribes the custom form components provided by this module.
Multiselect components¶
The module exposes two multiselect components: multiselect-async
and multiselect
. These components are wrappers of the multiselect component from the vue-multiselect library. The api of the base vue-multiselect
component can be found here.
multiselect-async component¶
The multiselect-async
component allows async loading of options from an api.
Props | Definition |
---|---|
value | The holder of the selected options |
api | The url of the api that the options are coming from |
success | A boolean representing the validation result |
error-messages | Messages to show when validation fails |
All the other props are the same as the base multiselect component.
multiselect component¶
The multiselect
component provides a multiselect feature without async loading of options.
Props | Definition |
---|---|
value | The holder of the selected options |
success | A boolean representing the validation result |
error-messages | Messages to show when validation fails |
All the other props are the same as the base multiselect component.
Bag component¶
The bag
component provides a bag behaviour to the form. A bag is a collection of field groups. The bag component behaves similar to the BagPart in Orchard Core.
Props | Definition |
---|---|
value | The holder of the selected options over the entire bag |
valueNames | The name of the value object of each individual field in a field group |
add-button-label | The label of the add button |
remove-button-label | The label of the remove button |
success | A boolean representing the validation result. |
errorMessages | Messages to show when validation fails |
Below is an example of the value
object:
value: [{ field1: "field1Value", field2: "field2Value" }];
The general form of the value
object is an array of objects. Each object represents a group of fields. Each proprety represents the value of a specific field.
The valueNames
prop is a string array of the proprety name used in the field group objects in the value
object. For example, the valueNames
array corresponding to the value
object given above is
valueNames: ["field1", "field2"];
Bag component example¶
Here is an example of using the bag
component
<validation-provider name="Bag" rules="required" v-slot="{ errors, valid }">
<bag
v-model="bagValues"
:valueNames="valueNames"
:success="valid"
:error-messages="errors"
add-button-label="Add"
remove-button-label="-"
>
<template #validations>
<validation-provider
rules="required"
name="Field 1"
></validation-provider>
<validation-provider
rules="required"
name="Field 2"
></validation-provider>
</template>
<template #components>
<v-text-field filled="filled" label="label"> </v-text-field>
<v-text-field filled="filled" label="label"> </v-text-field>
</template>
<template #title>
<div class="text-h5 mb-5">
Bag
</div>
</template>
</bag>
</validation-provider>
The data object is:
{
data: () => ({
bagValues: [{ field1: "field1", field2: "field2" }],
valueNames: ["field1", "field2"]
})
}
The bag
component can be wrapped in a validation-provider
just like any other field components.
The bag
component has three slots. The validations
slots contains the validation-provider
for each field in the field groups. The components
slot contains the actual field components. The title
slot contains components representing the title of the bag
component.
The components in the validations
and components
slots are prototypes. For example, whenever the add button is clicked, the components defined in those two slots will be "instantiated".
Some notes on using the bag component¶
Components defined in the validations
and components
slots should not contain any children.
Ignore v-slot="{ errors, valid }"
when defining validation-provider
components in the validations
slot because it is handled by the bag
component.
Ignore v-model
, :success
, and :error-messages
when defining components in the components
slots because they are handled by the bag
component.
Scripting¶
Please see the scripting documentation.
Workflow integration¶
Although this module does not require a workflow to handle the form submissions, we still provide a workflow hook to support performing some additional actions.
Please see the workflow documentation.
If you do use a workflow, you can use the addError("name", "message");
script to add form errors. You can also use the HttpRedirect
or HttpResponse
workflow tasks to redirect or return a custom set of data to the client. All data returned by the HttpResponse task is available via the form.responseData
object. You should also be able to use the debug()
scripting method to return debugging data to the client.
Localization (StatCan.OrchardCore.VueForms.Localized
)¶
While you can use Orchard's LocalizationPart to localize your forms. We suggest you use the LocalizedText feature to implement i18n in your forms. This part is what we weld to your VueForm content type when you enable this feature.
The [locale]
shortcode is also useful to use in your views to localize simple text fields.
Survey (StatCan.OrchardCore.VueForms.Survey
)¶
Adds SurveyJS support to VueForms. This adds a part to the VueForm where you can specify the SurveyJS creator json object.
In the Template, simply write this to output a Survey that uses the SurveyJS json object
<survey :survey="survey"></survey>
To get the json output of the survey on your server side scripts, simply use the getSurveyData()
method.
const surveyData = getSurveyData();
debug("surveyData", surveyData);
Examples¶
The following example forms are provided with the VueForms module as recipes:
- Contact Form
- UserProfile Form
UserProfile Form¶
This form allows you to edit a UserProfile
Content Type with the CustomUserSettings
stereotype. For this form to work, you must enable the Users Change Email
feature along with allowing users to update their email in the settings.