Contained submit button validating other forms

Tags: , ,



I have two forms on my page, each with its own fields and submit button, but whenever I use any of them, they always check the overall page fields instead of just the form they’re contained in…

The simulator.html has two forms, the first one is this:

<div class="forms">
 <div class="form-1">
  <form method="post" action="{{ url_for('core.simulator') }}">
   <div class="container">
    <div class="row g-3">
     <div class="col-sm-3">
      <label class="form-label"><b>Capital:</b></label>
      <input type="text" class="form-control" name="capital_html" required>
     </div>
     <div class="col-sm-3">
      <label class="form-label"><b>Price:</b></label>
      <input type="text" class="form-control" name="price_html" required>
     </div>
    </div>
   </div>
   <br>
   <div class="d-grid gap-2 d-md-flex justify-content-md-start">
    <button id="btn" type="submit" class="btn btn-info">Launch simulation!</button>
   </div>
  </form>
  <br>
   <p>Units to purchase: <b>{{simulation_units}}</b>
 </div>
</div>

And the second one is this:

<h3> Screener</h3>
 <div class="forms">
  <div class="form-2">
   <form method="post" action="{{ url_for('core.simulator') }}">
    <div class="container">
     <div class="row g-3">
      <div class="col-sm-3">
       <label class="form-label"><b>Ticker:</b></label>
       <input type="text" class="form-control" name="ticker_symbol_html" placeholder="Enter Ticker Symbol" required>
      </div>
     </div>
    </div>
    <br>
   <div class="d-grid gap-2 d-md-flex justify-content-md-start">
     <button id="btn" type="submit" class="btn btn-info">Launch!</button>
   </div>
   <p>Symbol <b>{{simulation_symbol}}.
  </form>
 </div>
</div>

The views.py file has the back-end code for each, the first one is this:

def capital_simulator():
    if request.method == 'POST':
       simulation_capital = request.form.get('capital_html', '')
       simulation_price = request.form.get('price_html', '')

       try:
          simulation_units = math.floor(float(simulation_capital) / float(simulation_price))
       except KeyError:
       simulation_units == 0

       return render_template('simulator.html',form1=form,capital_html=simulation_capital,price_html=simulation_price,simulation_units=simulation_units)

And the second form back-end script is this:

def screener():
    if request.method == 'POST':
       ticker_symbol = request.form.get('ticker_symbol_html', '')

       return render_template('simulator.html',ticker_symbol=ticker_symbol_html,ticker_symbol=simulation_symbol)

I thought by specifically calling the mentioned fields and containing them into forms classes, I would avoid an overall validation, but right now I’m failing to make the submit button focus on their own forms. How can I fix this, please?

Answer

You have two forms. One is within the ‘form-1’ div. One is within the ‘form-2’ div. Each one has its own <form> and </form> tags, which means they are separate forms. The first form contains two <input> fields: one called capital_html, one called price_html, and a button called btn. The second form has one <input> field called ticker_symbol_html and a button called btn.

Let’s say the user fills in the first two fields and clicks the first button. That’s going to send a request to whatever the URL is in the <form> tag. In the data, it will send three things:

capital_html=xxx
price_html=yyy
btn=submit

That’s it. That’s all you get. You don’t get any fields from the other form. If the user clicks the other form, all you will get is

ticker_symbol_html=xxx
btn=submit

The problem, as you can see, is there’s no easy way for you to tell which form was submitted. If you have to use the same URL for both, the usual way to solve this is to add a hidden field that gets sent with the data, like:

<input type=hidden name="ident" text="form1">

and in the second one:

<input type=hidden name="ident" text="form2">

Now, your handler can say

    if request.form.get("ident") == "form1":
        # Go handle first form.
    else:
        # Go handle second form.


Source: stackoverflow