Magento 1.9 Validation – Modify Existing Prototype JS Validation Method

magento-1.9prototype-jsvalidation

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!

Best Answer

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;
  }
);
Related Topic