dalgard / meteor-viewmodel

Minimalist VM for Meteor
24 stars 2 forks source link

What is the best way to do form validation with ViewModel? #3

Closed frabrunelle closed 8 years ago

frabrunelle commented 8 years ago

This is more of a general question but I think it could be very useful to people who want to use ViewModel.

I am wondering what is the best way to do form validation with ViewModel in your experience?

For example, when the user submits a ViewModel form, I would like to add the has-error and form-control-error class (http://v4-alpha.getbootstrap.com/components/forms/#validation) to the fields that contain errors (based on the validation of the model) and also display an error message under each field that has a validation error. This is easy to do with Autoform (or Astronomy) but I can't really use Autoform with a ViewModel form.

I was doing some tests with integrating meteor-astronomy (it's equivalent to SimpleSchema + Collection2, but it's highly modularized and I think it's very promising). It works fine for the server-side, but I am not sure how to integrate it for the client-side (normally it's easy, but I am not really able to make it work with a ViewModel form).

It's not a blocker because at least I have server-side validation and for most fields I can do the client-side validation using HTML5 attributes such as required, maxlength, min, max, pattern, etc. In some cases it could be useful to display a message if for example the user is entering a username that has already been taken by someone else. But I am not in a rush to find a good solution, I can implement the main parts of my apps and do proper client-side validation in a month or two. I can take the time to experiment with many approaches if necessary.

I saw the new classes binding and I am wondering if maybe it would be useful for when I want to add the has-error class. But before thinking too much about how to make this work, I thought I would ask you because you might already have a good solution :smiley:

My question to you is: do you know a good pattern to do client-side form validation with ViewModel? If yes, could you show an example? :smile:

And do you think there is a way to take advantage of a schema package such as Astronomy or SimpleSchema/Collection2 so that it's possible to only have to define the schema for a model one time and use the same validations on both the client and server? Maybe with ViewModel it's not possible to do that, I am not sure. Or if it is, what solution are you currently using?

I would really appreciate your opinion on this. Thank you very much :smile:

dalgard commented 8 years ago

You can simply make the "invalid" styling of the form field depend on a computed property on the viewmodel. The computed property retrieves a normal property, checks whether it is valid and returns the result.

<input class="{{#if isEmailInvalid}}has-error{{/if}}" {{bind 'value: email'}}>
{
  email: "",
  isEmailInvalid() {
    // Do not actually validate email addresses this way.... ;)
    return this.email().indexOf("@") >= 0;
  }
}

It's not very practical using the classes binding for this, because you can only have one has-error attribute on the viewmodel, and it may contain many form fields.

Having said that, on larger projects I would definitely use AutoForm instead of writing my own forms with ViewModel :+1:

dalgard commented 8 years ago

It would be possible to make a set of custom bindings that hook directly up to AutoForm, but that's a whole other story.

If one wasn't using AutoForm, one could probably make some bindings that check for a certain type and either save the value or mark the field as invalid with a class.

The possibilities with custom bindings are pretty much endless.

frabrunelle commented 8 years ago

I ended up using Astronomy alone for the admin forms I was creating (for example, the forms let an admin add or edit a member, etc.). I followed the example here. The advantage is that I can easily show the error messages under a specific field.

I'm still using ViewModel for my signup and login form, that's a great place to use it since I don't use Astronomy to validate the Meteor.users collection and I just show the error messages with meteor-toastr.

As a develop my application in the next 4 weeks, I'm sure there will be many places where I can use ViewModel. For example, there will be a complex form that lets the user place an order and I'll try to use ViewModel when I implement that this week.

Thank you for your help :+1:

dalgard commented 8 years ago

Feel free to create more issues in the future.