4

I'm having a little bit of difficulty trying to do this cleanly, and the majority of docs/posts I've seen about this typically involve adding a new custom validation method. I want to just add an extra piece of functionality to the existing validate() method to capture when form validation is failed. If I extend the class, it seems like I would have to duplicate the full validate() function (I may be wrong here but that was the result I was getting). I could just do that but I'm sure it can't be the best way to handle this.

It looks like what I'm after is wrapping the existing function with the additional functionality I want to add. However this is throwing an error.

My code is currently:

Validation.prototype.validate = Validation.prototype.validate.wrap(function(parentMethod){
    parentMethod();

   // I want to add some logic here when validation errors have been triggered
});

The above code generates the following error: prototype.js:429 Uncaught TypeError: wrapper.apply is not a function

Any help much appreciated!

1
  • I wish I was in front of my computer right now, this one is a piece of cake. If still without an accepted answer when I get home later, I will post the instructions. In the meantime, you should search the source code for Validation.addAllThese(.... Commented Aug 19, 2016 at 23:01

2 Answers 2

5

Here is how you can either override an existing validation method or create your own. There is only one js snippet below bc its the exact same procedure for either one. In my example, I override an existing Magento validation type.

First, add your custom js file to whatever page(s) you need:

<reference name="head">
    <action method="addItem"><type>js</type><file>my/custom/validation.js</file></action>
</reference>

Then create your js file following this example:

Validation.addAllThese([
  ['validate-zero-or-greater', 'This is my custom error message', function(v) {
    if(something){
      return false;
    } else {
      return true;
    }
  }]
]);

I tested this before posting.

Update:

In your javascript file, the below snippet will catch ALL failed js validation. If you reach the inside of the "if" statement, then you can attempt to log with javascript but you will most likely need to send the data to a controller using ajax.

Validation.prototype.validate = Validation.prototype.validate.wrap(
  function(parentFunction) {
    var result = parentFunction();
    if(!result){
      var form = this.form;
      for (var i in form) {
        if (form.hasOwnProperty(i)) {
          var element = form[i];
          if(element.hasClassName('validation-failed')){
            alert(element.id);
          }
        }
      }
    }
    return result;
  }
);

This one logs to the console if that's what you are looking for.

Validation.prototype.validate = Validation.prototype.validate.wrap(
  function(parentFunction) {
    var result = parentFunction();
    if(!result){
      var form = this.form;
      for (var i in form) {
        if (form.hasOwnProperty(i)) {
          var element = form[i];
          if(element.hasClassName('validation-failed')){
            console.log('Element ID is ' + element.id + '. The failed value is \'' + element.value + '\'');
          }
        }
      }
    }
    return result;
  }
);
10
  • Cheers Shawn - I'm possibly missing something obvious here, but my situation is wanting to catch any situation where validation fails, and then log that info along with the details of the field which triggered the failure. I want to hook into Validation.validate() to add this, without changing any of the rest of the validate() functionality.
    – bsod99
    Commented Aug 20, 2016 at 3:17
  • You will most likely need to create a controller then. The idea would be to catch any failed validation then send that data to the controller using ajax. In that controller, the logging action would take place. Im gonna see what I can do to create a catchall for ANY failed validation. At which point you can decide how to process the data. Commented Aug 20, 2016 at 3:21
  • I think it can stay just client side, as it's not required to write to the Mage logs. e.g in the original validate method, the following is what i'd like to do: `if(!result && this.options.focusOnError) { try{ Form.getElements(this.form).findAll(function(elm){ if ($(elm).hasClassName('validation-failed')) { console.log($(elm)); } return $(elm).hasClassName('validation-failed'); }).first().focus(); } catch(e){ } }
    – bsod99
    Commented Aug 20, 2016 at 3:37
  • I just updated the answer to demonstrate how to catch ALL failed validation as well as get the form itself and also get the form inputs serialized although it sounds now like you can do without the serialized data. Commented Aug 20, 2016 at 3:39
  • @bsod99 I just changed the last snippet to show you all elements with failed validation. Commented Aug 20, 2016 at 3:47
0

If:

  1. You don't need this to apply to all forms
  2. You just need to know if the form did not validate when submitted

then you try adding an else{} statement whenever the VarienForm is initiated. I say add an else{} statement because most forms on Magento already have the if( this.validator.validate()) statement.

var productAddToCartForm = new VarienForm('product_addtocart_form');

productAddToCartForm.submit = function(button, url) {
    if (this.validator.validate()) {
        // code for submitting the form if it validates
    } else{
        // form is not valid, you can add custom code here on a form by form basis
    }
}.bind(productAddToCartForm);
1
  • Thanks, but alas I need to apply this globally and to capture which form fields caused the validation error.
    – bsod99
    Commented Aug 19, 2016 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.