NewOldMax / react-form-validator-core

Core validator component for react forms
MIT License
94 stars 44 forks source link

TextValidators not displayed in error state on submit of form when there are validation issues #42

Closed mike-strauch closed 5 years ago

mike-strauch commented 5 years ago

Hello, I'm having an issue with a form that has multiple TextValidators with the same name prop value. I'll try to explain a simplified version of my setup for some context.

I have a component that contains an array of objects of type A. So, for example, each of these A objects has a name, description, etc because they're all of the same type. I'm rendering a form that contains TextValidator components for the fields that are editable on these A objects. So, after rendering an entire form containing form fields for this array of object, there will be multiple TextValidators with the same name prop because I'm using a sub-component to render these objects. In order to update the state of this array of objects, the sub-components just pass an index to a onUpdate handler with the onChange event which is just the browser event. So, using the index and the browser event (and more specifically event.target.name), the parent component knows how to update the correct A object that it is managing because it can index into its array of A objects and then use event.target.name to update the correct field value.

It seems, however, that the ValidatorForm component requires that TextValidator names be unique because of this line where it tries to find a child component of the form that has the same name as the input. If you have more than 1 input with the same name, then that find() call will only ever return the first one (as far as i can tell).

So, I have two questions about that. The first is: should name props of TextValidators be unique? The second is: In my debugging and in that particular piece of code I referenced, input is always a TextValidator component, so why would you then need to find a child component with the same name if you've already got the component? If that code just used the input param passed to the validate function, then I think my issue would be solved because the submit()->walk()->checkInput() function chain wouldn't care about matching names, it would just go through each form field and validate them regardless of names.

This is a problem mainly on submit because the default onSubmit handler in ValidatorForm rolls through all of its managed inputs and checks to see which ones are invalid by name (and has runs into the issue I mentioned above). So, currently the form I have will only display the first field with a given name as being invalid and any others will just remain in a normal state (no error message, no red outline, etc.)

Sorry for being a bit long-winded. Any advise?

NewOldMax commented 5 years ago

Hi,

sorry, don't have too much time right now for answer, but in ideal world html form must not have inputs with the same name, because values will be overwritten for inputs with same names. So I followed this convention

mike-strauch commented 5 years ago

Hello!

sorry, don't have too much time right now for answer,

No worries, I appreciate the response.

but in ideal world html form must not have inputs with the same name, because values will be overwritten for inputs with same names

I'm not sure this is entirely true since you can and usually do have radio and/or checkbox inputs that have the same name. I think since inputs can have an id to make them unique having unique names is not really required. It's mostly up to the server to make sense of post data that has the same key (in this case the input name).

NewOldMax commented 5 years ago

If you will have text inputs with same name, server can't handle values correctly.

unique_name = value

So in case of radio inputs it's ok, because you're sending one value of them:

<radio name="abc" value="a" />
<radio name="abc" value="b" />

"abc" param can be "a" or "b" and that's fine.

But in case of text inputs it's not valid:

<textinput name="email" value="a@a.a" />
<textinput name="email" value="b@b.b" />

What value will be sent to backend? "a@a.a" or "b@b.b"? But you need both of them. You can avoid this case with name="email[]", backend will get an array. Also you can handle this with current library by adding indexes (so names will be unique):

<textinput name="email[0]" value="a@a.a" />
<textinput name="email[1]" value="b@b.b" />

Anyway I plan to remove that 'unique name' requirement in future

mike-strauch commented 5 years ago

What value will be sent to backend? "a@a.a" or "b@b.b"? But you need both of them.

The browser will send both. In the case of using the get method on the form, the browser would just append the values onto the url like ?email=a&email=b. A post would basically basically do the same thing just not in the url.

You can avoid this case with name="email[]", backend will get an array.

That's really up to the backend you're using, though. As far as I've seen, there's nothing in the actual html spec that says you can't or shouldn't do it.

Anyway I plan to remove that 'unique name' requirement in future

That'd be great! If I get some time, I can submit a pull request for what I think would need changing if that would help things along.

Thanks!

NewOldMax commented 5 years ago

Please check the 0.6.1 version

mike-strauch commented 5 years ago

Awesome, thanks!