1

I'm using Django inline formsets and trying to use the delete checkbox dynamically with Javascript. Everything works as it is supposed to, however the checked = true property (although showing true in the console) won't check the box as long as updateSunForm() and totalForms.setAttribute(...) are present.

{% load crispy_forms_tags %}
{% load static %}
{% block content %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <link rel="stylesheet" type="text/css" href="{% static 'css/availability_update_new.css' %}">
</head>
<body>
<form id="all-add-form" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <legend class="bottom mb-4">Profiles Info</legend>
    {{ sun_bool.sunday|as_crispy_field }}
    {{ sunday_formset.management_form }}
    {% for sun_form in sunday_formset %}
        {% for hidden in sun_form.hidden_fields %}
            {{ hidden }}
        {% endfor %}
        <div class="sun_time_slot_form">
            {{ sun_form }}
            <button class="delete-sun-form" type="button" id="delete-sun-btn" onclick="one();"> Delete          This Sunday Timeslot
            </button>
        </div>
    {% endfor %}

    <button id="add-sun-form" type="button" class="button">Add Other Sunday Times</button>

    <input type="submit" name="submit" value="Submit" class="btn btn-primary"/>
</form>

<script type="text/javascript" src="{% static 'js/add_timeslot.js' %}"></script>

</body>
</html>
{% endblock content %}



const sunForm = document.getElementsByClassName('sun_time_slot_form');
const mainForm = document.querySelector('#all-add-form');
const addSunBtn = document.querySelector("#add-sun-form");
const submitFormBtn = document.querySelector('[type="submit"]');
const totalForms = document.querySelector("#id_id_sunday_formset-TOTAL_FORMS");

let formCount = sunForm.length - 1;

addSunBtn.addEventListener('click', function (e) {
    e.preventDefault();

    const newSunForm = sunForm[0].cloneNode(true);
    const formRegex = RegExp(`id_sunday_formset-(\\d){1}-`, 'g');

    formCount++;

    newSunForm.innerHTML = newSunForm.innerHTML.replace(formRegex, 
    `id_sunday_formset-${formCount}-`);
    mainForm.insertBefore(newSunForm, submitFormBtn);
    totalForms.setAttribute('value', `${formCount + 1}`);
});

function updateSunForm() {
    let count = 0;
    for (let sun_form of sunForm) {
        const sunFormRegex = RegExp(`id_sunday_formset-(\\d){1}-`, 'g');
        sun_form.innerHTML = sun_form.innerHTML.replace(sunFormRegex, 
            `id_sunday_formset-${count++}-`)
    }
}

mainForm.addEventListener('click', (ee) => {
    if (ee.target.classList.contains('delete-sun-form')) {
        ee.preventDefault();
        ee.target.value;
        ee.target.parentElement.querySelector('input[id$="-DELETE"]' +
            '[type="checkbox"]').checked = true;
        ee.target.parentElement.style.display = "none";
        formCount--;
        updateSunForm();
        totalForms.setAttribute('value', `${formCount + 1}`);
    }
});

I've tried many variations of DOM manipulation and nothing seems to be working.

Wideback
  • 49
  • 3
  • 2
    You've attached the same id to multiple elements. Ids are supposed to be unique within the document. Use a class instead, and get the buttons with `querySelectorAll`. Or alternatively take the advantage of [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation). – Teemu Nov 07 '22 at 08:45
  • I can't understand why the checked = true event won't fire if the other events are higher up the bubble ladder? Even if the ids are the same (even though I have no real control due to inlineformsets)? I've been reading up in depth. Nothing is making sense of my particular issue. – Wideback Nov 16 '22 at 08:17
  • Just to add, I would really like to take advantage of event delegation since it's this great thing in the Javascript arsenal. – Wideback Nov 16 '22 at 08:25

0 Answers0