@wasable/react-form
v1.0.0-rc.2
Published
form for beable use
Downloads
1
Readme
Form Usage
To use an HOC form with innerState, errors handlings and validation, an helper is available like as follows:
import { classicForm } from "@wasable/react-form";
you need to provide it some required properties:
initialData
: is the item to edit OR the initialData in a create ActionactionForm
: is the action triggered on submit, if the validation is correct
you can also provide it with an optional property:
load
: a function that is triggered in the constructor of the formreturnCompleteData
: if set to true, the first parameter of the actionform function will be the full formdata, not only the modified oneonSubmitError
: function triggered when submit is triggered but the validation is NOK (WARNING: this is not triggered on API error ATM)
finally, an example:
import { connect } from "react-redux";
import { classicForm } from "@wasable/react-form";
// Your components to wrap
import ExampleComponent from "path/to/component";
const mapStateToProps = (state) => {
initialData: {
} // here you store your selector or your initialData file
returnCompleteData: false;
};
const mapDispatchToProps = () => {
return {
actionForm: (data) => {
// data: is either the full data of the form or only the modified data
// here is the main action of your form, usually an Api call for creation/update
},
onSubmitError: (errorList) => {
// errorList : an array of all the text errors in your form
// you can dispatch here an action to display a toaster, for example.
},
load: () => {
// you can dispatch here an action to retrieve necessary data for your form, such as civilityList, cityList... etc.
},
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(classicForm(ExampleComponent));
import { HOCErrorLabel } from "@wasable/react-form";
import ComponentLabel from "./some_path_to_component";
// Utils
import { fieldDefaultPropTypes } from "./const/propTypes";
import { fieldDefaultProps } from "./const/defaultProps";
export default class ExampleComponent extends Component {
constructor(props) {
super(props);
props.setValidator(/* some rules, some custom rules func */);
}
render() {
const ErrorMessage = HOCErrorLabel(ComponentLabel);
const { getValidationStatus, handleChange, formData, submit } = this.props;
const { property_name, second_property_name } = formData;
return (
<>
<div>
<div>
<span>Some Label</span>
<Input
// some props...
value={property_name}
onChange={(e) => handleChange("property_name", e.value)}
/>
<ErrorMessage
getKeysStatus={() =>
getValidationStatus(["some_rule_name", "some_rule_name_again"])
}
isMulti={true}
/>
</div>
<div>
<span>Some Label Again</span>
<Input
// some props...
value={second_property_name}
onChange={(e) => handleChange("second_property_name", e.value)}
/>
<ErrorMessage
getKeysStatus={() =>
getValidationStatus([
"some_rule_name",
"some_rule_name_again",
"some_rule_name_the_prequel",
])
}
isMulti={false}
/>
</div>
</div>
/* will triger the validation according to rule set in constructor after
that, will triger actionForm (if validation OK) or (onSubmitError) */
<button onClick={submit}>Valider</button>
</>
);
}
}
Validation
Validator
The validator is a javascript class who can handle rules and validate a javascript object accordingly
Example
import { Validator } from "@wasable/beable-form";
// some code
const rules = {
my_strict_rules_name: {
// the key corresponding to a given rules (default or custom)
rule: "stricktlySameValue",
// the property of the object to Test given to the ruleFunction in the order
fields: ["bar", "foo"],
// error message given if invalid
message: "you striclty f***** something, mate !",
},
my_rules_name: {
// the key corresponding to a given rules (default or custom)
rule: "sameValue",
// the property of the object to Test given to the ruleFunction in the order
fields: ["foo", "bar"],
// error message given if invalid
message: "you f***** something, mate !",
},
};
const rulesFunc = {
// here we are defining a custom rules (for defaut rules given see Rules -> Native Rules
stricktlySameValue: isStrictlySameValue,
sameValue: isSameValue,
};
// here is the definition of the function to use in our custom rules
// note that in this exemple props1 = objectToTest.bar's value and props2 = objectToTest.foo's value
function isStrictlySameValue(props1, props2) {
return props1 === props2;
}
// here is the definition of the function to use in our custom rules
// note that in this exemple props1 = objectToTest.foo's value and props2 = objectToTest.bar's value
function isSameValue(props1, props2) {
return props1 == props2;
}
// create our validator with our rules and custome validation function
const exampleValidator = new Validator(rules, rulesFunc);
// --- validate Zone ---
// firstTest will be : { my_strict_rules_name: true, my_rules_name: true }
const firstTest = exampleValidator.validate({
foo: "1",
bar: "2",
});
// secondTest will be : { my_strict_rules_name: true }
const secondTest = exampleValidator.validate({
foo: "1",
bar: 1,
});
// thindTest will be : {} because all rules are valid
const thirdTest = exampleValidator.validate({
foo: "1",
bar: "1",
});
// --- hasError Zone ---
// will return true
exampleValidator.hasError(
["my_strict_rules_name", "my_rules_name"],
secondTest
);
// will return true
exampleValidator.hasError(["my_strict_rules_name"], secondTest);
// will return false
exampleValidator.hasError(["my_rules_name"], secondTest);
// --- getStatus Zone ---
// ---- firstTest Zone ----
// will be : ['you striclty f***** something, mate !', 'you f***** something, mate !']
exampleValidator.getStatus(
["my_strict_rules_name", "my_rules_name"],
firstTest
);
// will be : ['you striclty f***** something, mate !']
exampleValidator.getStatus(["my_strict_rules_name"], firstTest);
// will be : ['you f***** something, mate !']
exampleValidator.getStatus(["my_rules_name"], firstTest);
// will be : []
exampleValidator.getStatus(["another_rule_name"], firstTest);
// ---- secondTest Zone ----
// will be : ['you striclty f***** something, mate !']
exampleValidator.getStatus(
["my_strict_rules_name", "my_rules_name"],
secondTest
);
// will be : ['you striclty f***** something, mate !']
exampleValidator.getStatus(["my_strict_rules_name"], secondTest);
// errorMessages will be : []
exampleValidator.getStatus(["my_rules_name"], secondTest);
// ---- thirdTest Zone ----
// will be : []
exampleValidator.getStatus(
["my_strict_rules_name", "my_rules_name"],
thirdTest
);
// will be : []
exampleValidator.getStatus(["my_strict_rules_name"], thirdTest);
// will be : []
exampleValidator.getStatus(["my_rules_name"], thirdTest);
// some code
Rules
Syntaxe
const rulesList = {
my_rules_name_1: {
// the key corresponding to a given rules (default or custom)
rule: "someRule",
// the property of the object to Test given to the ruleFunction in the order
fields: ["props1", "props2", "propsX"],
// error message given if invalid
message: "a message",
},
my_rules_name_X: {
rule: "someRule",
fields: ["props7", "propsX"],
message: "a message",
},
};
Native Rules
email
: The field under validation must be formatted as an e-mail addresssiret
: The field under validation must be a FRENCH siret numberphone
: The field under validation must be a FRENCH phone number (ten numeric)password
: The field under validation casted in string must contain uppercase, lowercase, number and at least eight characterrequired
: The field under validation musn't be null, undefined or empty stringisSame
: The fields under validation must be strictly identical (===)password_repeat
: same as previous, here for backward compatibilityisTrue
: The field under validation must be trueisFalse
: The field under validation must be true
Helpers
Generators
To ease the writing of rules, some helpers (called 'rulesGenerators') are available:
generateRequiredRules
Description
will return an object containing required rules for multiple properties in your form
Syntaxe
generateRequiredRules(fields, message);
Parameters
fields
: Array[string] -> contain all the properties which required rule will be generatedmessage
: string -> an error message (CAUTION: this will be applied to all the rule generated in this manner), if not specified this will return '${property_name}.required'
Return value
a Javascript object with pair key/value -> ruleName/ruleValue (formatted defined in 'RULES')
import { generateRequiredRules } from "@wasable/beable-form";
// some code
const exampleRulesJSON = generateRequiredRules([
"my_property_1",
"my_property_2",
/*... */ "my_property_X",
]);
// some code
HOCErrorLabel
Will give to the wrapped component an array of error message depending on the rules to watch
Property Needed:
getKeysStatus
: a function who will return the list of message to handle (usually the return of getValidationStatus from the validationHOC)
isMulti
: if multiple message can be returned at once
Property given to Wrapped Component:
errorToDisplay
: an array of message to display
import { HOCErrorLabel } from "@wasable/react-form";
import ComponentLabel from "./some_path_to_component";
// Utils
import { fieldDefaultPropTypes } from "./const/propTypes";
import { fieldDefaultProps } from "./const/defaultProps";
export const TextField = (props) => {
const ErrorMessage = HOCErrorLabel(ComponentLabel);
const { getValidationStatus } = props;
return (
<div>
<ErrorMessage
getKeysStatus={() => getValidationStatus(validationErrors)}
isMulti={true}
/>
</div>
);
};
In this exemple, the component 'ComponentLabel', will receive an array of string (who are the corresponding message of all the rules 'watched')