如何将 table 下拉列表 select 字段发送到烧瓶

How to send table dropdown select fields to flask

我有一个 table 由三列组成,一个文本和另外两个 select 字段。 当用户从下拉列表中选择一个选项时 select,我想将这些数据发送到 flask。

我知道我可以让它与 inputs 一起工作,但由于我正在与 select 一起工作,我不确定如何将它们送回 flask。

这是我的 table:

<div class="row" id="tablediv">
    <div class="col">
        <table class="table table-striped table-bordered" id="table"/>
    </div>
</div>


const office_cardgroups = data['cardgroups']
const office_doorgroups = data['doorgroups']

const table = document.getElementById("table");
const header = table.createTHead();
var row = header.insertRow(0);
row.insertCell(0).innerHTML = "<b>Departments</b>";
row.insertCell(1).innerHTML =  "<b>Card Groups</b>";
row.insertCell(2).innerHTML =  "<b>Door Groups</b>";

{% for department in departments %}
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);
    row.insertCell(0).innerHTML = "{{ department.name }}";
    var row_cardgroup = '<td className="select"><select id="cardgroups_{{ department.id }}">'

    for (const [key, cardgroup] of Object.entries(office_cardgroups)) {
        var row_cardgroup = row_cardgroup + '<option value=' + cardgroup['id'] + '>'+ cardgroup['name']+'</option>'
    }
    row_cardgroup = row_cardgroup + '</select></td>'

    row.insertCell(1).innerHTML = row_cardgroup

    var row_doorgroup = '<td className="select"><select id="cardgroups_{{ department.id }}">'

    for (const [key, doorgroup] of Object.entries(office_doorgroups)) {
        var row_doorgroup = row_doorgroup + '<option value=' + doorgroup['id'] + '>'+ doorgroup['name']+'</option>'
    }

    row_doorgroup = row_doorgroup +  '</selec></td>'

    row.insertCell(2).innerHTML = row_doorgroup

{% endfor %}

共享代码中有几个问题:

  • table 标签没有自动关闭所以应该是
<table class="table table-striped table-bordered" id="table"></table>
  • 不确定 data['cardgroups']data['doorgroups'] 来自哪里,如果它们来自后端到 jinja 模板,那么它应该用括号括起来 {{}}
  • 既然你在写 javascript 它应该在 script 标签内
  • id 在 html 中应该是唯一的,现在我们在 select
  • 中有 2 个同名的 ID cardgroups_{{ department.id }}

示例中使用的数据

data = {
    "departments": [{
        "id": 1,
        "name": "Dept 1",
    }, {
        "id": 2,
        "name": "Dept 2",
    }, {
        "id": 3,
        "name": "Dept 3",
    }],
    "cardgroups": [{
        "id": 4,
        "name": "Card 1",
    }, {
        "id": 5,
        "name": "Card 2",
    }, {
        "id": 6,
        "name": "Card 3",
    }],
    "doorgroups": [{
        "id": 7,
        "name": "Door 1",
    }, {
        "id": 8,
        "name": "Door 2",
    }, {
        "id": 9,
        "name": "Door 3",
    }],
}

有两种方法可以将数据发送到后端

使用表格

您可以用带有提交按钮的表单包装 table 并在 select 标签中添加名称,这样数据就可以在 request.form

中使用
<div class="row" id="tablediv">
  <div class="col">
    <form method="POST">
      <table class="table table-striped table-bordered" id="table"></table>
      <input type="submit" />
    </form>
  </div>
</div>

<script>
    const office_cardgroups = {{ data['cardgroups'] | safe }}
    const office_doorgroups = {{ data['doorgroups'] | safe }}

    const table = document.getElementById("table");
    const header = table.createTHead();
    var row = header.insertRow(0);
    row.insertCell(0).innerHTML = "<b>Departments</b>";
    row.insertCell(1).innerHTML =  "<b>Card Groups</b>";
    row.insertCell(2).innerHTML =  "<b>Door Groups</b>";

    {% for department in data['departments'] %}
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        row.insertCell(0).innerHTML = "{{ department.name }}";
        var row_cardgroup = '<td className="select"><select name="cardgroups_{{ department.id }}">'

        for (const [key, cardgroup] of Object.entries(office_cardgroups)) {
            var row_cardgroup = row_cardgroup + '<option value=' + cardgroup['id'] + '>'+ cardgroup['name']+'</option>'
        }
        row_cardgroup = row_cardgroup + '</select></td>'

        row.insertCell(1).innerHTML = row_cardgroup

        var row_doorgroup = '<td className="select"><select name="doorgroups_{{ department.id }}">'

        for (const [key, doorgroup] of Object.entries(office_doorgroups)) {
            var row_doorgroup = row_doorgroup + '<option value=' + doorgroup['id'] + '>'+ doorgroup['name']+'</option>'
        }

        row_doorgroup = row_doorgroup +  '</selec></td>'

        row.insertCell(2).innerHTML = row_doorgroup

    {% endfor %}
