Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"keyword-spacing": ["warn", {"after": true}],
"jsx-quotes": ["warn", "prefer-double"],
"no-extra-boolean-cast": "off",
"no-console": 0,
"no-multi-spaces": "warn",
"no-spaced-func": "warn",
"no-unused-vars": "warn",
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ If there are many rules, the their priority will be similar to the array order.

## Api

### constructor({FieldsDescription}, errorsStorageName = 'validationStorage')
### constructor({FieldsDescription}, validationStorageName = 'validationStorage')
Describe in the constructor all the fields, that you will check. Like in the [example](#form-example).
By default all validation data will be added to the 'validationStorage' key of the state object. You can change it, if you need. You can describe for each field [1 or many rules](#creating-validation-rules).

Expand Down Expand Up @@ -228,7 +228,11 @@ this.setState(
Use this method inside the render function, like in the [example](#form-example). It will return the object with fields keys and their error messages. If the field is valid there will be an empty error string.

### isFormValid({state})
Use this method to check, if the field is valid. It will return true, if all the fields in the form are valid. See the [example](#form-example)
Use this method to check, if the form is valid. It will return true, if all the fields in the form are valid. See the [example](#form-example)

### isFieldValid({state}, fieldName)
Use this method to check, if particular field is valid. Returns true if it is valid, false otherwise


## Compatibility
This package id fully compatible with the React v.16, because it uses state updater functions inside.
22 changes: 22 additions & 0 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,27 @@ describe('Unit tests for Validation class', () => {
state = Object.assign({}, state, result);
expect(Validator.isFormValid(state)).toEqual(true);
});

test('Validator.isFieldValid(state,"login") method returns false', () => {
const updater = Validator.validate({
login: ''
});
const result = updater(state);
state = Object.assign({}, state, result);
expect(Validator.isFieldValid(state, 'login')).toEqual(false);
});

test('Validator.isFieldValid(state,"password") method returns true', () => {
expect(Validator.isFieldValid(state, 'password')).toEqual(true);
});

test('Validator.isFieldValid(state,"login") method returns true after login field became validated', () => {
const updater = Validator.validate({
login: 'peterson'
});
const result = updater(state);
state = Object.assign({}, state, result);
expect(Validator.isFieldValid(state, 'login')).toEqual(true);
});
});
});
47 changes: 36 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Validation {

constructor(
fields: FieldsDescription,
errorsStorageName: string = 'validationStorage'
validationStorageName: string = 'validationStorage'
) {
if (typeof fields !== 'object') {
throw new Error('Invalid fields parameter for fields, must be object');
Expand All @@ -48,7 +48,7 @@ class Validation {
this.fields = allRulesInArrays(fields);
this.fieldsToValidateList = [];
this.fieldsToShowErrors = [];
this.storage = errorsStorageName;
this.validationStorageName = validationStorageName;
this.statuses = [
'validation-passed',
'prevalidation-failed',
Expand Down Expand Up @@ -94,7 +94,7 @@ class Validation {
);

return Object.assign(state, {
[this.storage]: toStorage
[this.validationStorageName]: toStorage
});
}

Expand Down Expand Up @@ -129,7 +129,7 @@ class Validation {
// computing the state as a merge from prevState and stateUpdates to do the right validation
let state = Object.assign({}, prevState, stateUpdates || {});
// clean the service error storage field, so the rule will have no acces to it
delete state[this.storage];
delete state[this.validationStorageName];
keysToValidate.map(key => {
if (this.fields[key]) {
toStorage[key] = this._validateField(
Expand All @@ -142,7 +142,11 @@ class Validation {
});
this.fieldsToShowErrors = [];
return Object.assign(stateUpdates || {}, {
[this.storage]: Object.assign({}, prevState[this.storage], toStorage)
[this.validationStorageName]: Object.assign(
{},
prevState[this.validationStorageName],
toStorage
)
});
};
}
Expand Down Expand Up @@ -185,7 +189,7 @@ class Validation {
const validationFailed = this.statuses[2];

keys.map(key => {
const current = state[this.storage][key];
const current = state[this.validationStorageName][key];
// check every rule
for (let i = 0; i < current.length; i++) {
if (current[i] === validationFailed) {
Expand All @@ -202,15 +206,15 @@ class Validation {
}

isFormValid(state: Object): boolean {
const errors = state[this.storage];
if (typeof errors !== 'object') {
throw new Error('Invalid errors parameter for fields, must be object');
const storage = state[this.validationStorageName];
if (typeof storage !== 'object') {
throw new Error('Invalid fieldsMappedToStatuses object, must be object');
}

const keys = Object.keys(errors);
const keys = Object.keys(storage);
const [validationPassed] = this.statuses;
for (let i = 0; i < keys.length; i++) {
const currentStatuses = errors[keys[i]];
const currentStatuses = storage[keys[i]];
for (let j = 0; j < currentStatuses.length; j++) {
if (currentStatuses[j] !== validationPassed) {
return false;
Expand All @@ -220,6 +224,27 @@ class Validation {
// if form valid return true
return true;
}

isFieldValid(state: Object, fieldName: string): boolean {
const storage = state[this.validationStorageName];
if (typeof storage !== 'object') {
throw new Error('Invalid storage object, must be object');
}
const fieldStatuses = storage[fieldName];
if (!fieldStatuses) {
// TODO: how to disable warnings in production
console.warn("Attempt to validate field that doesn't exist");
return false;
}

const [validationPassed] = this.statuses;
for (let j = 0; j < fieldStatuses.length; j++) {
if (fieldStatuses[j] !== validationPassed) {
return false;
}
}
return true;
}
}

const allRulesInArrays = (
Expand Down