trco / django-bootstrap-modal-forms

A Django plugin for creating AJAX driven forms in Bootstrap modal.
MIT License
384 stars 142 forks source link

Form displayed and not loaded in modal #194

Closed nbarriere closed 2 years ago

nbarriere commented 2 years ago

Hello,

First thank you for your work which saves me a lot of time and works well on my form with model view. I'm trying to use it in a form where the data is not inside a Django model. My issue is when a validation error occurs after submit, the form is displayed in the browser and not loaded inside the modal.

Can you tell me what I’m doing wrong?

urls.py

re_path(r'computer-windows/update/(?P<computername>[-\w]+)/$', login_required(ComputerWindowsUpdateView), name='windows_update')

forms.py

class ComputerWindowsUpdateForm(forms.Form):
    Model = forms.CharField(max_length=100)
    User = forms.CharField(max_length=64, widget=forms.Select)
    Inventory = forms.CharField(min_length=7, max_length=7, required=True,  validators=[RegexValidator('^[A-Z]{1}[0-9]{6}', message="Please enter a valid inventory number")])

views.py

def ComputerWindowsUpdateView(request, computername):
    if request.method == 'POST':
        form = ComputerWindowsUpdateForm(request.POST)
        if form.is_valid():
            if not is_ajax(request.META): 
                    ...DO SOMETHING...
                    success_url = request.META.get('HTTP_REFERER')
                    return HttpResponseRedirect(success_url)
        return render(request, 'app/windows_update.html', {'form': form})  

    form = ComputerWindowsUpdateForm
    return render(request, 'app/windows_update.html', {'form': form})
christianwgd commented 2 years ago

Do you use the django-bootstrap4 library or some other third party form library? Then the most common mistake is, that they set a different error class, which is not recognised by this package. So you may want to try to set the error class like so:

$("#create-action").modalForm({
    formURL: "{% url 'app:url' %}",
    // django-bootstrap4 uses ".is-invalid" as error class!
    errorClass: '.is-invalid'
});

See also my comment on https://github.com/trco/django-bootstrap-modal-forms/issues/125

nbarriere commented 2 years ago

Hi,

I'm using BS5 without third party library. I’ve tried to add the errorClass parameter which should be also “. is-invalid” for BS5. But I’ve still the same issue.

windows_update.html

{% load widget_tweaks %}

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

  <div class="modal-header">
    <h3 class="modal-title">Update <strong>{{ form.Name.value }}</strong></h3>
    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  </div>

  <div class="modal-body">
    <div class="{% if form.non_field_errors %} invalid{% endif %} mb-2">
      {% for error in form.non_field_errors %}
      {{ error }}
      {% endfor %}
    </div>

    {% for field in form %}
    <div class="form-group">

      <div class="mb-3">
        <label for="{{ field.id_for_label }}" class="col-form-label">{{ field.label }}</label>
        {% render_field field class="form-control" placeholder=field.label %}
        <div class="{% if field.errors %} invalid{% endif %}">
          {% for error in field.errors %}
          <p class="text-danger help-block">{{ error }}</p>
          {% endfor %}
        </div>
      </div>
    </div>
    {% endfor %}
  </div>

  <div class="modal-footer">
    <button type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-primary">Save changes</button>
  </div>

</form>

main.html

...
<button type="button" class="windows-update btn btn-outline-primary mx-1" data-form-url="{% url 'windows_update' Computer.1.name.0 %}">
...

<!-- Modal with id="modal" -->
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" id="modal">
    <div class="modal-dialog" role="document">
        <div class="modal-content"></div>
    </div>
</div>

<script type="text/javascript">
    $(function () {

        // Update  buttons
        $("body").on("focus", ".windows-update", function (event) {

            $(this).modalForm({
                formURL: $(this).data("form-url"),
                errorClass: '.is-invalid'
            });
        });

    });
</script>
christianwgd commented 2 years ago

Tested this and found that the line

<div class="{% if form.non_field_errors %} invalid{% endif %} mb-2">

should also include "is-invalid" instead of "invalid":

<div class="{% if form.non_field_errors %}is-invalid{% endif %} mb-2">

This one worked for me.

nbarriere commented 2 years ago

It works! Thank you for your help.