foxhound87 / mobx-react-form

Reactive MobX Form State Management
https://foxhound87.github.io/mobx-react-form
MIT License
1.09k stars 129 forks source link

Support for rules/related validation with Array path. (DVR) #328

Open davorbadrov opened 7 years ago

davorbadrov commented 7 years ago

I'm not sure if I'm doing something wrong, but I'm trying to make validation work with an array of objects where 2 properties are related to each other, e.g. at least one needs to be present.

In the demo below: members[].id should be required unless the members[].age is present. At least that's the goal, am I doing something wrong or is there a bug in the lib?

Link to the demo

Lib versions:

mobx: 3.3.0 mobx-react-form: 1.32.2 validatorjs: 3.13.5

Output

is form Valid: false
form.values:
{
  "club": {
    "name": "Happy club",
    "city": "New York"
  },
  "members": [{
    "lastname": "Doe",
    "firstname": "John",
    "age": 32,
    "id": ""
  }]
}

errors:
{
  "club": {
    "name": null,
    "city": null
  },
  "members": [{
    "lastname": null,
    "firstname": null,
    "age": null,
    "id": "The id field is required when members[].age is empty."
  }]
}

Code for the demo

import Validator from 'validatorjs';
import MobxReactForm from 'mobx-react-form';

const fields = [
  'club.name',
  'club.city',
  'members',
  'members[].firstname',
  'members[].lastname',
  'members[].age',
  'members[].id'
];

const rules = {
  'club.name': 'string|required|min:3',
  'club.city': 'string|required|min:3',
  'members[].lastname': 'string|required',
  'members[].firstname': 'string|required',
  'members[].age': 'required|integer',
  'members[].id': 'boolean|required_without:members[].age'
};

var values = {
    club: {
      name: 'Happy club',
      city: 'New York'
    },
    members: [{
      lastname: 'Doe',
      firstname: 'John',
      age: 32,
      id: null
    }]
};

function report(form) {
    console.log('is form Valid: ', form.isValid);
    console.log('form.values: ',  JSON.stringify(form.values(), null, 2));
    console.log('errors: ', JSON.stringify(form.errors(), null, 2));
}

class NestedFieldsForm extends MobxReactForm {
  plugins() {
    return {dvr: Validator}
  }
  setup() {
     return {fields, values, rules}
  }
}

const form = new NestedFieldsForm();

form.submit({
  onError: form => report(form),
  onSuccess: form => report(form)
});

Edit: code format fix

foxhound87 commented 7 years ago

Right now using the array notation in the rules is not supported, you should specify the index of the array to validate inside the rule, so I suggest to dynamically create the rules:

const makeMemberIdRules = (id) =>   
  'boolean|required_without:members[' + id + '].age';

form.$('members')
  .each((field) => (field.name === 'id') && 
    field.set('rules', makeMemberIdRules(field.container().name)));

I updated your demo: https://www.webpackbin.com/bins/-Kv7y24BahF4zIdxa1nv

I will implement this feature in the future versions.

foxhound87 commented 7 years ago

Related to #249

davorbadrov commented 7 years ago

Thanks a lot for the swift response. You saved me a lot of grief 👍

simon998yang commented 5 years ago

It's been one year , any progress on this issue? ta

princejoseph commented 4 years ago

@foxhound87 the demo link is not available anymore. Where should I add the code you pasted for array validation to work?