0

I got this code from codepen: https://codepen.io/jsartisan/pen/wKORYL#=

What happens is I put it all in one page but it won't run. I tried to understand what is wrong with it, but it is just like the example in codepen above.

This happened before in other codepen examples but I couldn't figure out the reason why it won't work.

<html>
    <head> 
        <style>
            #filter_users {
                width:100%;
                padding:10px;
            }

            #users-list {
                margin:0;
                padding:0;
            }

            #users-list li {
                list-style:none;
                padding:10px;
                margin:5px 0;
                border: 1px solid #e4e4e4;
            }
        </style>

        <script>
            var users = [
                'Goku',
                'Naruto',
                'Ichigo',
                'Flash',
                'Batman',
                'Sherlock Holmes',
                'Khaleesi',
                'Steve Fox'
            ];

            ul = document.getElementById("users-list");

            var render_lists = function(lists) {
                var li = "";
                for (index in lists) {
                    li += "<li>" + lists[index] + "</li>";
                }
                ul.innerHTML = li;
            }

            render_lists(users);

            // lets filters it
            input = document.getElementById('filter_users');

            var filterUsers = function(event) {
                keyword = input.value.toLowerCase();
                filtered_users = users.filter(function(user) {
                    user = user.toLowerCase();
                    return user.indexOf(keyword) > -1; 
                });   
                render_lists(filtered_users);
            }
            input.addEventListener('keyup', filterUsers);
        </script>

    </head>

    <body>
        <input type="text" placeholder="Search Users" id="filter_users"/>
        <ul id="users-list">

        </ul>
    </body>
</html>

I expect it to work as in codepen.

Eduard Voiculescu
  • 141
  • 1
  • 3
  • 14
user ct
  • 47
  • 6
  • Any errors in your console? – empiric Aug 19 '19 at 13:10
  • I got this one: Uncaught TypeError: Cannot set property 'innerHTML' of null at render_lists (index.html:42) at index.html:45 – user ct Aug 19 '19 at 13:11
  • 2
    Your code runs immediately when the `script` tag is handled. The elements it's trying to use don't exist yet, because they're defined by HTML *under* the `script` tag. Put the script at the **end** of the document, just prior to the closing `

    ` tag. (If you were using `src` rather than inline script, an alternative would be to add `defer` to the `script` tag. But not with inline script.)

    – T.J. Crowder Aug 19 '19 at 13:12

1 Answers1

1

You have to place the javascript code to the end of the document body. At the time the page gets rendered it doesn't see the element with the id users-list visible yet. Therefore putting the script to the end of the document will help. For more advanced scenarios you might consider using a method which would wait until the document is loaded and first then append the event listener. See e.g. Pure JavaScript equivalent of jQuery's $.ready() - how to call a function when the page/DOM is ready for it

<html>
<head> 


<style>
#filter_users{
  width:100%;
  padding:10px;
}

#users-list{
  margin:0;
  padding:0;
}

#users-list li{
  list-style:none;
  padding:10px;
  margin:5px 0;
  border: 1px solid #e4e4e4;
}
</style>

</head>
<body>
<input type="text" placeholder="Search Users" id="filter_users"/>

<ul id="users-list">

</ul>
<script>
var users = [
  'Goku',
  'Naruto',
  'Ichigo',
  'Flash',
  'Batman',
  'Sherlock Holmes',
  'Khaleesi',
  'Steve Fox'
];

ul = document.getElementById("users-list");

var render_lists = function(lists){
  var li = "";
  for(index in lists){
    li += "<li>" + lists[index] + "</li>";
  }
  ul.innerHTML = li;
}

render_lists(users);

// lets filters it
input = document.getElementById('filter_users');

var filterUsers = function(event){
  keyword = input.value.toLowerCase();
  filtered_users = users.filter(function(user){
        user = user.toLowerCase();
       return user.indexOf(keyword) > -1; 
  });

  render_lists(filtered_users);
}

input.addEventListener('keyup', filterUsers);


</script>
</body>
</html>
jPO
  • 2,502
  • 1
  • 17
  • 26
  • 1
    Then please mark the answer as accepted. I will write an explanation why it is like that in a second. – jPO Aug 19 '19 at 13:13