fuzzybabybunny
fuzzybabybunny

Reputation: 5254

Best practice for Meteor AutoForm validation of items not in the form?

AutoForm works great when you want to validate a form using the schema, but oftentimes the form doesn't contain all the data that's in the schema, so you get a validation error.

For example, I have a submit button that is disabled until it determines the form is completely valid, but because the form doesn't contain all the data that's in the schema, it can never show that it's completely valid.

Say that you've got a schema

ShoppingCartSchema = new SimpleSchema({
  itemsOrdered: {
    type: [Object],
    optional: false,
  },
  totalPrice: {
    type: Number,
    optional: false,
  },
  customerAddress: {
    type: Object,
    optional: false
  },
  systemGeneratedInfo: {
    type: Object,
    optional: true,
    blackbox: true
  },
});

ShoppingCarts.attachSchema(ShoppingCartSchema);

My form code would be something like:

{{> quickForm collection="ShoppingCarts" id="shoppingCartForm" type="insert"}}

Obviously you don't want totalPrice to be an item on the form for the user to fill on their own. systemGeneratedInfo could be an object that your code generates based on the form values, but which doesn't appear on the form itself.

You could put totalPrice into a hidden form element but that seems sketchy. You really wouldn't want to do that with systemGeneratedInfo.

What other strategies would there be for tackling items on the object that don't show up on the form, but which still allow the form shown on the front end to be completely validated?

Upvotes: 1

Views: 378

Answers (1)

evolross
evolross

Reputation: 533

You have to make use of the schema field of the quickForm or autoForm. Then you create Template helpers to pass the schema to the form (or if your schemas are available globally you can just pass Schemas.someSchema to the form).

You can either define completely new schemas just for minor form functionality tweaks, which in my mind is overkill if you have a giant nested schema and you just want to omit a couple of fields or...

You can just import the original schema into your template.js and then do an EJSON.clone on it and modify the fields and attributes locally in the helper (or elsewhere) before you pass it to the template.

//  Profile.js

import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { AutoForm } from 'meteor/aldeed:autoform';
import { EJSON } from 'meteor/ejson';

import { Schema } from '../../../api/profiles/profiles.js';

Template.profile.helpers({

  profileSchema: function() {
    let userSchemaForAutoForm = EJSON.clone(Schema.User);
    userSchemaForAutoForm._schema.emails.optional = true;
    return userSchemaForAutoForm;
  }
});
//  Profile.html

{{#autoForm id="profileEditForm" collection="Meteor.users" schema=profileSchema doc=currentUser type="update"}}

Upvotes: 0

Related Questions