These samples has basic implementation for @enfometa/em-forms
em-forms-samples
forms-validation
A simple, robust and flexible react forms validation library for both React Js and React Native. The great thing about the library is, it has no dependency on the UI. You can easily decouple your business logic from the UI and can reuse in both React Js and React Native apps.
This section includes code samples for em-forms
This will register controls to specify how em-forms should deal with each control wrapped in EmFormControl
import { emFormsGlobalConfig } from "@enfometa/em-forms";
emFormsGlobalConfig.registerEmFormControls([
{
valuePropName: "value",
onChangePropName: "onChange",
valueFunc: (e) => e.target.value,
controls: [{ type: "input" }],
},
{
valuePropName: "value",
onChangePropName: "onChange",
valueFunc: (e) => e.target.value,
controls: [{ type: "select" }],
},
{
valuePropName: "checked",
onChangePropName: "onChange",
valueFunc: (e) => e.target.checked,
controls: [
{
type: "input",
props: { type: "checkbox" },
},
],
},
{
valuePropName: "selectedValue",
onChangePropName: "onChange",
valueFunc: (e) => e.target.value,
controls: [{ type: "RadioGroup" }],
},
]);
FormGroup
componentimport React from "react";
import { useEmForms, required, email, EmFormErrorMessage } from "@enfometa/em-forms";
const LoginWithoutFormsGroup = (props) => {
const forms = useEmForms({
forms: [
{
name: "username",
value: "",
validators: [
{ name: "required", func: required, message: "Username is required" },
{ name: "email", func: email, message: "Invalid email address" },
],
},
{
name: "password",
value: "",
validators: [{ name: "required", func: required, message: "Password is required" }],
},
{
name: "rememberMe",
value: false,
},
],
});
const login = () => {
if (forms.validate()) {
const model = forms.toModel();
//do something with the model
console.log(model);
}
};
const reset = () => {
forms.reset();
};
const updateFormValue = (formName, value) => {
forms.setFormValue(formName, value);
};
const setFormTouch = (formName) => {
forms.setFormTouch(formName, true);
};
return (
<div className="container">
<main>
<div className="row g-5">
<div className="col-md-6 col-lg-4">
<h4 className="mb-3">Functional component Login without FormGroup</h4>
<div className="row g-3">
<div className="col-12">
<input
type="email"
className="form-control"
placeholder="Email"
onChange={(e) => updateFormValue("username", e.target.value)}
value={forms.getFormValue("username")}
onBlur={(e) => setFormTouch("username")}
/>
<div className="error-message">
<EmFormErrorMessage emForms={forms} formName="username" validatorName="required" />
<EmFormErrorMessage emForms={forms} formName="username" validatorName="email" />
</div>
</div>
<div className="col-12">
<input
type="password"
className="form-control"
placeholder="password"
onChange={(e) => updateFormValue("password", e.target.value)}
value={forms.getFormValue("password")}
onBlur={(e) => setFormTouch("password")}
/>
<div className="error-message">
<EmFormErrorMessage emForms={forms} formName="password" validatorName="required" />
</div>
</div>
<div className="col-12">
<input
type="checkbox"
onChange={(e) => updateFormValue("rememberMe", e.target.checked)}
checked={forms.getFormValue("rememberMe")}
onBlur={(e) => setFormTouch("rememberMe")}
/>
</div>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={login}>
Login
</button>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={reset}>
Reset
</button>
</div>
</div>
</div>
</main>
</div>
);
};
export default LoginWithoutFormsGroup;
forms.reset()
: Reset all vlaues to default values (Initial values)
forms.reset(values?: ResetConfig[])
: This accepts an array of ResetConfig
object. If you want a form not set to default, specify a value for that form. For example, below example will set "password" to default value and "username", "rememberMe" to "enfometa", true respectively.
forms.reset([
{ name: "username", value: "enfometa" },
{ name: "rememberMe", value: true },
]);
reset(values?: ResetConfig[] | null, excludeForms?: ResetConfig | null): void
: The last parameter excludeForms
specifies which form should be ignored and not reset. For example, below sample code will ignore "rememberMe" to reset and "username" and "password" will be reset to default as first argument is null.forms.reset(null, [{ name: "rememberMe", value: true }]);
FormGroup
componentimport React, { useState } from "react";
import { useEmForms, required, email, EmFormErrorMessage, EmFormGroup, EmFormControl, minLength } from "@enfometa/em-forms";
const LoginWithFormsGroup = (props) => {
const forms = useEmForms({
forms: [
{
name: "username",
value: "",
validators: [
{ name: "required", func: required, message: "Username is required" },
{ name: "email", func: email, message: "Invalid email address" },
],
},
{
name: "password",
value: "",
validators: [
{ name: "required", func: required, message: "Password is required" },
{ name: "minLength", func: minLength, message: "min Length required is 6", param: { minLength: 6 } },
],
},
{
name: "rememberMe",
value: false,
},
],
});
const login = () => {
if (forms.validate()) {
const model = forms.toModel();
//do something with model
console.log(model);
}
};
const reset = () => {
//forms.reset();
//Ignore username reset
forms.reset(null, [{ name: "username" }]);
};
return (
<div className="container">
<main>
<div className="row g-5">
<div className="col-md-6 col-lg-4">
<h4 className="mb-3">Functional component Login with FormGroup</h4>
<div className="row g-3">
<EmFormGroup emForms={forms}>
<div className="col-12">
<EmFormControl formName="username">
<input type="email" className="form-control" placeholder="Email" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="username" validatorName="required" />
<EmFormErrorMessage formName="username" validatorName="email" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="password">
<input type="password" className="form-control" placeholder="password" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="password" validatorName="required" />
<EmFormErrorMessage formName="password" validatorName="minLength" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="rememberMe">
<input type="checkbox" />
</EmFormControl>
</div>
</EmFormGroup>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={login}>
Login
</button>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={reset}>
Reset
</button>
</div>
</div>
</div>
</main>
</div>
);
};
export default LoginWithFormsGroup;
FormGroup
componentimport React, { useState } from "react";
import { initEmForms, required, email, EmFormErrorMessage, EmFormGroup, EmFormControl } from "@enfometa/em-forms";
class LoginClassComponent extends React.Component {
constructor(props) {
super(props);
//this.state = {};
this.forms = initEmForms(
{
forms: [
{
name: "username",
value: "",
validators: [
{ name: "required", func: required, message: "Username is required" },
{ name: "email", func: email, message: "Invalid email address" },
],
},
{
name: "password",
value: "",
validators: [{ name: "required", func: required, message: "Password is required" }],
},
{
name: "rememberMe",
value: false,
},
],
},
this,
"forms"
);
}
login = () => {
if (this.forms.validate()) {
const model = this.forms.toModel();
console.log(model);
}
};
reset = () => {
this.forms.reset([{ name: "rememberMe", value: true }]);
};
render() {
return (
<div className="container">
<main>
<div className="row g-5">
<div className="col-md-6 col-lg-4">
<h4 className="mb-3">Class component Login with FormGroup</h4>
<div className="row g-3">
<EmFormGroup emForms={this.forms}>
<div className="col-12">
<EmFormControl formName="username">
<input type="email" className="form-control" placeholder="Email" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="username" validatorName="required" />
<EmFormErrorMessage formName="username" validatorName="email" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="password">
<input type="password" className="form-control" placeholder="password" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="password" validatorName="required" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="rememberMe">
<input type="checkbox" />
</EmFormControl>
</div>
</EmFormGroup>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={this.login}>
Login
</button>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={this.reset}>
Reset
</button>
</div>
</div>
</div>
</main>
</div>
);
}
}
export default LoginClassComponent;
This sample demonstrate how to get data from server and set to the em-forms and then update back to the server. This sample also shows a list of errors as well by using method forms.getErrors()
import React, { useState } from "react";
import { useEmForms, required, email, EmFormErrorMessage, EmFormGroup, EmFormControl, range, minLength } from "@enfometa/em-forms";
import RadioGroup from "./base/RadioGroup";
const Profile = (props) => {
const forms = useEmForms({
forms: [
{
name: "name",
value: "",
validators: [
{ name: "required", func: required, message: "Name is required" },
{ name: "minLength", func: minLength, message: "min Length required is 3", param: { minLength: 6 } },
],
},
{
name: "email",
value: "",
validators: [
{ name: "required", func: required, message: "Email is required" },
{ name: "email", func: email, message: "Invalid email" },
],
},
{
name: "age",
value: 10,
validators: [
{ name: "required", func: required, message: "Age is required" },
{ name: "range", func: range, message: "Age must be between 18 and 50", param: { min: 18, max: 50 } },
],
},
{
name: "gender",
value: "M",
validators: [{ name: "required", func: required, message: "Gender is required" }],
},
{
name: "accountType",
value: "admin",
validators: [{ name: "required", func: required, message: "Account type is required" }],
},
],
});
const accountTypes = [
{ text: "Admin", value: "admin" },
{ text: "User", value: "user" },
{ text: "Visitor", value: "visitor" },
];
//fake http call
const getProfile = () => {
return { name: "Enfometa", email: "enfometa@gmial.com", age: 30, gender: "M", accountType: "admin" };
};
//fake http call
const updateProfile = (model) => {
console.log("Profile updated", model);
};
//get values from server and set em-forms object
useState(() => {
const profile = getProfile();
forms.setValuesFromModel(profile);
}, []);
const update = () => {
if (forms.validate()) {
const model = forms.toModel();
updateProfile(model);
}
};
const reset = () => {
forms.reset();
};
return (
<div className="container">
<main>
<div className="row g-5">
<ul className="error-message">
{forms.getErrors().map((form, indx) => (
<li key={indx}>{form.message}</li>
))}
</ul>
</div>
<div className="row g-5">
<div className="col-md-6 col-lg-4">
<h4 className="mb-3">Profile component</h4>
<div className="row g-3">
<EmFormGroup emForms={forms}>
<div className="col-12">
<EmFormControl formName="name">
<input type="text" className="form-control" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="name" validatorName="required" />
<EmFormErrorMessage formName="name" validatorName="minLength" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="email">
<input type="text" className="form-control" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="email" validatorName="required" />
<EmFormErrorMessage formName="email" validatorName="email" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="age">
<input type="number" className="form-control" />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="age" validatorName="required" />
<EmFormErrorMessage formName="age" validatorName="range" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="gender">
<select>
<option value="">Please select</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="gender" validatorName="required" />
</div>
</div>
<div className="col-12">
<EmFormControl formName="accountType">
<RadioGroup name={"accountType"} dataSource={accountTypes} />
</EmFormControl>
<div className="error-message">
<EmFormErrorMessage formName="accountType" validatorName="required" />
</div>
</div>
</EmFormGroup>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={update}>
Update
</button>
<button className="w-100 btn btn-primary btn-lg" type="button" onClick={reset}>
Reset
</button>
</div>
</div>
</div>
</main>
</div>
);
};
export default Profile;