Richard_G
Richard_G

Reputation: 4820

JavaScript cannot locate one specific element by ID on page when all others work

I have an odd issue using JavaScript to find an element by ID. No function will run against it because the selection is undefined. It has the same kind of definition as many on the same page. There is only one element by this ID. And, when I assign an ID to the surrounding paragraph, it works just fine. So, the problem is bypassed. But, I am very curious as to the problem. I am showing the pertinent items.

This JavaScript is part and parcel of a Rails application, so it is included as an external file using application.js. It's a large file with many functions and they all work except when referencing this one ID. And, as I stated, I select many other ID's on this page in the same fashion with no issue.

I use RubyMine and have searched the entire application for conflicts and typos related to the issue. There are no conflicts and every expected reference to item_message is found. item_message is included in a partial along with other references that JavaScript locates easily. I searched for syntax errors before it was included and none are found. I reordered the items on the page and in JavaScript to no avail. I simply don't know why this doesn't work.

When I tried to hide the element using class optional, that worked. However, it also hid other items that should not have been hidden.

It's working like this:

HTML:

  <p id="item_message_p">
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>

JavaScript:

var item_message_p = $('#item_message_p');
select_item_spot_id.change(function () {
    var spot = $(this).val();
    if (spot != "") {
      $.getJSON('/spots', {spot: $(this).val()}, function (data) {
        if (data.name.toLowerCase() === 'sold') {
            item_message_p.hide();
        } else {
            item_message_p.show();
        }
      })
    }
});

It wouldn't work like this, as var item_message is undefined:

HTML:

  <p>
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>

JavaScript:

var item_message = $('#item_message');
select_item_spot_id.change(function () {
    var spot = $(this).val();
    if (spot != "") {
      $.getJSON('/spots', {spot: $(this).val()}, function (data) {
        if (data.name.toLowerCase() === 'sold') {
            item_message.hide();
        } else {
            item_message.show();
        }
      })
    }
});

Upvotes: 0

Views: 69

Answers (3)

Richard_G
Richard_G

Reputation: 4820

As per Andy's suggestion, I ended up checking the generated page to find that another element had generated the same ID. That explains the issue. Thanks to all who helped.

Upvotes: 1

emi
emi

Reputation: 3070

You are trying to access select_item_spot_id.change(), but select_item_spot_id is not defined. You defined item_message or item_message_p. You might like to do it inside a onDOMReady event listener, as spotted by @trincot . This example code works for me:

$(function () {
   var item_message = $('#item_message');
   var select_item_spot_id = $('#select_item_spot_id');
   select_item_spot_id.change(function () {
      var spot = $(this).val();
      // DEBUG
      if(item_message.length > 0)
         alert('works!');
      // END DEBUG
      if (spot != "") {
         $.getJSON('/spots', {spot: $(this).val()}, function (data) {
            if (data.name.toLowerCase() === 'sold') {
               item_message.hide();
            } else {
               item_message.show();
            }
         });
      }
   });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
  <select id="select_item_spot_id" name="select_item_spot_id">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </select>
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message">
</p>

Upvotes: 0

trincot
trincot

Reputation: 350232

Make sure your page is loaded before looking up elements. So wrap your code in $(function () {...});, like this:

$(function () {
    var item_message = $('#item_message');
    select_item_spot_id.change(function () {
        var spot = $(this).val();
        if (spot != "") {
          $.getJSON('/spots', {spot: $(this).val()}, function (data) {
            if (data.name.toLowerCase() === 'sold') {
                item_message.hide();
            } else {
                item_message.show();
            }
          })
        }
    });
});

This will make your code execute when the dom is ready.

Also, it is best to close your input tag explicitly:

<input ..... />

Notice the slash. This absence might also explain the issue, including the spoil-over effect you noticed when hiding the element.

Upvotes: 0

Related Questions