Symfony2 - 自定义窗体外的按钮

时间:2014-04-08 17:14:46

标签: forms symfony button

表单和页面布局有问题。我通过以下方式呈现我的页面:

{% block body -%}
{{ form(edit_form, {'style': 'horizontal'}) }}
    <ul class="record_actions">
        <li>
            <a href="{{ path('organization') }}">
                <button type="button" class="btn btn-default">Back to the list</button>
            </a>
        </li>
        <li>
            {{ form(delete_form) }}
        </li>
 {% endblock %}

我在ul record_actions上有一些风格。它看起来像这样:http://postimg.org/image/sby8jnojz/

我的问题是更新按钮。我想将其与其他2个按钮放在<ul>标签中。是否有可能将其置于形式之外?我喜欢,表单与{{ form(edit_form, {'style': 'horizontal'}) }}的外观如何。所以我不想按{{form_widget}}自定义每个部分。或者是否有可能渲染所有表格,然后只渲染此按钮?

2 个答案:

答案 0 :(得分:5)

更新回答

让我们采用一种假设的控制器方法 - 我已经定义了两种形式edit_formdelete_form。不要太担心这些,它们只是概念的证明。这里重要的是我有两个表单要发送给要呈现的模板:

// Foo\BarBundle\Controller\BazController
public function editAction()
{
    // a placeholder 'edit' form
    $editForm = $this->createFormBuilder()
        ->add('name', 'text')
        ->add('email', 'email')
        ->add('send', 'submit')
        ->getForm();

    // a placeholder 'delete' form
    $deleteForm = $this->createFormBuilder(['id' => 1])
        ->add('id', 'hidden')
        ->getForm();

    // assign form views to template
    return [
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    ];
}

接下来的模板。我们有两种表单可供呈现:edit_formdelete_form。我们需要考虑几个问题 - 在表单中呈现表单不允许,因此我们无法在delete_form内呈现edit_form,反之亦然。

但是,正如我在下面解释的那样,我们可以使用HTML5 form属性在<form>上下文之外放置表单元素,并将它们链接到该表单(具有上述IE *限制)。所以,让我们这样做,并在适当的时候提出一个解决方法。

最不具侵入性的事情是在delete_form之后呈现edit_form,但将edit_form删除按钮放在 edit_form内。< / p>

我不知道你是否使用CSS framewok来帮助你进行布局 - 我假设Bootstrap 2. *这里你可能需要更新你的标记 - 无论哪种方式,这个想法应该足够清楚:

<div class="row">
    {{ form_start(edit_form, {'attr': {'id': 'edit-form'}}) }}
    <div class="span4">
        <ul class="record_actions">
            <li>{{ form_widget(edit_form.send)}}</li>
            <li><button id="delete-form-submit" form="delete-form">
                Delete
                </button>
            </li>
        </ul>
    </div>
    <div class="span4">
        {{ form_rest(edit_form) }}
    </div>
    {{ form_end(edit_form) }}
</div>

{{ form(delete_form, {'attr': {'id': 'delete-form'}, 'method': 'GET'}) }}

以上HTML产生的布局类似于以下内容:

enter image description here

几点解释:

  1. 我为表单创建了一个双列布局。 .record_actions按钮在左列上呈现 - 这是必不可少的 - 但在这种情况下,它们会使用Bootstrap的.pull-right向右浮动。

    1. 更新按钮:我要做的第一件事就是在submit中呈现ul.record_actions我需要的地方:<li>{{ form_widget(edit_form.send)}}</li>

    2. 删除按钮:我没有在submit上定义delete_form按钮,因为我想在{{1}的上下文之外明确创建它而是把它放在我拥有的地方。请注意,我在此元素上定义了一个名为delete_form的表单属性。这会将此元素与delete-form而不是delete_form相关联:edit_form

    3. 剩余字段:在第二列中,我可以隐式使用<li><button id="delete-form-submit" form="delete-form">Delete</button></li>转储所有剩余的edit_form字段,按照 @Kix 的建议!

    4. 删除表单最后,我们使用{{ form_rest(edit_form) }}delete_form外面呈现edit_form 。这里需要注意几点 - 我们明确为{{ form(delete_form, {'attr': {'id': 'delete-form'}, 'method': 'GET'}) }}添加表单的ID。这很重要,因为它是删除按钮引用的属性。在这种情况下,我还添加了{'attr': {'id': 'delete-form'}来测试我的机器。您可能希望将其保留(在这种情况下,默认为'method': 'GET'

  2. 你有它......这应该可以帮助你定义你喜欢的布局。

    但是,我们仍然需要解决IE问题。如果您使用的是jQuery,则可以在删除按钮中添加一个单击处理程序,我们已为其分配了标识POST。请注意,以下是建议,未经过测试:

    #delete-form-submit

    现在您需要担心已禁用JS的IE用户...或者不是! ;)希望这有帮助。


    原始回答

    我认为你的问题可能与Symfony无关......让我解释一下:

    您是否使用表单构建器创建表单的$(function() { if ($.browser.msie) { // @see: http://api.jquery.com/jquery.browser/ $('#delete-form-submit').on('click', function(e) { e.preventDefault(); $('#delete-form').submit(); }); }); }); 按钮?我假设你是因为你没有在上面粘贴的twig片段中明确创建一个。

    当然这完全没问题。我通常只是定义我的Twig表单模板,我收集的是较旧的方法(因为2.4文档似乎没有建议如下):

    submit

    在我看来,这种方式完全可以接受 - 您只是不定义<form class="form-horizontal" action="{{ path('foo_edit') }}" method="post" {{ form_enctype(edit_form) }}> {{ form_widget(edit_form) }} <input type="submit"> </form> 按钮。

    当然这并不能解决您的问题,因为您想要“突破”表单。但实际上,您可以使用带有submit属性的HTML5执行此操作,该属性允许您将不同的标记链接到特定标记。一般例子:

    form

    请注意,<form id="foo"> <label>Username</label> <input type="text" name="username"> </form> <ul> <li><input type="submit" form="foo"> </ul> 按钮位于submit之外,但form#foo属性仍然链接到它。

    显然它的用处仅限于您想要支持的浏览器范围,因为它是HTML5功能。

    修改

    我查了一下 - 它有非常广泛的浏览器支持,除了.... drumroll IE。显然,包括IE10在内。不幸的是,我认为这是一个破坏者。

    kix 上面的方法可以很好地工作,但是打印出你想要的单个表单小部件,然后使用form。我想补充一点,并说它可能与上面的HTML布局不完全一致 - 如果您在调用form_rest 之前必须明确打印出任何字段。

答案 1 :(得分:2)

您始终可以使用

在特定于布局的位置渲染一些小部件
{{ form_widget(delete_form.yourWidgetName) }}

然后让Symfony用

填写表单
{{ form_rest(delete_form) }}