DJANGO Duplication of HTML on page load

I am using DJANGO to create a website, with minimal add ins. At this time, I have a page that duplicates itself on select change. Trying to change its' behavior only makes it worse, like if I change the swap to outer, then it duplicates outside of the element rather than in it.

The environment:

Windows 11 Pro x64
Visual Studio Code x64
python 3.12.3
Packages                  Versions
------------------------ ---------
asgiref                  3.8.1
certifi                  2025.1.31
charset-normalizer       3.4.1
Django                   5.2
django-htmx              1.23.0
django-multiselectfield  0.1.13
django-phonenumber-field 8.1.0
idna                     3.10
phonenumberslite         9.0.3
pip                      24.0
pyasn1                   0.6.1
pyasn1_modules           0.4.2
python-ldap              3.4.4

The base html:

{% load django_htmx %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="keywords" content="HTML, CSS, Python, JINJA"/>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        {% htmx_script %}
    </head>
    <bod hx-headers='{"x-csrftoken": "{{ csrf_token }}"}'>
        <div id="navbar">
            <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
                <span ><h1>{% block page_title %}base_title{% endblock page_title %}</h1></span>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbar" >
                    <div class="navbar-nav" style="margin-left: auto; margin-right: 0;">
                        <a class="nav-item nav-link" id="logout" href="/mytickets">
                            My Tickets
                        </a>
                        <a class="nav-item nav-link" id="logout" href="/createticket">
                            Create Ticket
                        </a>
                        <a class="nav-item nav-link" id="logout" href="/companytickets">
                            Company Tickets
                        </a>
                        <a class="nav-item nav-link" id="logout" href="/companyalerts">
                            Company Alerts
                        </a>
                        <a class="nav-item nav-link" id="logout" href="/logout">
                            Logout
                        </a>
                        <a class="nav-item nav-link" id="logout" href="/profile">
                            <svg xmlns="../static/css/person.svg" width="16" height="16" fill="black" class="bi bi-person" viewBox="0 0 16 16">
                                <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10s-3.516.68-4.168 1.332c-.678.678-.83 1.418-.832 1.664z"/>
                              </svg>
                        </a>
                    </div>
                </div>
            </nav>
        </div>
        {% block select %} base_select {% endblock select%}
        {% block content %} base_content {% endblock content %}
    </body>
</html>

The template for:

{% extends 'website/base.html' %} 

{% block page_title %}
    Create Tickets
{% endblock %}
{% block select %}
    <select hx-post="/createticket/" hx-swap="innerHTML" hx-trigger="change" hx-target="#form-content" selected="other" name="select_ticket_type" id="select_ticket_type">
        <option value="new_user">New Employee</option>
        <option value="new_asset">New Asset</option>
        <option value="new_app">New Application</option>
        <option value="other">Other</option>
    </select> 
{% endblock select %}
{% block content %} 
    <form name="form-content" id="form-content" method="post">
        {% csrf_token %}
        {{ form }}
        <button type="submit" name="Create Ticket">Create Ticket</button>
    </form>
{% endblock content %}

The view.py:

def create_ticket(response):
    form_selection = response.POST.get('select_ticket_type')
    print(response)
    if response.method == "POST":
        match form_selection:
            case "new_user":
                print("new user")
                new_user = CreeateUser(response.POST)
                if new_user.is_valid():
                    # Process form A data
                    response.session['display_form'] = response.POST.get('select_ticket_type')
                    return redirect('createticket')
            case "new_app":
                print("new app")
                new_app = CreateApplication(response.POST)
                if new_app.is_valid():
                    # Process form B data
                    response.session['display_form'] = response.POST.get('select_ticket_type')
                    return redirect('my_view')
            case "new_asset":
                print("new asset")
                new_asset = CreateAsset()
                if new_asset.is_valid():
                    # Process form B data
                    response.session['display_form'] = response.POST.get('select_ticket_type')
                    return redirect('my_view')
            case _:
                print("other")
                form = CreateOther(response.POST)
    display_form = response.session.get('display_form', response.POST.get('select_ticket_type'))
    print(f"display for is {display_form}")
    match display_form:
        case "new_user":
            print("Form is for user")
            form = CreeateUser()
        case "new_app":
            print("form is for app")
            form = CreateApplication()
        case "new_asset":
            print("form for new asset")
            form = CreateAsset()
        case _:
            form = CreateOther()

    context = {'form': form}
    return render(response, 'website/createticket.html', context)

I have tried to make it as simple as possible for now to reduce conflicts and narrow down what is going on. hx-swap"outer/innter/beforebegin/afterbeing/..." do not help.

I wrote out the AJAX for this and it does the same thing.

       const select_ticket_type = document.getElementById('select_ticket_type');
        select_ticket_type.addEventListener('change', function() {
            const selectedValue = this.value;
            fetch('/createticket/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-CSRFToken': '{{ csrf_token }}', 
                },
                body: 'select_ticket_type=' + selectedValue, 
            })
            .then(response => response.text())
            .then(data => {                
                document.getElementById('form-content').innerHTML = data;
            });
           
        });

The issue is that on select you're replacing the <form name="form-content" id="form-content" method="post"> with your entire page.

What you actually want to do is replace the contents of the form with the contents of the newly generated form, and ignore the remainder of the page.

Htmx has an attribute to achieve this, hx-select. Docs here.

To use it, add hx-select="#form-content" to your select tag:

<select 
    hx-post="/createticket/" 
    hx-swap="innerHTML" 
    hx-trigger="change" 
    hx-target="#form-content" 
    hx-select="#form-content" 
    selected="other" 
    name="select_ticket_type" 
    id="select_ticket_type"
    >
Вернуться на верх