在单击按钮时,Flask Jinja2模板重新加载生成的表

时间:2018-12-06 11:14:28

标签: python jquery ajax flask jinja2

我有一个在烧瓶中运行的应用程序,它将用于在我的云平台上自动配置服务器。

其中一个页面可让您上传电子表格,然后将其解析为交互式(可编辑)html <table>

在填充表格时,将验证填充的字段。如果任何字段无效,则该字段的类将更改以突出显示最终用户需要在何处进行编辑。

然后有一个验证器按钮,它将获取当前的html表并在其上再次运行验证,效果很好。但是,它不会重新加载html表,因此由于类未更改,用户更改的所有无效字段都将突出显示。

我需要在此处进行哪些更改以确保刷新表?

这是代码。

烧瓶:

# upload spreadsheet and validate
@app.route('/upload/', methods=['GET','POST'])
def upload():
    # if a file is attempted to be uploaded, save file and parse it
    if request.method == 'POST' and request.files:
        f = request.files['file']
        f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))
        myexcel = os.path.join(app.config['UPLOAD_FOLDER'], f.filename)
        myJson = exc.Parse(myexcel)
        mySpreadsheet = spreadsheet.zip_list(myJson)
        return render_template('upload2.html', spreadsheet=mySpreadsheet)
    # if the validate button is clicked, validate and repopulate table:
    elif request.method == 'POST' and not request.files:
        data = request.get_json()
        data = json.loads(str(data['rows']).replace("'",'"'))
# Test print. this prints the data as expected on click of the validate button
        pprint(data) 
        mySpreadsheet = spreadsheet.zip_list(data)
        return render_template('upload2.html', spreadsheet=mySpreadsheet)
    else:
        return render_template('upload2.html')

HTML表:

(是的,这是一张大桌子!)

<!-- bunch of table headers here -->
{% for row in spreadsheet %}
  <tr class="{{ loop.cycle('color1', 'color2') }}">
  {% for i in range(36) %}
    {% if "-invalid" in row[i]|string %}
      <td contenteditable="true" class="red table-editable">{{ row[i]|replace("-invalid", "") }}</td>
    {% else %}
      <td contenteditable="true" class="table-editable">{{ row[i] }}</td>
    {% endif %}
  {% endfor %}
{% endfor %}

HTML验证:

<div class="container">
  <button id="validate" value="validate" class="button" >Validate Spreadsheet</button>
</div>

Jquery / AJAX:

// on validate, send potentially updated table in json format to flask
$('#validate').click(function() {
var $table = $("table")
    rows = [],
    header = [];
$table.find("thead th").each(function () {
    header.push($.trim($(this).text()));
});
$table.find("tbody tr").each(function () {
    var row = {};
    $(this).find("td").each(function (i) {
        var key = header[i],
            value = $(this).text();
        row[key] = value;
    });
    rows.push(row);
});
    $.ajax({
        type: "POST",
        contentType: "application/json;charset=utf-8",
        url: "/upload/",
        traditional: "true",
        data: JSON.stringify({rows}),
        dataType: "json"
    });
});

因此AJAX可以毫无问题地将数据发送到flask,但是当elif语句被接收时,它似乎并没有使用新数据重新呈现模板。

很抱歉,很长的帖子,在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

所以,就像你自己说的那样,整个问题可以用这句话来概括:

因此AJAX可以毫无问题地将数据发送到flask,但是当该elif语句被接收时,它似乎并没有使用新数据重新呈现模板。

这是因为,当您发送POST请求时,不会自动解释服务器的响应。您必须对服务器响应进行某些操作,例如渲染它。

因此,您需要向ajax请求中添加一个成功参数:

$.ajax({
    type: "POST",
    contentType: "application/json;charset=utf-8",
    url: "/upload/",
    traditional: "true",
    data: JSON.stringify({rows}),
    dataType: "json",
    success: function(response){
        console.log(response)
        document.open();
        document.write(response);
        document.close();
    },
    error: function (jqXHR, status, err) {
      console.log(jqXHR, status, err);
    }
});

由于服务器当前响应的是完整呈现的html页面,因此您可以覆盖示例中显示的页面现有内容(不过是一种不好的做法)。

最好进行新的路由,特别是为了验证表中的所有内容是否正确。您可能还考虑在html td中使用onChange()解决此问题,并编写一个javascript函数来检查输入现在是否有效,以防止整个ajax调用。