user160820
user160820

Reputation: 15220

Javascript - Strategy Pattern suggestion required

I have a Javascript form validator function something like

 switch (element.getAttribute('validationtype')) {

        case 'text':
            if (cic.visible(element)) {
                if (cic.getValue(element).strip() == "") {
                    errors.push(element.getAttribute('validationmsg'));
                    element.style.border = "1px solid #B23232";
                } else {
                    element.style.border = "1px solid #CAD5DE";
                }
            }
            break;

        case 'textarea': if (element.value.strip() == "") {
                errors.push(element.getAttribute('validationmsg'));
            }
            break;

        case 'email':
            if (!cic.isEmail(cic.getValue(element))) {
                errors.push(element.getAttribute('validationmsg'));
                element.style.border = "1px solid #B23232";
            } else {
                element.style.border = "1px solid #CAD5DE";
            };
            break;

        case 'numeric':
            if (cic.getValue(element).strip() == "" || isNaN(cic.getValue(element).replace(',', '.'))) {
                errors.push(element.getAttribute('validationmsg'));
                element.style.border = "1px solid #B23232";
            } else {
                element.style.border = "1px solid #CAD5DE";
            };
            break;

    }

Everytime I need a new validation type I have to change the function. What should be the best way to organize this function as a class, so that it is closed to change.

Upvotes: 4

Views: 1354

Answers (4)

itea
itea

Reputation: 444


function validate(e) {
  var v = this.vMap[e.getAttribute('validationtype')];
  v && v(e);
}
validate.vMap = {
  'text': function(element) {
    // validate codes
  }, 'textarea': function(element) {
    // validate codes
  }/* ... and so on */
};

// to use
validate(document.getElementById('aId'));

Upvotes: 1

gblazex
gblazex

Reputation: 50109

You need to find the common parts in validation and the type specific ones (Don't Repeat Yourself).

// Type Specific Validation  
var Validator = {
  "text": function (data) {
       // validate text
  },
  "email": function (data) {
       // validate email
  },
  // ...
}

Inside your function:

// Common Validation
var type = el.getAttribute('validationtype');
var isValid = Validator[type];

if ( cic.visible(el) ) { 
  if ( !isValid(el) ) {
    element.style.border = "1px solid #B23232";
    errors.push(element.getAttribute('validationmsg'));
  } else {
    element.style.border = "1px solid #CAD5DE";
  }
}

Upvotes: 3

rickythefox
rickythefox

Reputation: 6851

Instead of implementing this yourself, how about using jQuery Validation plug-in?

Upvotes: 1

David Mårtensson
David Mårtensson

Reputation: 7620

You need to find a way to encode each validation rule in some portable format, string or maybe JSON that is easy to generate automatically.

Then you need to change the function to parse these rules.

The format might be

{
    [
        {"fieldname":"something","validationtype":"minmax","arguments":{"min":10,"max":20}}
        , {"fieldname":"somethingelse","validationtype":"largerthanfield","arguments":{"field":""something}}
    ]
}

This would then test that field something is in the range of 10 to 20 and that something2 is larger than something.

Which rule options you should implement depends on your solution and there can be almost any numer of variants.

Upvotes: 0

Related Questions