简体   繁体   中英

Flask + WTForms + SelectMultipleField and Dynamic Choices

I am trying to use WTForms.SelectMultipleField to manage some dynamic choices on a form but I'm running into some difficulty with it being modified client-side before being submitted for validation.

Basically I have two SelectMultipleField options:

class MyForm(Form):
    assigned = SelectMultipleField('Assigned', choices=[])
    available = SelectMultipleField('Available', choices=[('1','1'),('2','2')])

I'm using Flask to render Jinja2 templates like so:

@app.view("/myview", methods=['GET','POST'])
def myview():
    form = MyForm(request.form)
    if request.method == 'POST' and form.validate():
        return render_template("success.html")
    else:
        return render_template("index.html", form=form)

In my template I have this:

<script type="text/javascript">
    function assign_object() {
        return !$('#available option:selected').remove().appendTo('#assigned');
    };

    function unassign_object() {
        return !$('#assigned option:selected').remove().appendTo('#available');
    }

    $(document).ready( function() {
        $('#available').dblclick( assign_object );
        $('#assigned').dblclick( unassign_object );
    });
</script>

<form action="/myview" method="post" name="assign_objects">
    {{ render_field(form.a) }}
    {{ render_field(form.b) }}
    <input type="submit" value="Assign" name="assign_button"/>
</form>

Basically all of this works as intended; double-clicking on an item in the unassigned list moves it over to the assigned list. The issue is when the form is submitted for validation, because the .choices attribute on the "assigned" field was originally "[ ]" and is still expected to be "[ ]" rather than the new options list that we've given it.

Does anyone know a good way to do this? I was thinking I could override the forms pre_validate() function and update assigned.choices to include all the values from the "available" list, but this doesn't feel "right" and could be used to submit random values from the client-side on submit.

Cheers, David.

Update choices in the POST request:

AVAILABLE_CHOICES = [('1','1'),('2','2')]
DEFAULT_CHOICES = []

class MyForm(Form):
    assigned = SelectMultipleField('Assigned', choices=DEFAULT_CHOICES)
    available = SelectMultipleField('Available', choices=AVAILABLE_CHOICES)

@app.view("/myview", methods=['GET','POST'])
def myview():
    form = MyForm(request.form)
    if request.method == 'POST':
        form.assigned.choices = AVAILABLE_CHOICES
        if form.validate():
            return render_template("success.html")
        else:
            form.assigned.choices = DEFAULT_CHOICES

    return render_template("index.html", form=form)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM