1

I have one page with two forms. Depending on the radio button selected (one is selected by default) one of the forms is showing and the other one is hidden (using JS and CSS). When the user fills in the form field and submits the form both forms are validated and the page refreshes. I am looking to achieve that on submitting the form only the corresponding form is validated and the page is not refreshed. How can only one form be validated and the page prevented from refreshing (i.e. keep showing the manual form after submission)?

Looking for a solution the following suggestions did not solve the problem: Proper way to handle multiple forms on one page in Django, How to submit form without refreshing page using Django, Ajax, jQuery?, http://jquery.malsup.com/form/.

views.py

from flap.forms import FlapManualForm
from flap.forms import FlapAutoForm

def index(request):
    if request.method == 'POST':
        form_manual = FlapManualForm(request.POST)
        form_auto = FlapAutoForm(request.POST)
        if form_manual.is_valid():
            try:
                if form_manual.data['flap']:
                    print(form_manual.data['flap'])
                    manual = request.POST['flap']
            except:
                print('manual form empty')

        if form_auto.is_valid():
            try:
                if form_auto.data['flap_time']:
                    print(form_auto.data['flap_time'])
                    auto = request.POST['flap_time']
            except:
                print('auto form empty')

    else:
        form_manual = FlapManualForm()
        form_auto = FlapAutoForm()

    return render(request, 'index.html', {'form_manual': form_manual, 'form_auto': form_auto})

forms.py

class FlapManualForm(forms.Form):
    flap = forms.CharField(min_length=4, max_length=4, label=False, required=False, widget=forms.TextInput(attrs={'style': 'width:90px'}))
    def clean(self):
        cleaned_data = super(FlapManualForm, self).clean()
        flap = cleaned_data.get('flap')
        if not flap:
            pass

class FlapAutoForm(forms.Form):
    flap_time = forms.IntegerField(min_value=1, label=False, required=False, widget=forms.NumberInput(attrs={'style': 'width:90px'}))
    def clean(self):
        cleaned_data = super(FlapAutoForm, self).clean()
        flap_time = cleaned_data.get('flap_time')
        if not flap_time:
            pass

index.html

{% load widget_tweaks %}
<!DOCTYPE html>
<html lang="en">
<head>
  {% block title %}<title>flap</title>{% endblock %}
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
</head>
<body>

<style>
.content {
    max-width: 500px;
    margin: auto;
}
.align_center{
    text-align: center;
}
.auto_form {
    display: block;
}
.manual_form {
    display: none;
}
input[type=text] {
    margin: auto;
    text-align: center;
}
input[type=number] {
    margin: auto;
    text-align: center;
}
</style>

<script type="text/javascript">
function show_auto(){
  var x = document.getElementById("manual_form");
  var y = document.getElementById("auto_form");
  if (x.style.display === "none") {
    x.style.display = "block";
    y.style.display = "none";
  } else {
    x.style.display = "none";
    y.style.display = "block";
  }
}
function show_manual(){
  var x = document.getElementById("manual_form");
  var y = document.getElementById("auto_form");
  if (y.style.display === "none") {
    y.style.display = "block";
    x.style.display = "none";
  } else {
    y.style.display = "none";
    x.style.display = "block";
  }
}
</script>

<br>
<br>
<br>
<br>

<div class="align_center">
  <div class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary active" onclick="show_auto();">
      <input type="radio" name="tab" value="igotnone" checked/>auto
    </label>
    <label class="btn btn-primary" onclick="show_manual();">
      <input type="radio" name="tab" value="igottwo"/>manual
    </label>
  </div>

  <br>
  <br>

  <div id="manual_form" class="manual_form">
    <form method="post">
      {% csrf_token %}
      {{ form_manual }}
      <button type="submit" name="manual_submit" class="btn btn-primary">flap</button>
    </form>
  </div>

  <div id="auto_form" class="auto_form">
    <form method="post">
      {% csrf_token %}
      {{ form_auto }}
      <button type="submit" name="auto_submit" class="btn btn-primary">auto</button>
    </form>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
Aaron Scheib
  • 318
  • 2
  • 15
  • The ajax post you've viewed should solve the problem. You will need to ensure you're providing a JSON response rather calling your current `index` function. You'll need a separate function for each form. – HenryM Apr 21 '19 at 07:52
  • @HenryM trying this out with only one form and returning `return HttpResponse(json.dumps({'message': message}))` in the `index` function after the form is validated shows the plain JSON on the webpage. In the ajax post this should display in the `message` div and I would think the initial problem should be solved. Can you hint toward how to get this done. I only started using JS, jQuery, Ajax. Thanks! – Aaron Scheib Apr 21 '19 at 09:17
  • Try this tutorial: https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html – HenryM Apr 21 '19 at 09:24
  • this doesn't seem to get it done since it does not use a submit button to submit the whole form. What I would like to achieve is no refresh of the page after form submission. – Aaron Scheib Apr 21 '19 at 13:14
  • It should be enough to point you in the right direction – HenryM Apr 21 '19 at 13:15
  • Thanks für the suggestions. After all I did not manage to get it right and got rid of having two forms on one page. – Aaron Scheib Apr 23 '19 at 09:08

0 Answers0