Symfony2/Twig 页面上的多表单处理

Symfony2/Twig multiple form handling on page

作为一般主题提出了类似的问题,但没有真正得到有帮助的答案。我有以下模板

{% block main %}
    <div class="col-md-4">
        <section class="panel panel-default">
            <header class="panel-heading">
                <h3 class="panel-title">Terminal</h3>
            </header>

            <div class="panel-body">
                <form action="{{ path('NickAlertBundle_tsubmit') }}" method="post" enctype="multipart/form-data" class="terminalForm" id="terminalForm">
                    <div class="row">
                        <div class="col-md-12">
                            <input type="text" class="addMargin" id="terminal_command" name="terminal_command" placeholder=">">
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-md-8 col-md-offset-4">
                            <input type="submit" class="btn btn-default" id="terminal_submit" value="Submit">
                        </div>
                    </div>
                </form>
            </div>
        </section>
    </div>

    <div class="col-md-8" id="terminal-window">
        <table class="terminalAvailability">
            {% if data is defined %}
                {% for info in data %}
                    <tr>
                        <td class="flightNumber">{{ info.flightNumber }}</td>
                        <td class="details">{{ info.from ~ info.to }}</td>
                        {% for seat, availability in info.seats %}
                            <td class="seatClass"><span>{{ seat ~ availability }}</span></td>
                        {% endfor %}
                        <td class="otherInfo">{{ info.other }}</td>
                    </tr>
                {% endfor %}
            {% endif %}
        </table>
    </div>

    <div class="modal"></div>
{% endblock %}

简而言之,我有一个接受命令输入的表单,当提交时,命令针对 API 执行。然后视图返回显示在第二个 div 中的响应。响应如下所示

AB123   |  LHRLAX  |  J9  I7  C9  D9  A6   |  -0655 0910
--------------------------------------------------------
CF1153  |  LHRLAX  |  I7  J7  Z9  T9  V7   |  -0910 1305
--------------------------------------------------------
WF133   |  LHRLAX  |  Y7  T7  J9  T9  C9   |  -1500 2206

Letter/number组合由座位~可用性产生。我需要让这些组合可选择,选择后它们可以改变颜色。为此,我简单地完成了

$(function() {
    $( ".terminalAvailability .seatClass" ).on( "click", function() {
        $(this).find('span').toggleClass('green');
    });
});

我将提供一个提交按钮(没有表单),提交时,我需要将适当的数据传递给我的 ajax 函数。此数据应包括仅包含所选 seat/availability 组合的行中的所有数据。因此,如果我从第 1 行选择 J9 和 C9,从第 3 行选择 T7,则提交的数据应该是

AB123   |  LHRLAX  |  J9  C9  |  -0655 0910
--------------------------------------------------------
WF133   |  LHRLAX  |  T7  |  -1500 2206

收集正确的数据并将其传回我的 Ajax 函数(最终传回我的控制器)的最佳方法是什么?

谢谢

我会使用 <input type="checkbox" /> 使页面的表单部分清晰并轻松处理它的状态。

例如,您有:

{% for seat, availability in info.seats %}
    <td class="seatClass"><span>{{ seat ~ availability }}</span></td>
{% endfor %}

我会这样写:

{% for seat, availability in info.seats %}
    <td class="seatClass">
        <label for="{{ seat }}">
            <span>{{ seat ~ availability }}</span>
        </label>
        <input type="checkbox" id="{{ seat }}" name="{{ seat }}" style="display: none;" />
    </td>
{% endfor %}

显然,您还需要将 <form /> 元素放在 for 循环之外才能完成。

之所以有效,是因为标签的 for 属性与 inputid 属性匹配,将切换关联的 input。因此,如果您删除隐藏复选框的样式,并单击跨度内容,它将选中或取消选中 input。现在你有一个实际的表单值可以使用 javascript 和 AJAX.

很容易处理

有了这个,你可以很容易地将每个输入的值设置为相应的row/seat,你甚至可以在适用的时候使用HTML5 "checked"。

更新:(评论太多)
您可以使用其中一种方法或两种方法的组合将更多信息传递给您的控制器。一种是用信息创建一个 <input type="hidden" />。我可以想象这是在 for 循环之外,其中包含航班号、出发和到达信息等:意味着适用于每一行和每个座位的任何内容。

向控制器传递信息的另一种方法是使用表单 "arrays"。

应该是这样的(注意方括号):

{% for seat, availability in info.seats %}
    <td class="seatClass">
        <label for="{{ seat }}">
            <span>{{ seat ~ availability }}</span>
        </label>
        <input type="checkbox" id="{{ seat }}" name="{{ row }}[{{ seat }}]" style="display: none;" />
    </td>
{% endfor %}

然后您将收到一个包含提交数据的数组(如果选择了两个席位),您可以循环访问该数组。例如,如果用户选择同一行的两个座位,您将拥有:

[row1] => [seat1, seat2]

更新2
我刚刚意识到,如果选中该复选框,则意味着该座位将是用户想要的座位(虽然它以前是可用的,但因为他拿走了它,它不再是)。那么,为什么不将 "desired" 作为 <input /> 的值传递,为什么不将 "seat-desired" 分配给该行呢?为了更清楚地解释我自己:

<input type="checkbox" id="{{ seat }}" name="seats[{{ row }}][]" style="display: none;" value="{{ seat }}" />

现在,每个通过的 "seat" 都是您知道的 "chosen"。

在您的控制器中,您将遍历 seat 以查找任何行。然后,通过循环找到的任何行都会找到座位。例如:

foreach ($request->request->get('seats') as $row) {
    foreach ($row as $seat) {
        $seat->setSeatAsTaken($flight, $passenger);
    }
}