code-learner
code-learner

Reputation: 51

Jquery .apply() not a function error, from instantiated object

I have an object that I am trying to instantiate so I can create different instances of it, that checks against different Regex patterns.

On input + blur the input gets either a success/error class depending if the regex pattern is matched.

I have tried everything I possibly know, but it says "Uncaught TypeError: ((r.event.special[g.origType] || {}).handle || g.handler).apply is not a function"

LINK to code example = JS Fiddle

This is the raw js only:

$(document).ready(function() {
    validate();

function validate() {
    var RegexCheck = (function(window, undefined) {
        this.check = function check() {
            validator = {
                email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,                    
                text: /^[a-zA-Z ]*$/
            };
            var isEmpty, pattern, result, elem = this.value;
            isEmpty = !elem;
            pattern = validator.email;
            result = pattern.test(elem);
            if (result === false || isEmpty) {
                $(this).removeClass('success');
                $(this).addClass("error");
            } else {
                                    $(this).removeClass('error');
                $(this).addClass("success");
            }
        };
        return check;
    })(window);

            // Instansiate RegexCheck
    var RegexCheckEmail = new RegexCheck();
    RegexCheckEmail.pattern = validator.email;
    console.log("RegexCheckEmail.pattern = " + RegexCheckEmail.pattern);
    //Change value of 'pattern'
    RegexCheckEmail.pattern = validator.text;
    console.log("RegexCheckEmail.pattern = " + RegexCheckEmail.pattern);

    //$('form#form1 [type=email]').on('input blur', RegexCheck); //works
    $('form#form1 [type=email]').on('input blur', RegexCheckEmail); //doesn't work

    console.log(RegexCheckEmail instanceof RegexCheck); //true

    var RegexCheckText = new RegexCheck();
    RegexCheckText.pattern = validator.text;
    console.log("RegexCheckText.pattern = " + RegexCheckText.pattern);
    $('form#form-1 [type=text]').on('input blur', RegexCheckText); //Seems like I can instaniate from RegexCheck but just does not seem to work
}
});

Upvotes: 0

Views: 298

Answers (1)

Borys Serebrov
Borys Serebrov

Reputation: 16172

I think you do not understand clearly how classes and objects work.

The function you have first is a constructor, it should define which properties and methods the object has, there is no sense returning check from it (or return anything else as it will not be used as regular function). See more about objects and constructors here: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS.

The event handler expects the function, and you are passing the object (RegexCheckEmail). So the first fix is to pass the function into the event handler and not the object.

Next you do some assignments like RegexCheckEmail.pattern = validator.email, which does not make much sense. You just add the new pattern property to RegexCheckEmail object, this is not the same as pattern variable that is used inside the check function. And the validator.email also only exists inside your check function. Instead of these assignments you should use the object constructor to pass the parameters.

See below the working example, it is close to the idea you try to implement in your code, but it is simpler and, I hope, clearer.

$(document).ready(function() {
		validate();
    
    function validate() {
    
        validator = {
            email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
            text: /^[a-zA-Z ]*$/
        };
    
        function RegexCheck(pattern) {
            this.pattern = pattern;
            
            this.check = function check(input) {
                var isEmpty, pattern, result, elem = input.value;
                isEmpty = !elem;
                result = this.pattern.test(input.value);
                if (result === false || isEmpty) {
                    $(input).removeClass('success');
                    $(input).addClass("error");
                } else {
                    $(input).removeClass('error');
                    $(input).addClass("success");
                }
            };
        };
        
        var regexCheckEmail = new RegexCheck(validator.email);
        $('#exampleEmail').on('input blur', function() {regexCheckEmail.check(this)});

        var regexCheckText = new RegexCheck(validator.text);
        $('#exampleText').on('input blur', function() {regexCheckText.check(this)});
	}
});
.container{margin-top: 50px;}

.error{
  border: 1px solid red;
}

.success{
  border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="row">
    
      <form id="form1">
     
          <div class="col-sm-12">
            <div class="form-group">
              <label for="exampleEmail">Email</label>
              <input type="email" class="form-control" id="exampleEmail" placeholder="Email">
            </div>
          </div>

          <div class="col-sm-12">
            <div class="form-group">
              <label for="exampleText">Text only</label>
              <input type="text" class="form-control" id="exampleText" placeholder="Text only">
            </div>
          </div>
          
        </form>
        
    </div>
</div>

Upvotes: 1

Related Questions