Matt Wilkinson
Matt Wilkinson

Reputation: 99

Jquery Uncaught TypeError: Cannot read property 'value' of null

The below form uses Google Autocomplete API which takes the input "autocomplete" and changes it to separate items in a second form (which is hidden unless a user clicks "Can't find an address?". This all works great, however I am using JQuery to validate that each field has data in it (by changing background to green), and this does not work correctly. It works when I individually input into each field and makes them green, but neither autocomplete input or the individual inputs turn green when this happens. Html

<div id="locationField">
    <input id="autocomplete" placeholder="Begin typing an address"
               onFocus="geolocate()" type="text" class="form-control"/>
    <sup><a id="newClientAddressFormLink">Can't find an address?</a></sup>
</div>

<div id="newClientAddressForm" style="display:none;">
    <div id="address">
        <div>
            <input type="text" data-street-number-id="0" class="form-control" id="street_number" maxlength="10" placeholder="Number*" />
            <div id="StreetNumberValidation" class="alert alert-danger complaint-validation" role="alert" style="display: none; max-width: 280px;"><strong>Number</strong> required!</div>
        </div>
        <div>
            <input type="text" data-street-name-id="0" class="form-control" id="route" maxlength="50" placeholder="Street*" />
            <div id="StreetNameValidation" class="alert alert-danger complaint-validation" role="alert" style="display: none; max-width: 280px;"><strong>Street</strong> required!</div>
        </div>
   </div>
</div>

JQuery

$(function () {
    $(document).on('change keyup blur input', "#autocomplete", function () {
        if (this.value.length > 25)
        {
            checkStreetNumberLength(document.getElementById("#street_number"));
            checkStreetNameLength(document.getElementById("#route"));
            $("#autocomplete").css("background-color", "#dff0d8");
        }    
    });
    // Street Number (ID is from Google Autocomplete API)
    $(document).on('change keyup blur input', "#street_number", function () {
        checkStreetNumberLength(this);
    });
    // Street Name (ID is from Google Autocomplete API)
    $(document).on('change keyup blur input', "#route", function () {
        checkStreetNameLength(this);
    });
});

var checkStreetNumberLength = function (fn) {
    if (fn.value.length < 1) {
        $("#street_number").css("background-color", "#fff");
    }
    else {
        $("#street_number").css("background-color", "#dff0d8");
    }
}
var checkStreetNameLength = function (fn) {
    if (fn.value.length < 5) {
        $("#route").css("background-color", "#fff");
    }
    else {
        $("#route").css("background-color", "#dff0d8");
    }
}

It returns a Uncaught TypeError: Cannot read property 'value' of null error on if (fn.value.length < 1) and if (fn.value.length < 5).

Any ideas?

Upvotes: 1

Views: 3502

Answers (2)

mplungjan
mplungjan

Reputation: 178011

It is not a good idea to mix DOM and jQuery, especially not if you mix the selectors.

document.getElementById("#street_number") 

should not have a # like jQuery or querySelector. Instead use jQuery and pass the jQuery object:

checkStreetNumberLength($("#street_number"));
checkStreetNameLength($("#route"));

then when you pass, use the passed:

var checkStreetNumberLength = function ($obj) { // jQuery object passed
  $obj.css("background-color", $obj.val().length < 1?"#fff":"#dff0d8");
}

var checkStreetNameLength = function ($obj) {
  $obj.css("background-color", $obj.val().length < 5?"#fff":"#dff0d8");
}

You can also just trigger an event and get rid of some code:

$(function() {
  $(document).on('change keyup blur input', "#autocomplete", function() {
    if (this.value.length > 25) {
      $("#street_number").change(); // trigger change
      $("#route").change();
      $("#autocomplete").css("background-color", "#dff0d8");
    }
  });
  // Street Number (ID is from Google Autocomplete API)
  $(document).on('change keyup blur input', "#street_number", function() {
    $(this).css("background-color", $(this).val().length < 1?"#fff":"#dff0d8");
  });
  // Street Name (ID is from Google Autocomplete API)
  $(document).on('change keyup blur input', "#route", function() {
    $(this).css("background-color", $(this).val().length < 5?"#fff":"#dff0d8");
  });
});

Upvotes: 2

SamVK
SamVK

Reputation: 3405

document.getElementById doesn't use the #.

Also, alternatively, since you're using jQuery: document.getElementById("#street_number") could also be written as $("#street_number")[0]. jQuery returns an array-like wrapper with the native DOM element at the first index.

https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a-native-dom-element-from-a-jquery-object/

Upvotes: 1

Related Questions