Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript/Ajax to Dynamically Update WTForms Select Field

OK. I know this has been tackled many times but I can't find an answer with a useful example of javascript to use.

Say I have this form:

class MyForm(Form):
    category = SelectField("Category")
    issue = SelectField("Issue")

What I need is for whatever is selected in 'category' at runtime to determine what the user sees in the issue dropdown without a POST of any kind ocurring. I know how to dynamically create the choices in the view from my database query. I even have gone so far as to create a dictionary of "issue choices" based off of category choices.

I just can't for the life of me figure out the javascript I need so that on select of something from the category drop down determines whats in the issue dropdown.

like image 759
aizimmer Avatar asked Jan 05 '16 18:01

aizimmer


2 Answers

I found the info I needed by looking at the example at Flask jQuery AJAX Example - - it is a minimal working example, almost a GIST or a book chapter.

like image 157
aizimmer Avatar answered Oct 30 '22 18:10

aizimmer


I came up with an example very close to jsbueno's implementation. You can find the Gist here. The .py file is a standalone example.

In your html template use jquery to register an ajax request when you click the select field. If the request is a success the html for the select field gets updated with the new select options (send as a response from the server). Look at the actual HTML generated by the template to see how the select field looks like.

<form action="" method="post" id="selectDevice" name="device">
    Nummber of Devices: {{ form.selectAmount(size=1) }}
    Select device: {{form.deviceAddress() }}
</form>
<script type="text/javascript" charset="utf-8">
$("#deviceAddress").click(function(){
    $.ajax({
        url: '/selectform',
        type: 'POST',
        data: $('#selectDevice').serialize(),
        success: function(selectOptions){
            $("#deviceAddress").empty();
            for (var i = 0; i < selectOptions.length; i++){
                $("#deviceAddress").append(
                    $("<option></option>")
                    .attr("value", selectOptions[i][0])
                    .text(selectOptions[i][1])
                );
            }
        }
    });
});
</script>

On the server side, use a route for the ajax post request.`As example this route changes the options depending on another form field (the information got send over with the data tag in the ajax request). In WTForms the select field options is a list of tuples containing an ID and name, I kept this the same on the python side.

@app.route('/selectform', methods=['POST'])
def updateselect():
    deviceAmount = int(request.form.get('selectAmount'))
    choices = [('device{}'.format(i), i) for i in range(deviceAmount)]
    response = make_response(json.dumps(choices))
    response.content_type = 'application/jsons'
    return response`

Only one remark: the ajax request is performed on dropping down and on collapsing. The last part is not necessary of course, there is probably a way to structure the jquery so it only requests on dropdown.

like image 2
Ron Schutjens Avatar answered Oct 30 '22 19:10

Ron Schutjens