向 symfony 中的所有表单小部件添加类

发布于 2024-09-03 01:39:18 字数 527 浏览 7 评论 0 原文

我正在尝试找到一种更好的方法来分配类以形成 symfony 中的元素。目前,我似乎无法摆脱手动分配每一项的情况。即:

$this->widgetSchema['title']->setAttribute("class","fieldInput");
$this->widgetSchema['tag_line']->setAttribute("class","fieldInput");
$this->widgetSchema['description']->setAttribute("class","fieldInput");
// etc

我尝试过但没有成功的事情

1)循环遍历$this->widgetSchema,将其视为数组并为每个键设置属性

2)$this->widgetSchema->setAttribute()但这仅将该类应用于生成的标签,而不是表单元素

必须有一种方法可以命中所有字段而无需专门指导它们?

有人能指出我正确的方向吗?

I am trying to find a better way to assign classes to form elements in symfony. Currently, I can't seem to get away from assigning each one manually. ie:

$this->widgetSchema['title']->setAttribute("class","fieldInput");
$this->widgetSchema['tag_line']->setAttribute("class","fieldInput");
$this->widgetSchema['description']->setAttribute("class","fieldInput");
// etc

Things I tried without success

1) looping through $this->widgetSchema, treating it as an array and setting attributes to each key

2) $this->widgetSchema->setAttribute() but this only applied the class to the label that was generated, not the form element

There must be a way to hit all the fields without specifically directing them?

Can anyone point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

高速公鹿 2024-09-10 01:39:18

有一种方法:

在 lib/widget 中创建一个 sfWidgetFormSchemaFormatter,其中包含例如此(代码来自 symfonians ):

class sfWidgetFormSchemaFormatterDiv extends sfWidgetFormSchemaFormatter
{
  protected
    $rowFormat       = "<div class=\"form-row%is_error%\">\n  %label%\n  %error%\n   %hel<div class='myfieldclass'%field%</div>\n p%\n%hidden_fields%</div>\n",
    $errorRowFormat  = "%errors%\n",
    $helpFormat      = '<div class="form-help">%help%</div>',
    $decoratorFormat = "\n  %content%";

  public function formatRow($label, $field, $errors = array(), $help = '', $hiddenFields = null)
  {
    return strtr(parent::formatRow($label, $field, $errors, $help, $hiddenFields), array(
      '%is_error%'    => (count($errors) > 0) ? ' field_error' : '',
      //'%is_required%' => $field,
    ));
  }
}

然后,在您的表单中执行以下操作:

$oDecorator = new sfWidgetFormSchemaFormatterDiv($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('div', $oDecorator);
$this->getWidgetSchema()->setFormFormatterName('div');

然后您可以使用选择器 .myfieldclass input 或任何您想要的内容来设置元素的样式,这是更改表单的结构/外观的好方法。形式。

There is a way:

Create a sfWidgetFormSchemaFormatter in lib/widget, which contains for instance, this (code from symfonians):

class sfWidgetFormSchemaFormatterDiv extends sfWidgetFormSchemaFormatter
{
  protected
    $rowFormat       = "<div class=\"form-row%is_error%\">\n  %label%\n  %error%\n   %hel<div class='myfieldclass'%field%</div>\n p%\n%hidden_fields%</div>\n",
    $errorRowFormat  = "%errors%\n",
    $helpFormat      = '<div class="form-help">%help%</div>',
    $decoratorFormat = "\n  %content%";

  public function formatRow($label, $field, $errors = array(), $help = '', $hiddenFields = null)
  {
    return strtr(parent::formatRow($label, $field, $errors, $help, $hiddenFields), array(
      '%is_error%'    => (count($errors) > 0) ? ' field_error' : '',
      //'%is_required%' => $field,
    ));
  }
}

Then, in your form, do:

$oDecorator = new sfWidgetFormSchemaFormatterDiv($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('div', $oDecorator);
$this->getWidgetSchema()->setFormFormatterName('div');

Then you can style elements with the selector .myfieldclass input or whatever you want, this is a great way to change the structure/look of your forms.

榆西 2024-09-10 01:39:18

从表单类中:

foreach ($this->getWidgetSchema()->getFields() as $field)
{
  $field->setAttribute('class', 'custom-class');
}

如果您有许多表单类需要它,您还可以从自定义 sfWidgetFormSchemaFormatter 类的构造函数中调用该代码:

public function __construct(sfWidgetFormSchema $widgetSchema)
{
    parent::__construct($widgetSchema);

    foreach ($this->getWidgetSchema()->getFields() as $field)
    {
        $field->setAttribute('class', 'custom-class');
    }
}

From within the form class:

foreach ($this->getWidgetSchema()->getFields() as $field)
{
  $field->setAttribute('class', 'custom-class');
}

You could also call that code from the constructor of a custom sfWidgetFormSchemaFormatter class if you have many form classes that need it:

public function __construct(sfWidgetFormSchema $widgetSchema)
{
    parent::__construct($widgetSchema);

    foreach ($this->getWidgetSchema()->getFields() as $field)
    {
        $field->setAttribute('class', 'custom-class');
    }
}
风吹过旳痕迹 2024-09-10 01:39:18

我有同样的问题。

情况
我们开始认为,CSS 和 symfony 的小部件生成之间的分离对于集成商来说是一个很大的学习曲线,我们认为必须有一种方法让集成商更加独立于开发人员。

客户总是希望拥有自定义样式的表单...然而,自定义手工制作!DRY 代码已完成。我的意思是,平面设计师不会只用输入文本和标签来设计表单,他们会找到所有创造性的方法,而我们的现实是使其在框架中工作,使其看起来与他们的设计相同。

这就是为什么我们考虑使用 sfWidgetFormSchemaFormatter,但表单控制器都是不同的,我们希望能够从视图注入样式......因为这是一个集成问题,而不是应用程序问题。本身。

解决方案路径
我和我的团队领导想出了一个解决方案。主要使用部分并循环它们。表单视图可能如下所示。

我们的解决方案并不完美,因为我们想通过视图中的调用来说明哪个控制器可以获得哪些类名。但这比使用 CSS 的 input[type=text] 更好,因为我们的客户端仍然使用 < IE8。但至少,

所以我们想到了为什么不将字段 id 映射到可能具有不同行为的 className(与 label+input 不同(当然还有 +helper+error 如果需要的话))。

我们所做的是为那些特殊控制器注入控制样式(例如:label+select+select+select+helper+error),假设这个 Widget 有 id some_field_id 并且我们需要它给父级 <代码>

  • 我们可以这样做:

    $node_classes_map => array('some_field_id'=>'date-selector')
    

    所以...现在是一些代码的时候了:

    首先,我们需要使用“列表”widgetFormatter:

    <?php
    // lib/form/SomeForm.php
    class SomeForm extends BaseSomeForm
    {
       public function configure()
       {
           $this->widgetSchema->setFormFormatterName('list');
       }
    }
    

    或者,您可以使用 qais 答案 将所有表单作为列表(最后!!我之前不知道)。

    视图:

    <?php
    // apps/appName/modules/moduleName/templates/someviewSuccess.php
    $node_classes_map = array(
      'some_field_id'=>'date-selector'
       // .date-selector would have many select side by side. 
       // (no CSS for that in this example)
    );
    include_partial('global/patterns/formParent',
        array(
            'form'=>$form,
            'form_classes'=>'labels-on-left',
            'node_classes_map' => $node_classes_map
        )
    );
    

    formParent 看起来像:

    <?php
    // apps/appName/templates/_patterns/formParent.php
    $form_classes_attr = (isset($form_classes))?' class="'.$form_classes.'"':'';
    $form_list_node_partial = 'global/patterns/listFormDefaultNode';
    $model_name_lowercase = strtolower($form->getModelName());
    $node_classes_map = (isset($node_classes_map))?$node_classes_map:array();
    ?>
    <?php use_stylesheets_for_form($form) ?>
    <?php use_javascripts_for_form($form); ?>
    <form action="<?php 
        echo url_for($model_name_lowercase.'/'.($form->getObject()->isNew() ? 'create' : 'update').(!$form->getObject()->isNew() ? '?id='.$form->getObject()->getId() : ''))
    ?>"<?php echo $form_classes_attr;
    ?> method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" '?>>
    <h2><?php echo __(($form->getObject()->isNew()?'new.':'edit.').$model_name_lowercase.'.form.title'); ?></h2>
    <fieldset>
        <ol>
    <?php
        foreach($form as $item){
            $node_classes = (isset($node_classes_map[$item->renderId()]))?$node_classes_map[$item->renderId()]:'';
            include_partial($form_list_node_partial,
                array(
                    'item'=>$item,
                    'node_classes' => $node_classes
                )
            );
        }
    ?>
        <ol>
    </fieldset>
    <?php echo $form->renderHiddenFields() ?>
    <?php echo $form->renderGlobalErrors() ?>
    <?php echo (!$form->getObject()->isNew())? '<input type="hidden" name="sf_method" value="put" />':''; ?>
    </form>
    

    每个表单元素都由自定义元素或 listFormDefaultNode 呈现。

    从那里,您可以想出一个不同的部分来渲染控制器,从主流标签+输入+帮助器+错误到更复杂的东西,如标签+选择+选择+选择+帮助器+错误。

    这是我的默认形式 *Node

    <?php
    // apps/appName/templates/_patterns/listFormDefaultNode.php
    /**
     * Manual: http://www.symfony-project.org/forms/1_4/en/A-Widgets
     */
    if(!$item->isHidden()){ ?>
    <li class="<?php echo $item->renderId().((is_string($node_classes))?' '.$node_classes:''); ?>">
      <?php echo $item->renderLabel(); ?>
      <?php echo $item; ?>
      <?php echo (!!$item->renderHelp())?'<span class="helpers">'.$item->renderHelp().'</span>':''; // I did not find any hasHelper(), so switching to bool ?>
      <?php echo ($item->hasError())?'<span class="alertify error">'.$item->renderError().'</span>':''; ?>
    </li>
    <? }
    

    最后,这是我的 CSS 的开始:

    请注意,这是项目 CSS 的一部分,这使用了我正在开发的部分概念 Snippies。去那里获得更多关于我如何构建 CSS 的想法。

    /* ****** Misc ****** */
    /**
     * General form views settings
     **/
    form ol, form ul {
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
    form input.text, form select {
      display: block;
      border: 0;
      padding: 4px;
      line-height: 12px;
      font-size: 15px;
    }
    form select {
      background-color: #e3e8eb;
      color: #506775;
      margin: 0;
    }
    form label {
      color: #345569;
      display: block;
      font-weight: bold;
      margin-bottom: 5px;
    }
    form input.text {
      color: #345569;
      border: none;
      background-color: #e3e8eb;
      color: #738996;
      border: 0px solid #c3c987;
      padding: 4px;
      line-height: 12px;
      width: 100%;
    }
    form fieldset {
      padding: 0;
      margin: 0;
      border: none;
      padding-bottom: 10px;
      margin-bottom: 10px;
      border-bottom: 1px solid #98a7af;
      padding: 10px 0;
    }
    form li {
      margin-bottom: 10px;
    }
    form li .helpers {
      color: #98a7af;
    }
    /**
     * /General form views settings
     **/
    
    
    /**
     * General error messages 
     **/
    .alertify {
      padding: 0.8em;
      margin-bottom: 1em;
      border: 2px solid #ddd;
    }
    .alertify strong, .alertify p {
      padding: 0 0 10px 0;
      display: block;
    }
    .alertify ul {
      margin: 0;
      padding: 0 0 0 15px;
    }
    .alertify ul li {
      padding: 0 0 5px 0;
    }
    .error, .alert {
      background: #fbe3e4;
      color: #8a1f11;
      border-color: #fbc2c4;
    }
    /**
     * /General error messages 
     **/
    /* ****** /Misc ****** */
    
    
    /* ****** Specialization ****** */
    /**
     * Form labels on the left
     */
    form.labels-on-left fieldset {
      padding: 0;
      margin: 0;
      padding-bottom: 10px;
      margin-bottom: 10px;
    }
    form.labels-on-left li {
      clear: both;
      overflow: hidden;
    }
    form.labels-on-left li input.text, form.labels-on-left li select {
      border: 0;
      padding: 4px;
      line-height: 12px;
    }
    form.labels-on-left li input.text {
      width: 815px !important;
      float: left;
      padding: 6px;
      color: #506775;
    }
    form.labels-on-left li select {
      background-color: #e3e8eb;
      color: #506775;
      height: 26px;
      width: 400px;
      margin: 0;
      float: left;
    }
    form.labels-on-left li .beside {
      float: left;
    }
    form.labels-on-left li .beside a {
      font-weight: bold;
      padding: 5px 20px;
      font-size: 14px;
      display: block;
    }
    form.labels-on-left li label {
      color: #345569;
      width: 80px;
      font-size: 120%;
      text-align: right;
      font-weight: bold;
      float: left;
      display: block;
      padding: 5px 10px 0 0;
    }
    form.labels-on-left li .error span, form.labels-on-left li .helpers span {
      padding: 5px;
      display: block;
    }
    form.labels-on-left li .helpers {
      width: 100%;
    }
    /**
     * /Form labels on the left
     */
    /* ****** /Specialization ****** */
    

    I am having the same issue.

    Situation
    We have come to think that the separation between CSS and symfony's widget generation is a big learning curve for the integrators and we think there must be a way to leave the integrators more independent from the developers.

    Client always want to have custom styled forms... and yet, custom handmade !DRY code is done. What I mean is that, Graphic designers do not design forms with only input text and label, they find all creative ways and our reality is to make it work in the framework to look the same as they design.

    That's why we thought of using a sfWidgetFormSchemaFormatter, but form controllers are all different, and we wanted to be able to inject styling FROM the views... because it's an integration matter, not application matter. per se.

    Solution path
    My team-lead and I came up to a solution. Mostly using partials and looping through them. A form view could look like what follows.

    Our solution is not perfect because we'd like to say by the call in the view which controller could get which class names. But it's better than to use CSS's input[type=text] because our client still uses < IE8. But at least,

    So we thought of Why not mapping field id's with a className that could have a different behavior (different from label+input (and of course +helper+error if needs be)).

    What we do is that we inject control style for those special controllers (e.g.: label+select+select+select+helper+error) let's say this Widget has id some_field_id and we need it to the parent <li>.

    We could do it like this:

    $node_classes_map => array('some_field_id'=>'date-selector')
    

    So... now's time for some code:

    First, we need to use the 'list' widgetFormatter:

    <?php
    // lib/form/SomeForm.php
    class SomeForm extends BaseSomeForm
    {
       public function configure()
       {
           $this->widgetSchema->setFormFormatterName('list');
       }
    }
    

    Or, you could use qais answer to have ALL forms as lists (at last!! I didn't knew before now).

    The view:

    <?php
    // apps/appName/modules/moduleName/templates/someviewSuccess.php
    $node_classes_map = array(
      'some_field_id'=>'date-selector'
       // .date-selector would have many select side by side. 
       // (no CSS for that in this example)
    );
    include_partial('global/patterns/formParent',
        array(
            'form'=>$form,
            'form_classes'=>'labels-on-left',
            'node_classes_map' => $node_classes_map
        )
    );
    

    formParent looks like:

    <?php
    // apps/appName/templates/_patterns/formParent.php
    $form_classes_attr = (isset($form_classes))?' class="'.$form_classes.'"':'';
    $form_list_node_partial = 'global/patterns/listFormDefaultNode';
    $model_name_lowercase = strtolower($form->getModelName());
    $node_classes_map = (isset($node_classes_map))?$node_classes_map:array();
    ?>
    <?php use_stylesheets_for_form($form) ?>
    <?php use_javascripts_for_form($form); ?>
    <form action="<?php 
        echo url_for($model_name_lowercase.'/'.($form->getObject()->isNew() ? 'create' : 'update').(!$form->getObject()->isNew() ? '?id='.$form->getObject()->getId() : ''))
    ?>"<?php echo $form_classes_attr;
    ?> method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" '?>>
    <h2><?php echo __(($form->getObject()->isNew()?'new.':'edit.').$model_name_lowercase.'.form.title'); ?></h2>
    <fieldset>
        <ol>
    <?php
        foreach($form as $item){
            $node_classes = (isset($node_classes_map[$item->renderId()]))?$node_classes_map[$item->renderId()]:'';
            include_partial($form_list_node_partial,
                array(
                    'item'=>$item,
                    'node_classes' => $node_classes
                )
            );
        }
    ?>
        <ol>
    </fieldset>
    <?php echo $form->renderHiddenFields() ?>
    <?php echo $form->renderGlobalErrors() ?>
    <?php echo (!$form->getObject()->isNew())? '<input type="hidden" name="sf_method" value="put" />':''; ?>
    </form>
    

    Each form element gets rendered by either a custom one or listFormDefaultNode.

    From there, you could come up with a different partial to render a controller differently from a mainstream label+input+helper+errors to something more complex like label+select+select+select+helper+erros.

    This is my default form *Node

    <?php
    // apps/appName/templates/_patterns/listFormDefaultNode.php
    /**
     * Manual: http://www.symfony-project.org/forms/1_4/en/A-Widgets
     */
    if(!$item->isHidden()){ ?>
    <li class="<?php echo $item->renderId().((is_string($node_classes))?' '.$node_classes:''); ?>">
      <?php echo $item->renderLabel(); ?>
      <?php echo $item; ?>
      <?php echo (!!$item->renderHelp())?'<span class="helpers">'.$item->renderHelp().'</span>':''; // I did not find any hasHelper(), so switching to bool ?>
      <?php echo ($item->hasError())?'<span class="alertify error">'.$item->renderError().'</span>':''; ?>
    </li>
    <? }
    

    Lastly, here is a start from my CSS:

    Please note, here is a part of a project CSS and this uses part of concepts i'm developping with Snippies. Go there to get more ideas how I am structuring my CSS.

    /* ****** Misc ****** */
    /**
     * General form views settings
     **/
    form ol, form ul {
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
    form input.text, form select {
      display: block;
      border: 0;
      padding: 4px;
      line-height: 12px;
      font-size: 15px;
    }
    form select {
      background-color: #e3e8eb;
      color: #506775;
      margin: 0;
    }
    form label {
      color: #345569;
      display: block;
      font-weight: bold;
      margin-bottom: 5px;
    }
    form input.text {
      color: #345569;
      border: none;
      background-color: #e3e8eb;
      color: #738996;
      border: 0px solid #c3c987;
      padding: 4px;
      line-height: 12px;
      width: 100%;
    }
    form fieldset {
      padding: 0;
      margin: 0;
      border: none;
      padding-bottom: 10px;
      margin-bottom: 10px;
      border-bottom: 1px solid #98a7af;
      padding: 10px 0;
    }
    form li {
      margin-bottom: 10px;
    }
    form li .helpers {
      color: #98a7af;
    }
    /**
     * /General form views settings
     **/
    
    
    /**
     * General error messages 
     **/
    .alertify {
      padding: 0.8em;
      margin-bottom: 1em;
      border: 2px solid #ddd;
    }
    .alertify strong, .alertify p {
      padding: 0 0 10px 0;
      display: block;
    }
    .alertify ul {
      margin: 0;
      padding: 0 0 0 15px;
    }
    .alertify ul li {
      padding: 0 0 5px 0;
    }
    .error, .alert {
      background: #fbe3e4;
      color: #8a1f11;
      border-color: #fbc2c4;
    }
    /**
     * /General error messages 
     **/
    /* ****** /Misc ****** */
    
    
    /* ****** Specialization ****** */
    /**
     * Form labels on the left
     */
    form.labels-on-left fieldset {
      padding: 0;
      margin: 0;
      padding-bottom: 10px;
      margin-bottom: 10px;
    }
    form.labels-on-left li {
      clear: both;
      overflow: hidden;
    }
    form.labels-on-left li input.text, form.labels-on-left li select {
      border: 0;
      padding: 4px;
      line-height: 12px;
    }
    form.labels-on-left li input.text {
      width: 815px !important;
      float: left;
      padding: 6px;
      color: #506775;
    }
    form.labels-on-left li select {
      background-color: #e3e8eb;
      color: #506775;
      height: 26px;
      width: 400px;
      margin: 0;
      float: left;
    }
    form.labels-on-left li .beside {
      float: left;
    }
    form.labels-on-left li .beside a {
      font-weight: bold;
      padding: 5px 20px;
      font-size: 14px;
      display: block;
    }
    form.labels-on-left li label {
      color: #345569;
      width: 80px;
      font-size: 120%;
      text-align: right;
      font-weight: bold;
      float: left;
      display: block;
      padding: 5px 10px 0 0;
    }
    form.labels-on-left li .error span, form.labels-on-left li .helpers span {
      padding: 5px;
      display: block;
    }
    form.labels-on-left li .helpers {
      width: 100%;
    }
    /**
     * /Form labels on the left
     */
    /* ****** /Specialization ****** */
    
    薄暮涼年 2024-09-10 01:39:18

    这是旧的,但对于任何试图找到它的人来说,只需进入 /lib/filter/doctrine/ 内的 xxxxxFormFilter.php 并执行以下操作:

    $this->getWidget('inputname')->setAttribute('class_name','class_name/id_name');
    

    这样您就可以单独指定和控制所有内容。

    This is old but for anyone trying to find this just go into the xxxxxFormFilter.php inside /lib/filter/doctrine/ and do this:

    $this->getWidget('inputname')->setAttribute('class_name','class_name/id_name');
    

    This way you can individually specify and control everything.

    哀由 2024-09-10 01:39:18

    根据您扩展的基本表单,您可以在配置方法中添加以下内容:

    public function configure()
    {
        foreach ($this->widgetSchema->getFields() as $field) {
            $field->setAttribute('class','my-custom-class');
        }
        parent::configure();
    }
    

    我在 BaseFormDoctrine 中完成了我的操作。您可以使用相同的方法添加/覆盖字段中的任何属性,甚至可以根据字段类型添加自定义规则。

    Depending on what base form you extend, you can add the following in the configure method:

    public function configure()
    {
        foreach ($this->widgetSchema->getFields() as $field) {
            $field->setAttribute('class','my-custom-class');
        }
        parent::configure();
    }
    

    I did mine in BaseFormDoctrine. You can use the same approach to add/override any attribute in the field or even add custom rules based on field type.

    月下凄凉 2024-09-10 01:39:18

    将类应用于父元素,而不是单个元素:

    TEMPLATE:

    <form class="my-form" action="" method="">
     // put widgets here
    </form>
    

    CSS:

    .my-form select {}
    .my-form input[type=text] {}
    .my-form textarea {}
    .my-form input[type=submit] {}
    etc...
    

    Apply the class to a parent element, not the individual elements:

    TEMPLATE:

    <form class="my-form" action="" method="">
     // put widgets here
    </form>
    

    CSS:

    .my-form select {}
    .my-form input[type=text] {}
    .my-form textarea {}
    .my-form input[type=submit] {}
    etc...
    
    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文