【问题标题】:Symfony2 - Customizing buttons out of formsSymfony2 - 从表单中自定义按钮
【发布时间】:2014-04-08 17:14:46
【问题描述】:

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

{% 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 个按钮将它放入 &lt;ul&gt; 标签中。有没有可能把它放在形式之外?我喜欢{{ form(edit_form, {'style': 'horizontal'}) }} 的表单外观。所以我不想通过{{form_widget}} 自定义每个部分。或者是否有可能渲染所有表单,然后只渲染这个按钮?

【问题讨论】:

    标签: forms symfony button


    【解决方案1】:

    更新答案

    让我们假设一个控制器方法 - 我定义了两种形式 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。我们需要考虑几个问题 - 不允许在表单中呈现表单,因此我们不能在 edit_form 中呈现 delete_form,反之亦然。

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

    最少侵入性的做法是在edit_form 之后渲染delete_form,但将edit_form 删除按钮放在edit_form 内部

    我不知道您是否使用 CSS 框架来帮助您进行布局 - 我假设 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 产生了一个类似于下面的布局:

    几点说明:

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

      1. 更新按钮:我要做的第一件事是将submit 按钮呈现在我想要的ul.record_actions 中:&lt;li&gt;{{ form_widget(edit_form.send)}}&lt;/li&gt;

      2. 删除按钮:我没有在delete_form 上定义submit 按钮,因为我想在delete_form 的上下文之外显式创建它,而不是放置它我在哪里。请注意,我在此元素上定义了一个名为 delete-form 的表单属性。这会将这个元素链接到delete_form 而不是edit_form&lt;li&gt;&lt;button id="delete-form-submit" form="delete-form"&gt;Delete&lt;/button&gt;&lt;/li&gt;

      3. 剩余字段:根据 @Kix 的建议,在第二列中,我可以使用 {{ form_rest(edit_form) }} 隐式转储所有剩余的 edit_form 字段!

      4. 删除表单最后,我们将delete_form edit_form 之外 渲染为{{ form(delete_form, {'attr': {'id': 'delete-form'}, 'method': 'GET'}) }}。这里有几点需要注意——我们明确地为带有{'attr': {'id': 'delete-form'} 的表单添加了一个id。这很重要,因为它是删除按钮所引用的属性。在这种情况下,我还添加了'method': 'GET' 以在我的机器上进行测试。您可能希望忽略它(在这种情况下,它默认为 POST

    你有它......这应该可以帮助你定义你的首选布局。

    但是,我们仍然需要解决 IE。如果您使用的是 jQuery,您可以向删除按钮添加一个单击处理程序,我们已为其分配了 ID #delete-form-submit。请注意,以下是建议,未经测试:

    $(function() {
      if ($.browser.msie) { // @see: http://api.jquery.com/jquery.browser/
        $('#delete-form-submit').on('click', function(e) {
          e.preventDefault();
          $('#delete-form').submit();
        });
      });
    });
    

    现在您需要担心禁用 JS 的 IE 用户...与否! ;) 希望这会有所帮助。


    原答案

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

    您是否使用表单构建器创建表单的submit 按钮?我假设是这样,因为您没有在上面粘贴的 twig sn-p 中明确创建一个。

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

    <form class="form-horizontal" action="{{ path('foo_edit') }}" method="post" {{ form_enctype(edit_form) }}>
        {{ form_widget(edit_form) }}
        <input type="submit">
    </form>
    

    这种方式在我看来是完全可以接受的——你只是没有定义submit按钮。

    当然这并不能解决你的问题,因为你要“突围”出表格。但是您实际上可以使用带有form 属性的HTML5 来做到这一点,它允许您将不同的标签链接到特定的标签。一个通用的例子:

    <form id="foo">
        <label>Username</label>
        <input type="text" name="username">
    </form>
    <ul>
        <li><input type="submit" form="foo">
    </ul>
    

    注意submit 按钮在form#foo 之外,但form 属性仍然链接到它。

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

    编辑

    我检查过 - 它有相当广泛的浏览器支持,除了.... drumroll IE。显然包括IE10。不幸的是,我认为这会破坏交易。

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

    【讨论】:

    • 感谢您的回答。这对我来说听起来很好。但我遇到了一些问题。我真的不知道我必须使用输入标签中的哪个参数。 (&lt;input form="?"&gt;)。我试图查看 {{ form(edit_form) }} 使用哪个参数,但没有成功。
    • 嗨。好的,我不熟悉 `{{ form(edit_form) }} 语法 - 我更喜欢上面的方法。当然,无论哪种方式都很好。无论如何,我正在为你调查这个,看看我是否可以提出进一步的建议。我想我可以提供一个答案 - 有一些警告。一会儿……
    • 我也尝试了您的表单创建,但我也没有管理好。因为,当我单击按钮时,它会在更新后将我重定向到同一页面,但 symfony 没有来自控制器的变量,我将它们发送到视图。
    • 这正是我想要的。感谢您的广泛回复!
    • 没问题 - 这就是 SO 的用途 :) 很高兴为您提供帮助!
    【解决方案2】:

    您始终可以使用

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

    然后让 Symfony 用

    完成表格
    {{ form_rest(delete_form) }}
    

    【讨论】:

    • form_rest()点赞!
    猜你喜欢
    • 2013-09-20
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    相关资源
    最近更新 更多