Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-part form using Flask / WTForms

I have a multi-part form to generate - think similar workflow to a Shopping Cart where you have multiple "sections" (eg details, billing, payment etc) for the one form that display one at a time.

Key Details:

  • I have 3 sections to the form
  • The sections must be completed in sequence and Section 2 relies on information from Section 1
  • The form data is useless (eg will be thrown away) unless the person completes the FULL process (Section 1, 2 and 3).

Ways I've considered approaching this:

  • Using the one Route def and storing a value in request.args that tells me which "Section" I am at then render_template a different Form template depending on the section. This feels hacky...
  • Having a different Route and View for each section. This feels wrong and I'd have to stop people from going directly to Step 2 via URL
  • Putting all Sections on the one form, using Javascript to hide portions of the one form and moving between sections that way

What's the best method to accomplish this in Flask/WTForms? None of the methods I've posted above seem right and I have no doubt this is a fairly common requirement.

like image 210
mal-wan Avatar asked Nov 18 '15 00:11

mal-wan


1 Answers

The most elegant solution will no doubt require some javascript as you mentioned in your last idea. You can use JS to hide the different parts of your form and perform the necessary checks and/or data manipulations on the client side and ONLY when that is correct and complete submit it to your flask route.

I have used the first method you mentioned. Here is what it looked like:

@simple_blueprint.route('/give', methods=['GET', 'POST'])
@simple_blueprint.route('/give/step/<int:step>', methods=['GET', 'POST'])
@login_required
def give(step=0):
    form = GiveForm()
    ...
    return blah blah

You are right that this feels "hacky". However it can work if the route doesn't have to do much else besides handling the form. The way my route worked was to collect data and then ask users a bunch of questions about the data. The way you are explaining your situation, with the need to collect data on each step, I would really recommend the javascript solution.

like image 57
Dan Safee Avatar answered Oct 27 '22 20:10

Dan Safee