简体   繁体   中英

How can I render a Django render() response in an ajax function?

In my view, I return html if a form is valid:

if form_valid():
    return render(request, 'home.html', context=context)
else:
    return HttpResponse(status=204)

I'm submitting multiple forms via ajax and want to render the response, if the status code is not 204:

$.ajax({
    data: $(this).serialize(),
    type: $(this).attr('method'),
    url: $(this).attr('action'),
    success: function (response, status, jqXHR) {
        if (jqXHR.status !== 204) {
            document.write(response); // this works, but I lose some functionality. Some buttons stop working.
            // How can I render the response correctly?
        }
    }
});

EDIT: The buttons that don't work anymore. It's a form using bootstrap collapse with some workarounds

main.html

<form action="." method="post">
    {% csrf_token %}


    {% include 'collapse_form.html' with form=mysql_form %}
    {% include 'collapse_form.html' with form=postgres_form %}
    {% include 'collapse_form.html' with form=sqlite_form %}

    <input type="hidden" name="databases-section"/>

    <a id="download-btn" class="btn btn-success">Download</a>
    <a id="hidden-download-link" class="js-scroll-trigger" href="#download"></a>
</form>

collapse_form.html

{% load crispy_forms_filters %}

<div class="collapseForm">
    <div class="collapseFormButton">
        <button id="collapseBtn" class="d-none btn btn-check p-0 m-0" type="button" data-toggle="collapse"
                data-target="#{{ form.prefix }}-collapseTarget"
                aria-expanded="false">
        </button>

        {{ form.active|as_crispy_field }}
    </div>

    <div class="collapse" id="{{ form.prefix }}-collapseTarget">
        <div class="card card-body">
            {{ form|as_crispy_errors }}
            {% for field in form.visible_fields|slice:"1:" %}
                {{ field|as_crispy_field }}
            {% endfor %}

        </div>
    </div>
</div>

js

$('.collapseFormButton').find("input").change(function () {
        toggleCollapseForm()
    });

function toggleCollapseForm() {
    let collapseForm = $(".collapseForm");

    collapseForm.each(function () {
        let collapseCheckbox = $(this).find("input[id*='active']");
        let collapseTarget = $(this).find("div[id*='collapseTarget']");

        if (collapseCheckbox.is(':checked')) {
            collapseTarget.collapse('show');
        } else {
            collapseTarget.collapse('hide');
        }
    });

}

instead of document.write there is more functions like append , you could use that to append the rendered htmls cooming to ajax as a response to a specific element selected by id to avoid any problem like lossing the documents html tags( html, body, header ). and there is big point!

javascript has different behavior regarding dynamically added elements!

to be more clear, I think js and/or jQuery has different behavior for keword this which doesn't work on dynamically added elements. so you sould use another query-selector like $(document).on('click', element, function (){....} and this would work as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM