4

In a website I'm building with Flask I'm using WTForms for form validation. I currently have a field which is dependent on another field: if a user inserts a specific year (2012) a couple radio buttons are inserted using Javascript. I made the RadioField optional, which works fine, but if I actually do submit the form with the radiobuttons the value of it remains None.

To talk some code; the two relevant form fields are defined as follows:

construction_year = IntegerField('construction_year')
transfer_tax_rate = SelectField('transfer_tax_rate', validators=[Optional()], choices=[('ZERO', '0%'), ('SIX', '6%')])

the code I first used in the template to display the construction_year and transfer_tax_rate is as follows:

{{ form.construction_year(size=10) }}
{{ form.transfer_tax_rate() }}

This works fine; I can print out the values on the back end like so:

if form.validate_on_submit():
    print form.construction_year.data  # prints out '2012'
    print form.transfer_tax_rate.data  # prints out ZERO or SIX depending on my choice

I then removed {{ form.transfer_tax_rate() }} and wrote some Javascript which inserts the some html if the construction_year is 2012:

function displayTransferTaxRate(){
    var year = $("#construction_year").val();
    var propertyType = $("#property_type").val();
    if (year.length == 4 && year == 2012) {
        var transferTaxRateHtml = 'Applicable tax rate <select id="transfer_tax_rate" name="transfer_tax_rate"><option value="ZERO">0%</option><option value="SIX">6%</option></select>';
        $('#transfer-tax-rate-div').html(transferTaxRateHtml);
    } else {
        $('#transfer-tax-rate-div').html('');
    }
}
$("#construction_year").on('keyup paste', displayTransferTaxRate);

for easy reading; the html it inserts is as follows:

<select id="transfer_tax_rate" name="transfer_tax_rate">
    <option value="ZERO">0%</option>
    <option value="SIX">6%</option>
</select>

The html gets inserted fine, and I can select either of the options. But when I submit the form and try to get the value of the transfer_tax_rate as follows, it always prints out None:

if form.validate_on_submit():
    print form.construction_year.data  # prints out '2012'
    print form.transfer_tax_rate.data  # prints out None

Does anybody have any idea what I'm doing wrong here? All tips are welcome!

[EDIT] Following the tip from user3147268 below I aslo tried getting it from the standard flask request.form, but that doesn't contain an entry for 'transfer_tax_rate' either.

7
  • 1
    Did you pass the form from the view to the template in which there's your javascript code? Commented Nov 3, 2014 at 18:10
  • @boh - Yes I did. All the other fields show up fine, and return fine. Everything else works perfectly well. It's just that one field that doesn't return well. I suspected that it is because I create it dynamically using js, but I have no idea if that's true, or how I can solve it. Commented Nov 3, 2014 at 21:07
  • Instead of using form.transfer_tax_rate.data you could try request.form['transfer_tax_rate'] which is provided by Flask itself. Commented Nov 4, 2014 at 14:10
  • I've created the same form, commeted {{ form.transfer_tax_rate() }} out and entered the usually by flask-wtf rendered HTML manually inside the browser to simulate your JS. Everything worked fine. You should look at your JS code. Maybe you inserted the HTML not properly or you misspelled the code, that I added manually. Commented Nov 4, 2014 at 14:19
  • 1
    @boh - In the end I solved it, but it was a pretty weird reason (see my answer below). Thanks for your time and energy! Commented Nov 4, 2014 at 16:05

1 Answer 1

4

Okay, after about 5 hours of banging my head against the wall, I'll answer my own question, because you guys could not have known this.

It turns out that it was related to a table in which this form was embedded. I left that information out, because I didn't expect that to be relevent.

So this works fine:

<table>
    <form action="" method="post" id="prop-form">
        {{ form.hidden_tag() }}
        <tr>
            <td>Construction year: </td>
            <td>
                {{ form.construction_year(size=10) }}
            </td>
        </tr>
        <tr>
            <td>Transfer tax rate: </td>
            <td>
                {{ form.transfer_tax_rate()
            </td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="Save property"></td>
        </tr>
    </form>
</table>

But when I add the exact same html in this div, it doesn't work anymore:

<table>
    <form action="" method="post" id="prop-form">
        {{ form.hidden_tag() }}
        <tr>
            <td>Construction year: </td>
            <td>
                {{ form.construction_year(size=10) }}
                <div id="transfer-tax-rate-div"></div>
            </td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="Save property"></td>
        </tr>
    </form>
</table>

whereas, without the table around it, it does work:

<form action="" method="post" id="prop-form">
{{ form.hidden_tag() }}
Construction year: {{ form.construction_year(size=10) }} <br />
<div id="transfer-tax-rate-div"></div>
<input type="submit" value="Save property">
</form>

The solution turned out to lie in the placement of the <form> tags, because if I move them out of the table like this last piece of code, it all works fine:

<form action="" method="post" id="prop-form">
{{ form.hidden_tag() }}
<table>
    <tr>
        <td>Construction year: </td>
        <td>
            {{ form.construction_year(size=10) }}
            <div id="transfer-tax-rate-div"></div>
        </td>
    </tr>
    <tr>
        <td></td>
        <td><input type="submit" value="Save property"></td>
    </tr>
</table>
</form>

Excuse me for bothering all you guys and girls time whilst not providing all the relevant information. Thank you for giving me the energy to keep on looking though!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.