0

I am trying to populate a dropdown form field created with:

<div class="section">
    <label >Province</label><br>
    <select id="provinces"></select>
</div>

using the following JavaScript:

var provinces = ['Gauteng', 'Limpopo', 'Western Cape','Northern Cape','Mpumalanga','Kwazulu Natal','North West','Eastern Cape','Free State'],
select = document.getElementById( 'provinces' );
for( province in provinces ) {
    select.add( new Option( provinces[province] ) );
};

This works perfectly if I place the script in the HTML document but nothing happens if I remove the script tags and place it in an external file. I have referenced the js file from within the HTML file with

<script type="text/javascript" src="js/formcalculations.js"></script>

and I have confirmed that I am referencing the correct field.

I'm obviously making some other stupid mistake. Would any of you experts be kind enough to show me where I am going wrong?

j08691
  • 204,283
  • 31
  • 260
  • 272
Beemerang
  • 13
  • 2
  • 1
    There is nothing wrong with the code you shared. – Quentin Jun 26 '17 at 13:41
  • Are you sure, that you place it after the HTML just before `

    ` tag

    – Yordan Nikolov Jun 26 '17 at 13:41
  • It doesn't need to go just before `

    `. That's a cargo cult performance trick which only applies if you don't want the JS to run until the very last second. (This JS looks like it should run as soon as the select element is available).

    – Quentin Jun 26 '17 at 13:42
  • 2
    Can you confirm that your external script is correctly loaded? In chrome use the F12 dev tools and look at Sources tab. – Joe Jun 26 '17 at 13:42
  • @Quentin if the script loads before the html or before the #provinces is create, how can the `getElementById` will find that element – Yordan Nikolov Jun 26 '17 at 13:43
  • You need to make sure the script comes AFTER your HTML elements are loaded into the page. – KyleS Jun 26 '17 at 13:43
  • You should call `document.getElementById` after a [`DOMContentLoaded`](https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded) event. – Code4R7 Jun 26 '17 at 13:44
  • @YordanNikolov — There is a significance difference between "After the select element is available" and "Just before `

    `"

    – Quentin Jun 26 '17 at 13:44
  • Your script needs to run after the DOM elements exist. Your problem is almost certainly that the ` – Ted Hopp Jun 26 '17 at 13:45
  • 1
    What errors do you get in the console? That alone should point to the problem. As Joe already noted, press F12 and open the dev tools. – j08691 Jun 26 '17 at 13:46
  • @Quentin and that doesnt mean that it can be equal? please! – Yordan Nikolov Jun 26 '17 at 13:46
  • There are a couple of things that could be wrong here, and there are duplicates for both of them, but the question needs an [mcve] to tell what the problem is. Until then, any answer is only speculating as to what the problem is. – Quentin Jun 26 '17 at 13:48
  • Your code works perfectly for me, both inline and when referenced. Show us the complete HTML page otherwise we can't fix it – Alex Jun 26 '17 at 13:55

3 Answers3

3

You are Calling Script Before it's Element Created in DOM Structure.

JavaScript Code:

<script type="text/javascript">    
    var provinces = ['Gauteng', 'Limpopo', 'Western Cape', 'Northern Cape', 'Mpumalanga', 'Kwazulu Natal', 'North West', 'Eastern Cape', 'Free State'],
        select = document.getElementById('provinces');
    for (province in provinces) {
        select.add(new Option(provinces[province]));
    };
</script>

This works perfectly if I place the script in the HTML document (you are placing the script after Select Element Created, That's why it is working)

but nothing happens if I remove the script tags and place it in an external file (You are adding external file in html head section top, the script will be execute instant head section load. It will not wait to load entire body, and thus your script will not get Select Element & you will get JavaScript error in your browser "Uncaught TypeError: Cannot read property 'add' of null at ..."). I have referenced the js file from within the HTML file with <script type="text/javascript" src="js/formcalculations.js"></script> and I have confirmed that I am referencing the correct field.

I'm obviously making some other stupid mistake (You are not stupid, it happens with everyone who are beginners even it happened lots of time with me even... Well, that time I was kid :D). Would any of you experts be kind enough to show me where I am going wrong? (Off course dear, Stackers are everywhere and willing to help each and every person on SO :) :))

The Correct Way is add script or external javascript always at the end of html body, So then your script will get all required elements from body.

Working Script: Inline (No matter it's before </head> or before </body>)

<script type="text/javascript">
    window.onload = function() {
        var provinces = ['Gauteng', 'Limpopo', 'Western Cape', 'Northern Cape', 'Mpumalanga', 'Kwazulu Natal', 'North West', 'Eastern Cape', 'Free State'],
        select = document.getElementById('provinces');
        for (province in provinces) {
            select.add(new Option(provinces[province]));
        };
    };
</script>

External Script Code: (No matter it's before </head> or before </body>)

window.onload = function() {
    var provinces = ['Gauteng', 'Limpopo', 'Western Cape', 'Northern Cape', 'Mpumalanga', 'Kwazulu Natal', 'North West', 'Eastern Cape', 'Free State'],
        select = document.getElementById('provinces');
    for (province in provinces) {
        select.add(new Option(provinces[province]));
    };
};
Nono
  • 6,986
  • 4
  • 39
  • 39
0

Check if 1) The script file is referenced correctly (open the src location) and 2) The script tag is within the body (ideally after the section element). It may be that the javascript code is executing before the element is rendered

user5480949
  • 1,410
  • 1
  • 15
  • 22
-1

You must execute your code after the dom is loaded, you have some options how to do it:

  1. load your js at the end of your page;

  2. use defer attribute on your script tag;

  3. pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it
Winni
  • 85
  • 1
  • 7
  • `window.onload="myFunction()"`?! `onload` is a stupid length delay, and it doesn't accept a string as a value. – Quentin Jun 26 '17 at 13:50
  • your point 1 is a tip, not a requirement. Same with point 2. And number 3 should be avoided – treyBake Jun 26 '17 at 13:51