text: var bestNameFromField = function(field) {
    var msg = field.attr("data-st-name") || field.attr("name");
  
    if (!msg) {
      msg = 'Field';
    }
  
    return _.capitalize(msg);
  };
  
  SirTrevor.BlockValidations = {
  
    errors: [],
  
    valid: function(){
      this.performValidations();
      return this.errors.length === 0;
    },
  
    // This method actually does the leg work
    // of running our validators and custom validators
    performValidations: function() {
      this.resetErrors();
  
      var required_fields = this.$('.st-required');
      _.each(required_fields, this.validateField, this);
      _.each(this.validations, this.runValidator, this);
  
      this.$el.toggleClass('st-block--with-errors', this.errors.length > 0);
    },
  
    // Everything in here should be a function that returns true or false
    validations: [],
  
    validateField: function(field) {
      field = $(field);
  
      var content = field.attr('contenteditable') ? field.text() : field.val();
  
      if (content.length === 0) {
        this.setError(field, bestNameFromField(field) + " must not be empty");
      }
    },
  
    runValidator: function(validator) {
      if (!_.isUndefined(this[validator])) {
        this[validator].call(this);
      }
    },
  
    setError: function(field, reason) {
      var $msg = this.addMessage(reason, "st-msg--error");
      field.addClass('st-error');
  
      this.errors.push({ field: field, reason: reason, msg: $msg });
    },
  
    resetErrors: function() {
      _.each(this.errors, function(error){
        error.field.removeClass('st-error');
        error.msg.remove();
      });
  
      this.$messages.removeClass("st-block__messages--is-visible");
      this.errors = [];
    }
  
  };