Skip to content

Instantly share code, notes, and snippets.

@danecando
Created June 18, 2018 05:29
Show Gist options
  • Save danecando/d5c755201bb1252bb726c46e23915380 to your computer and use it in GitHub Desktop.
Save danecando/d5c755201bb1252bb726c46e23915380 to your computer and use it in GitHub Desktop.
Mobx store for managing form state (built for my react-native app)
import { reduce, find } from 'lodash';
import { observable, action, computed, extendObservable } from 'mobx';
import Validator from 'validatorjs';
import en from 'validatorjs/src/lang/en';
Validator.setMessages('en', en);
class FormStore {
@observable fields = {};
constructor(fields) {
const fieldsObj = reduce(
fields,
(acc, val) => ({
...acc,
[val.field]: {
focused: false,
value: '',
error: null,
rules: val.rules || ''
}
}),
{}
);
extendObservable(this.fields, fieldsObj);
}
@computed get isFormValid() {
return !find(this.fields, x => !!x.error);
}
@action setInputFocus = (field, focus) => {
this.fields[field].focused = focus;
}
@action setFieldError = (field, errMsg) => {
this.fields[field].error = errMsg;
}
@action setFieldValue = (field, value) => {
this.fields[field].value = value;
}
@action validateField = (field, rules = '') => {
const validateField = this.fields[field];
const value = { [field]: validateField.value };
const rule = { [field]: rules || validateField.rules };
const validation = new Validator(value, rule);
const isValid = validation.passes();
if (!isValid) {
validateField.error = validation.errors.first(field);
} else {
validateField.error = null;
}
return isValid;
}
@action validateForm = () => {
const fields = {};
const rules = {};
Object.keys(this.fields).forEach((x) => {
fields[x] = this.fields[x].value;
rules[x] = this.fields[x].rules;
});
const validation = new Validator(fields, rules);
const isValid = validation.passes();
// map errors to field
const { errors } = validation.errors;
Object.keys(this.fields).forEach((x) => {
if (!isValid && Object.hasOwnProperty.call(errors, x)) {
this.fields[x].error = validation.errors.first(x);
} else {
this.fields[x].error = null;
}
});
return isValid;
}
@action resetForm = () => {
Object.keys(this.fields).forEach((x) => {
this.fields[x].value = '';
this.fields[x].error = null;
});
}
getFieldValue = field => this.fields[field].value;
getFieldError = field => this.fields[field].error;
isFieldFocused = field => this.fields[field].focused;
}
export default FormStore;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment