Home > Blockchain >  Error: Cannot read properties of null reading "checked"
Error: Cannot read properties of null reading "checked"

Time:11-28

Im having trouble fully wiring on my django applications submit button, it seems that the JS function does not understand which checked boxes to look for all the console returns is "cannot read properties of null, reading "checked" Im assuming its something with the function defining but I cannot seem to get it working

Heres the code:

<html>
    <head>
        {% load static%}
        {% block content%}
        <link rel="shortcut icon" type="image/png" href="{% static 'IMG/favicon.ico' %}"/>
        <link rel="stylesheet" href="{% static 'CSS/bootstrap.min.css' %}">
        <link rel="stylesheet" href="{% static 'CSS/jquery-ui.css' %}">
        <script type="text/javascript" src="{% static 'JS/bootstrap.min.js' %}"></script>
        <title>Task List</title>
        <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
        <script src="{% static 'JS/jquery-ui.min.js' %}"></script>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script>
            let _csrf = '{{csrf_token}}';
            function submit_delete() {
                var listItems = $("#list li input");
                var checkedListItems = [];
                listItems.each(function() {
                    if (document.getElementById(this.id).checked) {
                        checkedListItems.push(getTaskId(this.id));
                        console.log(checkedListItems);
                    }
                })
          $.ajax({
            headers: { "X-CSRFToken": _csrf },
            type: "POST",
            url: "/ptm/item_delete",
            data: {
                'deleteList[]': checkedListItems
            }
          }).done(location.reload());
          
        }

        function getTaskId(str) {
            return str.split('-')[1];
        }
      </script>
    </head>
    <body>
        <div id="logo"  style="width: 61.rem;">
            <div >
                <img  src="{% static '/IMG/Logo.png' %}">
            </div>
        </div>
        <div id="taskList" >
            {% if task_list %}
            <ul  id="list">
                {% for item in task_list %}
                <li  id='tdList'>
                    <input id="check-{{ item.id }}" type="checkbox"  value="">
                    <label class='d-flex w-100 justify-content-between'>
                        <h2  for="check-{{ item.id }}">{{ item.title }}</h2>
                        <small class='text-muted'>{{ item.date }}</small>
                        <input size='3'>
                    </label>
                    <h5 >{{ item.description }}</h5>

                </li>
            {% endfor %}
            </ul>
            {% else %}
            <p>There are no current tasks assigned to this department.</p>
            {% endif %}
        </div>
        {% csrf_token %}
        <div id="taskEnter" >
            <div >
                {% if task_list %}
                <button type="button" onclick="submit_delete()" value='delete'  value='delete'><i >Submit</i></button>
                {% endif %}
            </div>
        </div>
    </body>
    {% endblock %}
</html>

CodePudding user response:

In the part:

document.getElementById(this.id).checked

document.getElementById(this.id) evaluates to null, which doesn't have any properties, hence the exception you're getting. You're effectively doing null.checked which won't work.

It looks like you're trying to iterate over the checkboxes and determine whether they're checked or not. I'm reasonably confident that this inside the function you wrote will just refer to the window object, so calling this.id won't give you a checkbox id. You have actually already fetched all of the checkboxes (you're iterating over them!) so there's no need to refetch each one manually. Just do:

listItems.each(function(listItem) {
    if (listItem.checked) {
        checkedListItems.push(getTaskId(listItem.id));
        console.log(checkedListItems);
    }
})

Note that the function takes as argument the individual listItem (confusingly named since they're actually checkboxes but I'm following your nomenclature here) that each is currently iterating over. Which is what you need.

CodePudding user response:

Try adding a child combinator ('>') to the element selector used in the first line of function submit_delete:

var listItems = $("#list li > input");

- or use a more precise selector of your own devisement.

As posted there appear to be descendant input elements of .list li of form <input size='3'> that don't have an id attribute. Processing these in each returns null from getElementById and throws the error that checked can't be a property of null.

About each

JAuery's each function fires its callback with a this value set to the element being processed during the iteration. The element is also provided to the callback as its second argument. Given elements in HTML should have unique id values:

  • For elements referred to by this that have id values, using this for the element is simpler than calling getElementById(this.id).

  • For elements (referred to by this) that do not have an id, !this.id) is a simpler conditional expression than getElementById(this.id)===null.

  • Filtering out elements that should not be mnatched during selection is preferable to filtering them out later.

  • Related