Ricky
Ricky

Reputation: 275

jQuery validation regex: multiple rule checks, same field

I have a jQuery validation regex that checks if phrase(s) are included:

$.validator.addMethod("regex", function(value, element, regexp) {
    return this.optional(element) || regexp.test(value);
}, "You must include the required keyword phrase(s).");

If I have multiple phrases to check, i'm adding them with:

$("#text").rules("add", { regex: /phrase one/i });
$("#text").rules("add", { regex: /another phrase/i });
$("#text").rules("add", { regex: /test phrase/i });

The problem i'm having is that it only checks for the last phrase rule, meaning if "test phrase" is included, but the others aren't, it will accept it. I need it to check to make sure all phrases are included.

I would also like the error message to be able to include the phase that's missing, example, if "another phrase" is missing, the error will be:

You must include the required phrase: another phrase

Thx

Upvotes: 1

Views: 2538

Answers (2)

Halconit
Halconit

Reputation: 21

I used Box9 answer, and fixed the problem him and Ricky were having about the message being overwritten with "Warning: No message defined for..." So the complete and working solution would be this:

Quoting Box9:

You should make a method specific to the requirement, rather than going for the generic regex:

$("form").validator(/* options */);

$.validator.addMethod("multiPhrases", function (value, element, phrases) {
  var missingPhrase, errObject = {};

  // Check for all the phrases
  for (var i = 0; i < phrases.length; i++) {
    if (value.toLowerCase().indexOf(phrases[i].toLowerCase()) < 0) {
       // Phrase not found
       missingPhrase = phrases[i];
       break;
    }
  }

  // Set the message as default for this validation
  if (missingPhrase) {
    errObject["multiPhrases"] =
        "You must include the required phrase: " + missingPhrase;
     jQuery.extend(jQuery.validator.messages, errObject);
  }

  // Tell the plugin if there was an error
  return (missingPhrase == false);
});

Instead of showing the error yourself, as Box9 initially proposed with showErrors(), you must set it as the default message for this validation, because jQuery.validation plugin will look for the default anyway, and overwrite any previous error shown for this element.

Quoting Box9 again:

This requires your input to have a name attribute.

Use it like so:

$("#text").rules("add", {multiPhrases: [
   "phrase one",
   "another phrase",
   "test phrase"
]});

Thank you Box9 and Ricky for initially posting this, as it helped me find the solution.

Upvotes: 0

David Tang
David Tang

Reputation: 93694

You should make a method specific to the requirement, rather than going for the generic regex:

var vInstance = $("form").validator(/* options */);

$.validator.addMethod("multiPhrases", function (value, element, phrases) {
   var missingPhrase, errObject = {};

   // Check for all the phrases
   for (var i = 0; i < phrases.length; i++) {
      if (value.toLowerCase().indexOf(phrases[i].toLowerCase()) < 0) {
         // Phrase not found
         missingPhrase = phrases[i];
         break;
      }
   }

   // Show the error yourself
   if (missingPhrase) {
      errObject[$(element).attr("name")] =
         "You must include the required phrase: " +
         missingPhrase;
      vInstance.showErrors(errObject);
   }

   // Tell the plugin if there was an error
   return (missingPhrase == false);
});

This requires your input to have a name attribute, and you need to save a reference to the validator object (vInstance) when it's created. It's the best hack I can think of after looking at jQuery validator's API. IMO, a decent validation plugin should let you return a custom error message from the custom function...

Use it like so:

$("#text").rules("add", {multiPhrases: [
   "phrase one",
   "another phrase",
   "test phrase"
]});

Upvotes: 1

Related Questions