changesetWebform class methods and properties
Every instance of the instance of the ChangesetWebform component is underpinned by an instance of the changesetWebform class instance. It has several methods and properties which apply to the form as a whole, outlined below.
Note that the changesetWebform class instance is included as an argument in all action callbacks. See Action handling.
Methods
validate
Arguments: (opts)
Validates all fields which are not omitted (See Hiding and showing fields).
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods1', hideSubmitButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, ], }; export default function FormMethodsExampleOne() { const changesetWebformRef = React.useRef(null); function afterGenerateChangesetWebform(changesetWebform) { changesetWebformRef.current = changesetWebform; } async function externalValidation() { await changesetWebformRef.current.validate(); } return ( <> <div className="border rounded p-2 mb-4 bg-light"> <b className="mb-2">These buttons are outside of the ChangesetWebform component</b> <div className="d-flex mt-2"> <button data-test-id="validate-externally" className="btn btn-primary me-2" type="button" onClick={externalValidation} > Validate externally </button> </div> </div> <ChangesetWebform formSchema={formSchema} afterGenerateChangesetWebform={afterGenerateChangesetWebform} /> </> ); }
If you would like to only revalidate fields which have already been validated, set opts.skipUnvalidated to true.
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods2', hideSubmitButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validatesOn: ['$inherited', 'insertWithValue'], validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, validationMethod: 'validateFormat', arguments: { type: 'email', }, }, ], }, ], }; export default function FormMethodsExampleTwo() { const changesetWebformRef = React.useRef(null); function afterGenerateChangesetWebform(changesetWebform) { changesetWebformRef.current = changesetWebform; } async function externalValidation() { const emailField = changesetWebformRef.current.fields.find((field) => field.fieldId === 'email'); emailField.updateValue('steveholt@bluthcompany.com'); await changesetWebformRef.current.validate({ skipUnvalidated: true }); } return ( <> <div className="border rounded p-2 mb-4 bg-light"> <b className="mb-2">These buttons are outside of the ChangesetWebform component</b> <div className="d-flex mt-2"> <button data-test-id="validate-externally" className="btn btn-primary me-2" type="button" onClick={externalValidation} > Update email and validate externally </button> </div> </div> <ChangesetWebform formSchema={formSchema} data={{ email: 'not-a-valid-email' }} afterGenerateChangesetWebform={afterGenerateChangesetWebform} /> </> ); }
setFieldOmission
Allows you to update whether or not a form field is omitted, by passing the fieldId and a boolean value.
See /docs/hiding-and-showing-fields#the-setfieldomission-method.
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods3', hideSubmitButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, ], }; export default function FormMethodsExampleThree() { const changesetWebformRef = React.useRef(null); function afterGenerateChangesetWebform(changesetWebform) { changesetWebformRef.current = changesetWebform; } function toggleEmailField() { const emailField = changesetWebformRef.current.fields.find((field) => field.fieldId === 'email'); changesetWebformRef.current.setFieldOmission('email', !emailField.isOmitted); } return ( <> <div className="border rounded p-2 mb-4 bg-light"> <b className="mb-2">These buttons are outside of the ChangesetWebform component</b> <div className="d-flex mt-2"> <button data-test-id="toggle-email-field" className="btn btn-primary me-2" type="button" onClick={toggleEmailField} > Toggle email field </button> </div> </div> <ChangesetWebform formSchema={formSchema} afterGenerateChangesetWebform={afterGenerateChangesetWebform} /> </> ); }
getField
Retrives a field int he changesetWebform based on the fieldId property.
@actiononFieldValueChange(formField, changesetWebform) {const emailField = changesetWebform.getField('email'); // The field with `fieldId === 'email'}getData
Saves the underlying chnageset, and returns the value of changeset.data. This is the javascript object whoch represents that collective values of the form fields. It is the data that would be passed to submitData.
- Name:
- Email:
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods5', hideSubmitButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, ], }; export default function FormMethodsExampleFive() { const [data, setData] = React.useState(null); async function onFieldValueChange(_formField, changesetWebform) { setData(await changesetWebform.getData()); } return ( <> <div className="border rounded p-2 mb-4 bg-light"> <ul> <li>Name: {data?.name}</li> <li>Email: {data?.email}</li> </ul> </div> <ChangesetWebform formSchema={formSchema} onFieldValueChange={onFieldValueChange} /> </> ); }
pushErrors
Allows you to push errors on to any field in the changesetWebform object. The example below will do so if the email taken@example.com is submitted.
import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods6', }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', defaultValue: 'Steve Holt', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', defaultValue: 'taken@example.com', validationEvents: ['$inherited', 'insertWithValue'], validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, { validationMethod: 'validateFormat', arguments: { type: 'email' }, }, ], }, ], }; function submitData(data, changesetWebform) { if (data.email === 'taken@example.com') { changesetWebform.pushErrors({ fieldId: 'email', errors: ['This email address is already taken. Please use another one.'], }); } } export default function FormMethodsExampleSix() { return ( <ChangesetWebform formSchema={formSchema} submitData={submitData} /> ); }
clear
Sets the value of each form field to null, and resets the form UI.
Clear form callbacks
If an action is passed to the ChangesetWebform component as @beforeClearForm, it will be called after the clear button is clicked, but before any of the clear form code runs.
Similarly, if an action is passed to the ChangesetWebform component as @afterClearForm, it will be called after the clear form code has been run.
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const data = { name: 'Steve Holt', email: 'steveholt@bluthcompany.com', }; const formSchema = { formSettings: { formName: 'formMethods7', clearFormButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, { validationMethod: 'validateFormat', arguments: { type: 'email' }, }, ], }, ], }; export default function FormMethodsExampleSeven() { const [actionsLog, setActionsLog] = React.useState([]); function beforeClearForm() { setActionsLog((prev) => [...prev, 'The beforeClearForm action was called']); } function afterClearForm() { setActionsLog((prev) => [...prev, 'The afterClearForm action was called']); } return ( <> {actionsLog.length > 0 && ( <div className="border rounded p-2 mb-4 bg-light" data-test-id="actions-log" > <ul> {actionsLog.map((entry, i) => ( <li key={i}>{entry}</li> ))} </ul> </div> )} <ChangesetWebform formSchema={formSchema} data={data} beforeClearForm={beforeClearForm} afterClearForm={afterClearForm} /> </> ); }
reset
Resets the value of each field, and resets the form UI.
It's important to note that under the hood this method runs the rollback method on the underlying changeset. This has a few important consequences, outlined below.
- If a field has an initial value from the
@dataprop passed to theChangesetWebformcomponent, clicking the reset button will reset that field to that initial value. See how, in the example below, the fields are reset to their initial values if they are updated and then ther reset button is clicked.
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const data = { name: 'Steve Holt', email: 'steveholt@bluthcompany.com', }; const formSchema = { formSettings: { formName: 'formMethods8', resetFormButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, { validationMethod: 'validateFormat', arguments: { type: 'email' }, }, ], }, ], }; export default function FormMethodsExampleEight() { const [actionsLog, setActionsLog] = React.useState([]); function beforeResetForm() { setActionsLog((prev) => [...prev, 'The beforeResetForm action was called']); } function afterResetForm() { setActionsLog((prev) => [...prev, 'The afterResetForm action was called']); } return ( <> {actionsLog.length > 0 && ( <div className="border rounded p-2 mb-4 bg-light" data-test-id="actions-log" > <ul> {actionsLog.map((entry, i) => ( <li key={i}>{entry}</li> ))} </ul> </div> )} <ChangesetWebform formSchema={formSchema} data={data} beforeResetForm={beforeResetForm} afterResetForm={afterResetForm} /> </> ); }
- If a field was inserted with
defaultValue, clicking the reset button will clear that field, because in this case the value has not been saved on the changeset. See how the fields are cleared when the reset button is clicked in the example below.
import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods9', resetFormButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', defaultValue: 'Steve Holt', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', defaultValue: 'steveholt@bluthcompany.com', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, { validationMethod: 'validateFormat', arguments: { type: 'email' }, }, ], }, ], }; export default function FormMethodsExampleNine() { return <ChangesetWebform formSchema={formSchema} />; }
- If fields are updated and the
savemethod of the underlying changeset is called, then clicking the reset button will reset fields to their values when the chnageset was last saved. The most common instance of this is when the submit button is clicked. See how, in the example above, if the submit button is clicked when the fields have values, then clicking the reset button resets the fields to those values, rather than clearing them.
Reset form callbacks
If an action is passed to the ChangesetWebform component as @beforeResetForm, it will be called after the reset form button is clicked, but before any of the reset form code runs.
Similarly, if an action is passed to the ChangesetWebform component as @afterResetForm, it will be called after the reset form form code has been run.
Properties
hasValidationErrors
Returns true if one or more fields have validation errors.
This allows us to ignore fields which have not yet been validated, and check if any of those that have been validated failed validation.
hasUnvalidatedFields
Returns true if there are any fields which have validation rules, but have not yet been validated.
Using hasUnvalidatedFields with hasValidationErrors allows us to check that all fields with validation rules have validated successfully.
Thus, in the example below, if you click the "Check if all fields have successfully validated" button, while both fields are empty and unvalidated, the alert will show that the form is not valid, but the form itself will not update in any way.
import React from 'react'; import ChangesetWebform from 'react-changeset-webforms/src/components/ChangesetWebform.jsx'; const formSchema = { formSettings: { formName: 'formMethods4', hideSubmitButton: true, }, fields: [ { fieldId: 'name', fieldType: 'input', fieldLabel: 'Name', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, { fieldId: 'email', fieldType: 'input', inputType: 'email', fieldLabel: 'Email', validationRules: [ { validationMethod: 'validatePresence', arguments: { presence: true, }, }, ], }, ], }; export default function FormMethodsExampleFour() { const [nextStepEnabled, setNextStepEnabled] = React.useState(false); function afterFieldValidation(_formField, changesetWebform) { setNextStepEnabled(!changesetWebform.hasValidationErrors && !changesetWebform.hasUnvalidatedFields); } return ( <> <div className="border rounded p-2 mb-4 bg-light"> <div className="mt-2"> {nextStepEnabled ? ( <> <button data-test-id="next-step-enabled" className="btn btn-primary me-2" type="button" > Go to next step </button> <div className="alert alert-success mb-0" data-test-id="alert-success" > All validating fields have successfully validated. </div> </> ) : ( <> <button data-test-id="next-step-disabled" className="btn btn-gray me-2" type="button" disabled > Next step disabled </button> <div className="alert alert-danger mb-0" data-test-id="alert-danger" > One or more validating fields has either failed validation, or not yet been validated. </div> </> )} </div> </div> <ChangesetWebform formSchema={formSchema} afterFieldValidation={afterFieldValidation} /> </> ); }