Oto przykładowa implementacja tej logiki do pracy z natywną funkcjonalnością WTForms. Tutaj chodzi o to, że jeśli chcesz użyć walidacji WTForms, musisz utworzyć formularz z każdą możliwą wartością, a następnie zmodyfikuj dostępne opcje w JavaScript, aby wyświetlić przefiltrowane wartości na podstawie innego wyboru.
W tym przykładzie zamierzam użyć pojęcia stanów i hrabstw (pracuję z wieloma danymi geograficznymi, więc jest to powszechna implementacja, którą tworzę).
Oto moja postać, mam przypisane unikalne identyfikatory do ważnych elementów do nich dostęp z javascript:
class PickCounty(Form):
form_name = HiddenField('Form Name')
state = SelectField('State:', validators=[DataRequired()], id='select_state')
county = SelectField('County:', validators=[DataRequired()], id='select_county')
submit = SubmitField('Select County!')
Teraz, widok Kolba do wystąpienia i przetworzyć postać:
@app.route('/pick_county/', methods=['GET', 'POST'])
def pick_county():
form = PickCounty(form_name='PickCounty')
form.state.choices = [(row.ID, row.Name) for row in State.query.all()]
form.county.choices = [(row.ID, row.Name) for row in County.query.all()]
if request.method == 'GET':
return render_template('pick_county.html', form=form)
if form.validate_on_submit() and request.form['form_name'] == 'PickCounty':
# code to process form
flash('state: %s, county: %s' % (form.state.data, form.county.data))
return redirect(url_for('pick_county'))
Widok kolby odpowiadający na żądania XHR dla hrabstw:
@app.route('/_get_counties/')
def _get_counties():
state = request.args.get('state', '01', type=str)
counties = [(row.ID, row.Name) for row in County.query.filter_by(state=state).all()]
return jsonify(counties)
I wreszcie cript umieścić na dole twojego szablonu Jinja. Zakładam, że wspomniałeś Bootstrap, że używasz jQuery. Zakładam też, że to jest w linii javascript, więc używam Jinja, aby zwrócić poprawny adres URL dla punktu końcowego.
<script charset="utf-8" type="text/javascript">
$(function() {
// jQuery selection for the 2 select boxes
var dropdown = {
state: $('#select_state'),
county: $('#select_county')
};
// call to update on load
updateCounties();
// function to call XHR and update county dropdown
function updateCounties() {
var send = {
state: dropdown.state.val()
};
dropdown.county.attr('disabled', 'disabled');
dropdown.county.empty();
$.getJSON("{{ url_for('_get_counties') }}", send, function(data) {
data.forEach(function(item) {
dropdown.county.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.county.removeAttr('disabled');
});
}
// event listener to state dropdown change
dropdown.state.on('change', function() {
updateCounties();
});
});
</script>
Zarządzam tym z Javascriptem. Interesuje Cię, czy ktoś ma inne rozwiązanie. Pamiętaj, jeśli planujesz użyć formularza.validate_on_submit() w twojej funkcji widoku lista wyborów musi być załadowana z każdą możliwą wartością lub walidacja WTForms zawiedzie. – abigperson
@PJ Santoro Tak, ale jak mogę wywołać JavaScript w polu wtf w szablonie? – fkaralis
Podzielę się poniższym przykładem tego, jak mogę to zaimplementować. – abigperson