Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic forms from variable length elements: wtforms

I'm using wtforms, and I need to create a something that will generate a form definition based off information in a database; dynamic form creation. I'm getting a sense of what needs to be done and I've just started. I can create forms and use them with wtforms/flask but defining forms from data that will vary slightly from form to form is currently beyond my current skill level.

Has anyone done this and have some input to offer? Somewhat a vague question, no actual code yet. I haven't found any examples, but it is not impossible to do.

mass of variable data to be used in a form --> wtforms ---> form on webpage

EDIT:

So, a 'for example' we can use surveys. A survey consists of several SQLAlcehmy models. A survey is a model with any number of associated questions models(questions belong to surveys and it gets complicated for say, multiple choice questions). To simplify let's use simple json/dict pseudo code for:

{survey:"Number One",
    questions:{
        question:{type:truefalse, field:"Is this true or false"},
        question:{type:truefalse, field:"Is this true or false"},
        question:{type:text, field:"Place your X here"}
     } 
 }

{survey:"Number Two",
    questions:{
        question:{type:text, field:"Answer the question"},
        question:{type:truefalse, field:"Is this true or false"},
        question:{type:text, field:"Place your email address here"}
     } 
 }

Imagine instead of this, several hundred of varying lengths with 5+ field types. How to use WTForms to manage forms for this, or do I even need to use wtforms? I can define static forms as I need them, but not dynamically, yet.

As an aside I've done something like this in rails with simpleform but as I'm working in Python atm (on something different, I'm using the survey thing as an example, but the question/field/answer thing abstracts across a many types of inputs I've needed).

So yes it is possible I'll need to build some sort of factory, doing it will take me some time e.g.:

http://wtforms.simplecodes.com/docs/1.0.2/specific_problems.html

https://groups.google.com/forum/?fromgroups=#!topic/wtforms/cJl3aqzZieA

like image 712
blueblank Avatar asked Oct 06 '22 16:10

blueblank


1 Answers

Simply add the appropriate fields to the base form at run time. Here's a sketch of how you might do it (albeit much simplified):

class BaseSurveyForm(Form):
    # define your base fields here


def show_survey(survey_id):
    survey_information = get_survey_info(survey_id)

    class SurveyInstance(BaseSurveyForm):
        pass

    for question in survey_information:
        field = generate_field_for_question(question)
        setattr(SurveyInstanceForm, question.backend_name, field)

    form = SurveyInstanceForm(request.form)

    # Do whatever you need to with form here


def generate_field_for_question(question):
    if question.type == "truefalse":
        return BooleanField(question.text)
    elif question.type == "date":
        return DateField(question.text)
    else:
        return TextField(question.text)
like image 99
Sean Vieira Avatar answered Oct 10 '22 01:10

Sean Vieira