如何将表单“提交”到ajax脚本而不是回到Flask?

时间:2015-06-26 19:25:14

标签: jquery python ajax flask celery

目标: 模拟this example(长条与条)有一点不同:我需要传递提交表单中的值列表。

这是我的form.py:

class InstallForm(Form):
  servers = SelectField(u'Server Names', validators = [required()])
  prop_files = SelectField(u'Properties Files', validators = [required()])
  mod_files = SelectField(u'Mod Files', validators = [required()])
  build = SelectField(u'Build Type', validators = [required()])
  do_install = SelectField(u'Do Install?', validators = [required()])
  submit = SubmitField('Submit')

以下是路线:

用户最初来到/ installer

@servers.route('/installer', methods=['GET', 'POST'])
def installer():

    servers = UcxServer.query.order_by(UcxServer.name)
    file_options = Install(app.config['LOADER_LOCATION']).get_options()

    form = InstallForm()
    form.servers.choices = [(s.ip_address, s.name) for s in servers]
    form.prop_files.choices = [(f,f) for f in file_options['props']]
    form.mod_files.choices = [(f,f) for f in file_options['mods']]
    form.build.choices = [("'ci'",'ci'), ("'nightly'",'nightly')]
    form.do_install.choices = [('TRUE','TRUE'), ('FALSE','FALSE')]


    if form.validate_on_submit():
      install_list = [form.prop_files.data, form.mod_files.data,      
                      form.build.data, form.servers.data, form.do_install.data]

    return render_template('installer.html') <- what to do here?

return render_template('installer.html', form=form)

我正在使用wtf.quick_form()呈现此表单。

这是我完全迷失的模板:

{{ wtf.quick_form(form) }}

<div id="progress"></div>

<script src="//cdnjs.cloudflare.com/ajax/libs/nanobar/0.2.1/nanobar.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
    function start_long_task() {
        // add task status elements
        div = $('<div class="progress"><div></div><div>0%</div><div>...</div><div>&nbsp;</div></div><hr>');
        $('#progress').append(div);

        // create a progress bar
        var nanobar = new Nanobar({
            bg: '#44f',
            target: div[0].childNodes[0]
        });

        // send ajax POST request to start background job
        $.ajax({
            type: 'POST',
            url: '/longtask',
            data: $('form').serialize()
            success: function(data, status, request) {
                status_url = request.getResponseHeader('Location');
                update_progress(status_url, nanobar, div[0]);
            },
            error: function() {
                alert('Unexpected errorS');
            }
        });
    }
    function update_progress(status_url, nanobar, status_div) {
        // send GET request to status URL
        $.getJSON(status_url, function(data) {
            // update UI
            percent = parseInt(data['current'] * 100 / data['total']);
            nanobar.go(percent);
            $(status_div.childNodes[1]).text(percent + '%');
            $(status_div.childNodes[2]).text(data['status']);
            if (data['state'] != 'PENDING' && data['state'] != 'PROGRESS') {
                if ('result' in data) {
                    // show result
                    $(status_div.childNodes[3]).text('Result: ' + data['result']);
                }
                else {
                    // something unexpected happened
                    $(status_div.childNodes[3]).text('Result: ' + data['state']);
                }
            }
            else {
                // rerun in 2 seconds
                setTimeout(function() {
                    update_progress(status_url, nanobar, status_div);
                }, 2000);
            }
        });
    }
    $(function() {
        $('#button').click(start_long_task);
    });

我的路线中也有一个芹菜任务,还有一个重定向路线,其中有一个带有task.id的位置标题,以便我可以获得状态更新。

EDIT1:

更具体一点:

单击提交时,表单中选择的数据应转到:

$.ajax({
        type: 'POST',
        url: '/longtask',
        data: $('form').serialize()

而不是

if form.validate_on_submit():
    install_list = [form.prop_files.data, form.mod_files.data,    form.build.data, form.servers.data, form.do_install.data]
    flash(install_list)
    return render_template('installer.html', form=form)

2 个答案:

答案 0 :(得分:1)

虽然您已为用户点击#button元素添加了监听器,但除非您使用jquery.submit()为该特定操作添加处理程序,否则表单仍会提交:

$(function() {
    $('form').submit(function(event) {
        event.preventDefault();
        start_long_task();
    });
});

答案 1 :(得分:1)

解决了我遇到的问题。以下是同一艘船上其他人的一些亮点。

  • 放弃了wtf.quick_form 新表单如下所示:

     <form action="" id='ucx'>
     {{ form.hidden_tag() }}
     <dl>
     {{ render_field(form.servers) }}
     {{ render_field(form.prop_files) }}
     {{ render_field(form.mod_files) }}
     {{ render_field(form.build) }}
     {{ render_field(form.do_install) }}
     </dl>
     <p><input type="button" value="Install!" onclick="start_long_task()">
     </form>
    

我没有使用提交,而是使用链接到长任务功能的按钮。 在函数内部,我得到了这样的形式的值:

        myArray =  [];
        myArray.push(document.getElementById('prop_files').value);
        myArray.push(document.getElementById('mod_files').value);
        myArray.push(document.getElementById('build').value);
        myArray.push(document.getElementById('servers').value);
        myArray.push(document.getElementById('do_install').value);

然后我使用AJAX将其传递回Web服务器,如下所示:

    .ajax({
            type: 'POST',
            url: '/longtask',
            data: JSON.stringify(myArray),
            contentType: "application/json; charset=utf-8",
            dataType: "json",

希望这有助于其他人。 顺便说一下,如果我对自己的方式完全愚蠢,我就会渴望学习。

谢谢!