9

I have a need for users to be able to create partial URLs without needing to type the full URL each time.

For example, say I plan on the url being www.example.com/areas/{userinput}/home. I want the user to be able to enter some text in a text box and I want to validate that it is a valid URL.

The URL validator functions like this:

url: function(value, element) {
        return this.optional(element) || /giantregex/.test(value);
}

I've attempted adding a validation method to the validator via the following:

$.validator.addMethod("exturl", function(value) {
    return $.validator.methods.url.call($.validator, "http://www.example.com/areas/" + value + "/home");
});

However, when the form is validated and my extension is called, I keep getting this error:

Uncaught TypeError: Object function (d,a){this.settings=b.extend(true,{},b.validator.defaults,d);this.currentForm=a;this.init()} has no method 'optional' 

optional looks to be a method on the $.validator object but I can't figure out how to call the validator url method.

2 Answers 2

17

jQuery Validation Plugin - v1.11.0

jQuery.validator.addMethod("complete_url", function(val, elem) {
    // if no url, don't do anything
    if (val.length == 0) { return true; }

    // if user has not entered http:// https:// or ftp:// assume they mean http://
    if(!/^(https?|ftp):\/\//i.test(val)) {
        val = 'http://'+val; // set both the value
        $(elem).val(val); // also update the form element
    }
    // now check if valid url
    // http://docs.jquery.com/Plugins/Validation/Methods/url
    // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
    return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(val);
});

Then:

$("#form1").validate({
    rules: {
        complete_url:true
    }
});

From http://www.robsearles.com/2010/05/jquery-validate-url-adding-http/

Sign up to request clarification or add additional context in comments.

2 Comments

if(!/^(https?|ftp):\/\//i.test(val)) { This line is commented out as because of //
Your code is missing this.optional(element)... pretty important stuff. Without it, you cannot leave this field blank, even when you want the field to be optional!
2

I managed to make it work without errors, here is the JS code I used:

$(document).ready(function(){

    function validateURL(value){
      // URL validation from http://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url
      var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
      var regex = new RegExp(expression);
      return value.match(regex);
    }

    $.validator.addMethod("urlvalidation", function(value, element) {
      return this.optional(element) || validateURL(value);
    }, "URL is not valid");

    $('#frm_validation').validate({
      rules : {
          urlvalidation : { urlvalidation : true }
      }
    });  

});​

You can see it in action on this JSFiddle.

4 Comments

This still requires that I copy the regex. It has to be possible to create my url from user input before validating that it's a valid URL and then calling the internal URL validate method to validate my formatted string.
Ok, I didn't understand that the requirement was to avoid copying the regex. In that case, why don't you call your URL validation function like so return this.optional(element) || urlValidationFunction(value)?
That's exactly what I did and outlined in the question. I ended up with the errors also in the question.
I edited my answer, tell me if it satisfies your requirements.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.