Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow custom variables to be attached to form for use by validators. (extra) #220

Closed
faassen opened this issue Feb 22, 2017 · 12 comments
Closed

Comments

@faassen
Copy link

faassen commented Feb 22, 2017

I have a custom validator function, and to do the validation I need some external information that isn't known when the validator function is defined yet. It could be passed into MobxReactForm just in time though, as this is created just before it's needed, just like the form values. I could create a subclass of MobxReactForm just so I can maintain this extra information, but this seems overkill.

It would be nice if the form constructor could take an additional argument with validation information, say "validationData". The validators then can receive this validationData as a property in the object they receive (like field and form), so they can make use of it when needed.

@faassen
Copy link
Author

faassen commented Feb 22, 2017

Something equivalent of "form.update" would also be handy for this use case.

@foxhound87
Copy link
Owner

You mean in the VJF plugin or others plugins too?

Can you better explain the reference to the update method? You mean a method to update this additional data inside/outside the validation functions?

@faassen
Copy link
Author

faassen commented Feb 23, 2017

I run into this with the function-based validators (not strictly a plugin, right?). I'm not sure it is relevant to other validators. The function based validators are the most flexible, and I have validation rules that depend on the state of the form and external validation data that is loaded from the server. A combination of this information depends on whether a validator fails or succeeds.

I reference the update method as this allows you to update the values in the form without having to construct a new one. Similarly it might be needed in some circumstances to update the validationData without constructing a whole new form, or because the validationData is only known after form construction time.

@foxhound87
Copy link
Owner

foxhound87 commented Feb 23, 2017

The VJF is a plugin driver which is active by default (I'm planning to separate the plugins drivers into separate packages in the future). But I need to think more about on your request and read your message more times to get a better vision of what you need. If you can provide a pseudo-code of what you need would be helpful. Thanks.

@foxhound87
Copy link
Owner

Anyway, I think that extending the form with an extra validationData prop and creating setter/getter methods for this prop, then access the form your validation function:

class MyForm extends MobxReactForm {

  validationData;

  onInit() {
     this.setValidationData( ... );
  }

  getValidationData() { return this.validationData; };
  setValidationData(data) { this.validationData = data; };
}

const form = new MyForm();
form.setValidationData( ... );

export function myValidationFunction({ form }) {
  const data = form.getValidationData();
}

I know, accessing the Form instance from the VJF function is not documented but this is already available, I will update the docs.

If you need you can disable validateOnInit and execute the validation manually after the form initialization into onInit():

this.validate({ showErrors: this.state.options.get('showErrorsOnInit') })

or if you want to get data before the first initial automatic validation I can create another event method like beforeInit(). It seems better than implementing a custom logic only for your needs.

@faassen
Copy link
Author

faassen commented Feb 23, 2017

I know I could subclass form to solve this, but I've avoided subclassing so far, and I have a very complicated form. I think it is a general use case that a validator function needs access to validation data that is dynamically determined . Right now I get this dynamic data from a global store, but it would be cleaner if I could pass this in explicitly (as I really want to get this store in a prop).

@foxhound87
Copy link
Owner

So, this feature can be called 'customData' (I don't find a better name, ideas? Should be generic) as a prop to pass to the constructor with initial data and custom getter/setter functions.

@faassen
Copy link
Author

faassen commented Feb 28, 2017

customData sounds good to me, just a generic mechanism to hook up some data to the form.

@foxhound87
Copy link
Owner

I will implement it using the extra property. It sounds better :D

foxhound87 added a commit that referenced this issue Apr 3, 2017
@foxhound87
Copy link
Owner

Both Form & Fields instances now have access to .state.extra() method which is both a getter and setter. It can set objects & arrays, and can retrieve deep nested props like this:

Set Object:

.state.extra({ 
  nested: { 
    foo: 'bar',
  }, 
});

Get All:

.state.extra();
=> { 
  nested: { 
    foo: 'bar',
  }, 
}

Get Prop:

.state.extra('nested.foo');
=> "bar"

@jbmusso
Copy link

jbmusso commented Feb 6, 2018

Thanks for adding this, useful feature.

Unless I'm mistaken, I believe I found a bug with state.extra() that only occurs during the first form validation ({ validateOnInit: true }). Because the extra state cannot be set right away when instantiating the form, validators during that first validation round will not be able to access that extra state (value: undefined). A workaround is to check for the existence of that state in the validators.

@foxhound87
Copy link
Owner

Thanks for adding this, useful feature.

Unless I'm mistaken, I believe I found a bug with state.extra() that only occurs during the first form validation ({ validateOnInit: true }). Because the extra state cannot be set right away when instantiating the form, validators during that first validation round will not be able to access that extra state (value: undefined). A workaround is to check for the existence of that state in the validators.

Now extra can be also defined in fields definitions

@foxhound87 foxhound87 changed the title allow custom variables to be attached to form for use by validators. allow custom variables to be attached to form for use by validators. (extra) Apr 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants