Django View to return template with refreshed modal window

I'm using Django form in modal window where core content (in container) generated by JS. On submit django model instance saved without any issues if form.is_valid() == True a modal window closes with switching focus on current background page. However if form.is_valid() == False the modal content just opens in separate URL instead and takes all browser screen as View renders just a short code fragment in .html file.

The goal is to refresh the modal window on current condition in case if form_is_valid() == False with form errors.

Template "accounts/profile_settings.html" contains a form and submit button which renders inside

<div class="preferences_content">
    {% comment %} JS generated dynamic content depends on tab pressed. {% endcomment %}
</div>

My JS knowldge is very basic so I appreciate any suggestion on this topic.

The View :

def profile_update_view(request):
    """ Updates current Profile instance."""
    if request.method == "POST":
        current_profile = request.user.profile
        profile_form = ProfileUpdateForm(request.POST, request.FILES, instance=current_profile)
        if profile_form.is_valid():
            profile_form.save()
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', "/"))
        else:
            profile_form = ProfileUpdateForm()
            return render(request, "accounts/profile_settings.html", {'profile_form': profile_form})
    else:
        profile_form = ProfileUpdateForm()
        return render(request, "accounts/profile_settings.html", {'profile_form': profile_form})

document.addEventListener("DOMContentLoaded", function() {
    var openModalLink = document.getElementById("openPreferencesModal");
    var modal = document.getElementById("preferencesModal");
    var span = modal.querySelector(".close");
    var preferencesContent = modal.querySelector(".preferences_content");
    var tabs = modal.querySelectorAll(".tab");

    openModalLink.addEventListener("click", function(event) {
        event.preventDefault();
        modal.style.display = "block"; // Встановлюємо стиль блоку при відкритті модального вікна

        tabs.forEach(function(tab) {
            tab.classList.remove('active');
        });

        tabs[0].classList.add('active');

        // Отримуємо url першої вкладки та завантажуємо вміст
        var firstTabUrl = tabs[0].getAttribute("data-url");
        fetch(firstTabUrl)
            .then(response => response.text())
            .then(data => {
                preferencesContent.innerHTML = data;
            })
            .catch(error => {
                console.error('Error fetching content:', error);
            });
    });

    span.addEventListener("click", function() {
        modal.style.display = "none";
    });

    window.addEventListener("click", function(event) {
        if (event.target === modal) {
            modal.style.display = "none";
        }
    });

    tabs.forEach(function(tab) {
        tab.addEventListener("click", function(event) {
            event.preventDefault();

            tabs.forEach(function(tab) {
                tab.classList.remove('active');
            });

            tab.classList.add('active');

            var url = tab.getAttribute("data-url");
            fetch(url)
                .then(response => response.text())
                .then(data => {
                    preferencesContent.innerHTML = data;
                })
                .catch(error => {
                    console.error('Error fetching content:', error);
                });
        });
    });

    var editLink = modal.querySelector(".base_info a[href='']");
    editLink.addEventListener("click", function(event) {
        event.preventDefault();
        tabs.forEach(function(tab) {
            if (tab.getAttribute("href") === "#profile") {
                tab.click();
            }
        });
    });
});
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="preferencesModal" class="preferences_modal">
    <!-- Modal content -->
    <div class="preferences_modal_content">
      <span class="close">&times;</span>
        <section class="profile_info">

            {% if user.profile.avatar %}
              <img src={{ user.profile.avatar.url }} alt="avatar">
            {% else %}
              <img src={% static "img/default_profile_avatar.svg" %} alt="avatar">
            {% endif %}
            
            <div class="base_info">
              <span>{{ user.profile.username }}</span>
              <span>{{ user.email }}</span>
              {% if user.profile.first_name and user.profile.last_name %}
                <span>{{ user.profile.first_name}}, {{user.profile.last_name}}</span>
              {% endif %}
              <a href="">Edit</a>
            </div>

        </section>

        <section class="preferences_data">
            <div class="preferences_tabs">
                {% comment %} Tabs {% endcomment %}
                <a href="#preferences" class="tab" data-url="{% url 'preferences:preferences_update' %}">Preferences</a>
                <a href="#profile" class="tab" data-url="{% url 'accounts:profile_update' %}">Profile</a>
            </div>
            
            <div class="preferences_content">
              {% comment %} JS generated dynamic content depends on tab pressed. {% endcomment %}
            </div>
        </section>
        
    </div>
  </div>
</body>
</html>

Back to Top