2016-12-19 74 views
5

這個新的選擇,試圖建立一個應用程序下面的一個衆所周知的瓶教程,用瓶的自舉,燒瓶wtforms,神社等填入WTForms選擇字段使用值從之前的場

我有2形式選擇字段和一個按鈕。

class Form(FlaskForm): 
    school_year = SelectField('School year', choices=some_tuples_list) 
    category = SelectField('Category', choices=[]) 
    submit = SubmitField('submit') 

我想被預先填充僅第一個字段,並根據上一字段的值選擇其他得到填充(在客戶端?)。

在模板中我嘗試像

{{ form.school_year(**{"onchange":"getCategories()"}) }} 

該工程確定(前提是我返回的元組列表來填充下一個字段,使用適當的javascript和路線),但我想要的東西像下面

{{ wtf.form_field(form.school_year(**{"onchange":"getCategories()"})) }} 

不工作(錯誤:wtforms.widgets.core.HTMLString對象有沒有屬性‘標誌’)

所以,我想我的問題真的是:我如何在此wtf表單字段上實現onChange事件? (這是我必須做的,或者有沒有辦法從視圖功能?)

在此先感謝。

+0

我使用Javascript進行管理。有興趣看看是否有人有不同的解決方案。請記住,如果你打算使用表格。你的視圖函數中的validate_on_submit()選擇選項列表必須加載每個可能的值,否則WTForms驗證將失敗。 – abigperson

+0

@PJ Santoro是的,但是如何在模板中的wtf字段中調用Javascript? – fkaralis

+0

我將在下面分享我如何實現這個功能的例子。 – abigperson

回答

8

這是一個使用WTForms本機功能的邏輯示例實現。這裏的技巧是,如果你想使用WTForms驗證,你需要用每個可能的值實例化表單,然後修改Javascript中的可用選項,以顯示基於另一選擇的過濾值。

對於這個例子,我將使用州和縣的概念(我使用了很多地理數據,所以這是我構建的一個常見實現)。

這是我的形式,我已經分配了唯一的ID中的重要元素,使用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!') 

現在,瓶以實例和處理形式:

@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')) 

Flask視圖響應縣的XHR請求:

@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) 

而且,最後,Java狠狠地放在Jinja模板的底部。我假設你是因爲你提到了Bootstrap,所以你正在使用jQuery。我也假設這是行javascript,所以我使用Jinja返回端點的正確URL。

<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> 
+0

似乎做的工作 - 也提供了一個非常實用的介紹我的jQuery。非常感謝你。 – fkaralis

+0

+1用於使用所有可能的值實例化選擇。我只是花了很多年試圖弄清楚爲什麼表單在使用Javascript更新選項後無法驗證。謝謝! –

+0

我正在使用這個例子,我得到了錯誤NameError:name'State'沒有被定義 – neilH

0

PJ Santoro的回答非常好。加載更新被調用,但事件監聽器一開始並不適用於我。原來我沒有將自己的領域ID換成'狀態',因爲我認爲這是一個關於領域狀態的關鍵字! D'哦!因此,在尋找其他選項時,我發現這也起作用,可能對那裏的某個人有用:

// event listener to state dropdown change 
$('#state').change(function() { 
    updateCounties(); 
}); 
相關問題