Maarten de Graaf
Maarten de Graaf

Reputation: 526

Uncaught TypeError: Cannot read property 'length' of undefined when there is a parent

Alright, so check this out

http://jsfiddle.net/J9Tza/

<form class="validation">
<div>
<input type="email" class="form-control" id="inputEmail" name="email" placeholder="Email" pattern=".{3,200}" title="3 to 200 characters" required="required">
    </div>
</form>

I'm working on a form validation script and want to use the HTML5 attributes for this. I'm not sure if this is the most handy way (tips are welcome) but in this case I'm trying to get the minimum amount and maximum amount of allowed characters.

If you look at the console, everything seems to work fine apart from the "Uncaught TypeError: Cannot read property 'length' of undefined" error. It is strange since it isn't even undefined.

So this fixes it http://jsfiddle.net/J9Tza/1/

<form class="validation">
    <input type="email" class="form-control" id="inputEmail" name="email" placeholder="Email" pattern=".{3,200}" title="3 to 200 characters" required="required">
</form>

I removed the surrounding element and now it works but without any errors.

How to fix this? And is there a better way to do this? (might be a bit off-topic)

Greetings

Upvotes: 0

Views: 10391

Answers (1)

Arun P Johny
Arun P Johny

Reputation: 388346

it is because of event propagation, the keyup event is propagated to the div(which is selected because of the selector :not([type])) element where there is no pattern attribute. So pattern = that.attr('pattern') will be undefined

You need to tweak the :not([type]) selector to select only input elements without type attribute. But you can combine the [type="text"], :not([type]) selectors to input:text.

Also since you are interested in only elements with pattern attribute you can add it also to the selector

$('form.validation').find('input:text[pattern], input[type="email"][pattern], input[type="password"][pattern]').each(function () {
    $(this).on('keyup', function () {
        var that = $(this),
            pattern = that.attr('pattern');

        console.log(this, pattern)

        pattern_array = pattern.substr(2, pattern.length - 3).split(','),
        min_characters = pattern_array[0],
        max_characters = pattern_array[1];

        console.log(min_characters);
    });
});

Demo: Fiddle

Upvotes: 2

Related Questions