1
votes

Update later... I finally get my problem solved. I just wonder if there is a way doing this more elegant?

I'm at the very beginning of programing with Python3, Flask and Jquery.

What I aim to do is that making one SelectField change its value(s) based on another SelectField's option. Just like, when I choose US as country, then automatically load states(say, New York/Washington, D.C./...) from database with ajax help.

Now I could get data using ajax call, which means I could see the response in debug mode of Browser. I just do not know how to fill the specific SelectField with the response data. Below is the relevant code snippet. Thanks in advance for your time.

choose.html

<html>
<head>...</head>
<body>
...
<div class="row">
  <form action="{{url_for('some_view_function')}}" method="post">
    ...
    <div class="col-md-4 col-sm-4 col-xs-12">
      {{ form.country(class="form-control select2_single") }}
    </div>
    <div class="col-md-4 col-sm-4 col-xs-12">
      {{ form.state(class="form-control select2_single") }}
    </div>
    ...
  </form>
</div>
...
<script>
    $(document).ready(function(){
      $("#country").change(function(){
          country_id=$("#country").val();
          $.get("{{ url_for('get_states_by_country') }}",
                {"country_id":country_id},
                function(data, status){
                    if (status == 'success') {
                        // What should I do here with data?
                    }
          });
      });
  });
</script>
</body>
</html>

view_function.py

@app.route('/obtain/states', methods={'GET', 'POST'})
def get_states_by_country():
    country_id = request.args.get("country_id")

    states = State.query.filter_by(
        country_id=country_id
    )
    return jsonify(
        {int(s.state_id): s.state_name
         for s in states}
    )

form.py

class LinkChooseForm(Form):
    country = SelectField(label='Country')
    state = SelectField(label='State')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.country.choices = [(c.id, c.name) for c in Country.query.all()]
        self.state.choices = [] # I leave it empty when initiating

Update-1:
The data is json format. Mock data below. The key would be value of <option>, and value would be text of <option>.

{
  "bash", "desc_for_bash",
  "csh", "desc_for_csh",
  ...
}   

Update-2:
With @Deepak's help, I finally solved this problem. The issue I mentioned under @Deepak's answer(form doesn't accept select option) is post wrong. In fact, form does accept the select option on my html page. I debug that and find out I miss to reset state.choices in my action function. You could notice that I leave the state.choices empty when initiating form object. But flask-wtf would validate that if your choice on page is one of state.choices. Which is obviously not, since I leave it empty. So I must reset it with request.form.get('state') to meet flask-wtf's validation. Below is submit function.

@app.route('/test', methods={'GET', 'POST'})
def some_view_function():
    form = LinkChooseForm(**request.view_args)

    if request.method == 'POST':
        # The most important part here.
        form.state.choices = [(request.form.get('state'), "")]

        if form.validate_on_submit():
            action_entity = ActionEntity()
            action_entity.do(form)
            return redirect(url_for('.another_view_function'))
        else:
            # reset it as empty again
            form.state.choices = []

    return render_template(
        'result.html',
        form=form
    )
1
why cant you use plugins for that.why are you dumping the db - Deepak A
cssscript.com/demo/… please refer this.hope this helps - Deepak A
@Deepak Thanks for your time. But what I put up here is just an example. In fact, I have two SelectFields with specific business meaning, not country and state. - Light.G
can you post your json data or a mock json so that i can write the code - Deepak A
@Deepak I edited my post, is that enough? Thanks. - Light.G

1 Answers

1
votes
var data = '{"bash":"desc_for_bash","csh":"desc_for_csh, city"}';//Your JSON data
data = JSON.parse(data);                                        //To parse your JSON data
var str=''
for(d in data)
str+='<option value="'+d+'">'+data[d]+'</option>'

$("#your_select_id").html(str)                                 //For adding options to select