Model object for form validation In order to perform form validation, I have created a custom object:  

define(["jquery", "validate", "activities/new/common/components/BaseFormdata"], 
    function($, Validate, BaseFormData){ 

    var FormData = function(options){ 

        this.defaults = { 
            name: "", 
            privacy: "", 
            price: "", 
            short_description: "", 
            long_description: "" 
        }; 

        //Constraints to be used by the validation library 
        this.constraints = {
            name: { 
                presence: true, 
                length: { maximum: 100, minimum: 1 }
            }, 
            privacy: {
                presence: true
            }, 
            short_description: { 
                short_description: true, 
                length: { maximum: 20 }
            }, 
            max_description: { 
                length: { maximum: 1000 } 
            } 
        }; 

        this.formData = $.extend({}, this.defaults, options); 

    }; 

    //Inherit from the BaseFormData component 
    FormData.prototype = new BaseFormData(); 

    return FormData; 
});  


The base FormData object: 

define(["underscore", "validate"], function(_, Validate){

    //Defines a Base FormData object that modules can use to inherit from 
    function BaseFormData(){}; 

    /*@param: 
     * object containing to be validated properties 
     * @return: 
     * Success returns false (no error), Error returns an error object 
     */
    BaseFormData.prototype.validateProperties = function(objToValidate){ 

        var constraints = this.getConstraints(objToValidate); 

        var status = validate(objToValidate, constraints, {format: "detailed"}); 
        if(status === undefined){ 
            //There is no error 
            for(var key in objToValidate){ 
                if (this.formData.hasOwnProperty(key)) { 
                    //Set the value on the this.formData object 
                    this.setProperty(key, objToValidate[key]); 
                }; 
            }; 
            //Return no error 
            return false; 

        } else { 
            //An error object is returned 
            return status; 
        } 
    }; 

    //Set property on object 
    BaseFormData.prototype.setProperty = function(key, value){ 
        this.formData[key] = value; 
    }; 

    //Get relevant constraints from constraints object 
    BaseFormData.prototype.getConstraints = function(objToValidate){ 
        //Get keys in array 
        var arrKeys = _.allKeys(this.constraints); 
        var constraints = {}; 
        _.each(arrKeys, _.bind(function(key){ 
            if(objToValidate.hasOwnProperty(key)){ 
                constraints[key] = this.constraints[key]; 
            }; 
        }, this)); 

        return constraints; 
    }; 

    return BaseFormData; 
});


Is it bad practice to set the form properties immediately on the FormData object? Currently, I have per form one custom FormData object that inherits from the Base FormData object, for which I have set custom properties depending on the form components.  

I wonder if it would be better to inject the form fields as a collection of objects in a single FormData object (instead of creating one for each form); this would allow me to define only the base FormData object, but it would require the calling function to also send the constraints along (which is in my case a presenter object that coordinates between the different views that manage the form).

Which is the best approach architectural-wise?
First of all, I think creating a constructor for each form type is overkill. All you need from that subclass are defaults and constraints. Why not remove all that wrapper code and just have the module return defaults and constraints?

// FormDataRules.js
define(function(require, exports, module){
  exports.defaults = { ... };
  exports.constraints = { ... };
});


Then create a validation module that contains all your validation APIs. Doing the above, setProperty falls off since you'll be operating on plain objects. 

getConstraints also falls off leaving you with validateProperties which we can just rename to validate - which is a huge operation which just delegates checking to subfunctions inside the module.

// Validator.js
define(function(require, exports, module){

  exports._validateNumbers = function(data, constraint){ ... }
  exports._validatePresence = function(data, constraints){ ... }

  exports.validate = function(data, constraints){
    /* Huge operation to validate each item with each constraint it comes */
  };
});


Here's sample code using above.

define(function(require){
  var Validator = require('Validator');
  var FormDataRules = require('FormDataRules');
  var _ = require('lodash');

  var dataWithDefaults = _.defaults({
    // instance stuff
  }, FormDataRules.defaults);

  var isDataPassed = Validator.validate(dataWithDefaults, FormDataRules.constraints);

});


This makes everything easy to test. FormDataRules are just objects you can simply check values. Validator is a bunch of functions you can simply test by throwing values at it. All the data that mutates lives in a plain object that we have hold to (dataWithDefaults), and not something internal to the validator nor the rules.