7

I am using a drop down for dynamically changing content on a page. It works but is throwing a js error in Chrome ONLY. What Chrome recommends I don't know how to implement. Site is built in ExpressionEngine 2.8.1.

ERROR MESSAGE IN CHROME

Uncaught TypeError: Cannot set property 'onchange' of null functions.js:65
event.returnValue is deprecated. Please use the standard event.preventDefault() instead.

MY JS Code

document.getElementById("drop").onchange = function() {
    if (this.selectedIndex!==0) {
        window.location.href = this.value;
    }        
};

MY HTML Code

            <form method="post" action="{path='locations/index'}" class="drop">
                <select id="drop">
                    <option>Select a Location:</option>
                {exp:channel:entries channel="locations" category="not 3" orderby="title" sort="asc" dynamic="no"}
                    <option value="{site_url}index.php/locations/{url_title}">{title}</option>
                {/exp:channel:entries}
                </select>
            </form>
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
DVLPR
  • 73
  • 1
  • 1
  • 4
  • works fine in Chrome, what version are you running? I did this in a [jsfiddle](http://jsfiddle.net/6RsLA/) and it worked fine –  May 08 '14 at 14:32
  • 1
    Can you give some more info on the JS, please? Is that script directly in the HTML? Is there more JS or just this line? Are you sure your Chrome is stable? – Blake Simpson May 08 '14 at 14:32
  • Looks like you're executing this code in a jQuery eventhandler, `$(document).ready()` maybe? If the code really works in other browsers, your template probably breaks in Chrome. You could check the `innerHTML` of the `form` just before trying to set the event handler to `select`. Can you see the select tag and its id? – Teemu May 08 '14 at 14:55
  • It is very likely it is a browser quirk. Knowing vanilla js to access the dom is great but if you want reliability, use JQuery to select the appropriate element. Like Adeneo posted, the only explanation is that the element hasn't been selected by the document.getElementById call. Without additional info, it's impossible to answer. – dot slash hack May 08 '14 at 15:07

5 Answers5

19

There's only one possible reason for that error message, document.getElementById("drop") does not return the element, and the only reason for that is that the element doesn't exists, but in the HTML it clearly does, so the script must be running before the elements in the DOM.

You have to include the javascript after the elements in the DOM, or wrap it in a DOM ready handler, like window.onload etc.

<form method="post" action="{path='locations/index'}" class="drop">
    <select id="drop">
        <option>Select a Location:</option>{exp:channel:entries channel="locations" category="not 3" orderby="title" sort="asc" dynamic="no"}
        <option value="{site_url}index.php/locations/{url_title}">{title}</option>{/exp:channel:entries}
    </select>
</form>
<script>
    document.getElementById("drop").onchange = function() {
        if (this.selectedIndex !== 0) {
            window.location.href = this.value;
        }
    };
</script>
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • I have the js code in my functions file. I will try it the way you have it and see if I still get the error. Thanks for your help on this. – DVLPR May 08 '14 at 14:55
2

You are running the JavaScript code before your HTML has rendered.

Code Whisperer
  • 22,959
  • 20
  • 67
  • 85
1

Use document ready event

$(document).ready(function(){

 $('#drop').change(function(){ 
    if (this.selectedIndex !== 0) {
        window.location.href = this.value;
    }
 })

});
Prosto Trader
  • 3,471
  • 3
  • 31
  • 52
1

For executing external scripts, also try defer attribute. It specifies that the script is downloaded in parallel to parsing the page, and executed after the page has finished parsing.

Like this:

<script src="example.js" defer></script>
salante
  • 11
  • 1
0

You need to make sure that your connection with HTML file by tag was put at the last child of tag. Reason is here HTML must be executed first, then JS after that.

Nathan
  • 1