</script>
@app.route('/', methods=["GET", "POST"])
def index():
    print(request.form)
    return render_template('index.html', data=data)

使用javascript

<div class="row" id="tablediv">
  <div class="col">
    <table class="table table-striped table-bordered" id="table"></table>
    <button id="send-data">Submit</button>
  </div>
</div>

<script>
    const office_cardgroups = {{ data['cardgroups'] | safe }}
    const office_doorgroups = {{ data['doorgroups'] | safe }}

    const table = document.getElementById("table");
    const header = table.createTHead();
    var row = header.insertRow(0);
    row.insertCell(0).innerHTML = "<b>Departments</b>";
    row.insertCell(1).innerHTML =  "<b>Card Groups</b>";
    row.insertCell(2).innerHTML =  "<b>Door Groups</b>";

    {% for department in data['departments'] %}
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        row.insertCell(0).innerHTML = "{{ department.name }}";
        var row_cardgroup = '<td className="select"><select id="cardgroups_{{ department.id }}">'

        for (const [key, cardgroup] of Object.entries(office_cardgroups)) {
            var row_cardgroup = row_cardgroup + '<option value=' + cardgroup['id'] + '>'+ cardgroup['name']+'</option>'
        }
        row_cardgroup = row_cardgroup + '</select></td>'

        row.insertCell(1).innerHTML = row_cardgroup

        var row_doorgroup = '<td className="select"><select id="doorgroups_{{ department.id }}">'

        for (const [key, doorgroup] of Object.entries(office_doorgroups)) {
            var row_doorgroup = row_doorgroup + '<option value=' + doorgroup['id'] + '>'+ doorgroup['name']+'</option>'
        }

        row_doorgroup = row_doorgroup +  '</selec></td>'

        row.insertCell(2).innerHTML = row_doorgroup

    {% endfor %}

    const departments = {{ data['departments'] | safe }}

    document.querySelector('#send-data').addEventListener('click', function() {
        const form_data = new FormData();
        departments.forEach(function(department) {
            let card_id = `cardgroups_${department.id}`;
            form_data.append(card_id, document.querySelector("#" + card_id).value);
            let door_id = `doorgroups_${department.id}`;
            form_data.append(door_id, document.querySelector("#" + door_id).value);
        })
        const url = 'http://localhost:5000/';
        const xhr = new XMLHttpRequest();

        xhr.open( 'POST', url, true );
        // xhr.setRequestHeader('Content-Type', 'multipart/form-data');
        xhr.onreadystatechange = function ( response ) {};
        xhr.send( form_data );

        // using jQuery
        // $.ajax({
        //   url: url,
        //   data: form_data,
        //   processData: false,
        //   contentType: false,
        //   type: 'POST',
        //   success: function(data){
        //     alert(data);
        //   }
        // });
    });
</script>
@app.route('/', methods=["GET", "POST"])
def index():
    print(request.form)
    return render_template('index.html', data=data)

改进:模板仅使用 jinja no javascript

<div class="row" id="tablediv">
  <div class="col">
    <table class="table table-striped table-bordered" id="table">
      {% for department in data['departments'] %}
        <tr>
          <td>{{ department.name }}</td>
          <td className="select">
            <select id="cardgroups_{{ department.id }}">
              {% for card in data['cardgroups'] %}
                  <option value='{{ card.id }}'>{{ card.name }}</option>
              {% endfor %}
            </select>
          </td>
          <td className="select">
            <select id="doorgroups_{{ department.id }}">
              {% for door in data['doorgroups'] %}
                  <option value='{{ door.id }}'>{{ door.name }}</option>
              {% endfor %}
            </select>
          </td>
        </tr>
      {% endfor %}
    </table>
  </div>
</div>

注意:如果您想分别发送每个 select 值,您可以 addEventListener 到每个 select。