使用CakePHP和Bootstrap时如何修改包装器div错误类

时间:2013-08-07 19:52:35

标签: css cakephp twitter-bootstrap

我正在Bootstrap 3.0RC1使用CakePHP 2.3.6。为validation states尝试利用has-errorhas-warning这些美观的类,我需要更改默认元素类FormHelper添加到包装div。

到目前为止,我正在使用此代码:

echo $this->Form->create('User', array(
    'inputDefaults' => array(
        'class' => 'form-control',
        'div' => array('class' => 'form-group'),
        'label' => array('class' => 'control-label'),
        'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-block'))
    )
)); 

echo $this->Form->input('email'));

哪个会在出错时输出:

<div class="form-group error">
    <label for="UserEmail" class="control-label">Email</label>
    <input name="data[User][email]" class="form-control form-error" type="email" value="a@a.com">
    <span class="help-block">Email already in use.</span>
</div>

一切都很好,除了我需要将包装div中的error类更改为has-error,因此新的样式会应用于labelinputspan。到目前为止找不到干净的解决方案。

我认为这个丑陋的解决方案是将has-error样式从Bootstrap复制到我应用中的error类。

7 个答案:

答案 0 :(得分:10)

如果您反省FormHelper,那么您将find in this line“丑陋”的代码可以执行错误魔法。

由于原始作者没有通过配置留下任何机会,我建议您编写自己的BootstrapFormHelper,并通过更改该单行覆盖输入函数。

这是片段:

//inside public function input($fieldName, $options = array())

$out['error'] = null;
if ($type !== 'hidden' && $error !== false) {
    $errMsg = $this->error($fieldName, $error);
    if ($errMsg) {
        $divOptions = $this->addClass($divOptions, 'has-error'); //old string value was 'error'
        if ($errorMessage) {
            $out['error'] = $errMsg;
        }
    }
}

由于我已使用自定义BootstrapFormHelperhere is link to full gist

只需将文件复制到app\View\Helper,然后在此行中添加 ALL 您的控制器:

public $helpers = array(
  'Form' => array('className' => 'BootstrapForm')
);

假设您已将gist保存为BootstrapFormHelper.php

答案 1 :(得分:10)

解决方案我使用:

每当你创建一个新输入时,使用CakePhp函数isFieldError()检查该字段是否有任何错误,只需将“has-error”类附加到div,就像我在下面所做的那样:

只需设置div:

'div' => array('class' => "form-group ".($this->Form->isFieldError('username') ? 'has-error' : '')),

一个字段的完整代码:

<?php echo $this->Form->input(
    'username',
    array(
        'label' => array('text' => 'Username', 'class' => 'strong'), 'placeholder' => "Your Username", 'class' => 'form-control', 
        'div' => array('class' => "form-group ".($this->Form->isFieldError('username') ? 'has-error' : '') ),
        'error' => array('attributes' => array('wrap' => 'p', 'class' => 'help-block has-error'))
        )
); ?>

答案 2 :(得分:1)

稍微不那么难看的解决方案是将特定类型的错误div的选择器添加到bootstrap的CSS文件中。这样你就不会复制所有的样式值,只需将你的错误div添加到现有的样式定义中。

另一种选择是在DOMREADY上使用javascript将这些类从'error'更改为'has-error',尽管在此之前你的页面看起来会很奇怪。不是一个干净的解决方案。

答案 3 :(得分:1)

我同意Dereks的第一个答案,将你的风格添加到Bootstrap CSS文件中。

第1590-1611行


    .has-error .help-block,
    .has-error .control-label {
      color: #b94a48;
    }

    .has-error .form-control {
      border-color: #b94a48;
      -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    }

    .has-error .form-control:focus {
      border-color: #953b39;
      -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
    }

    .has-error .input-group-addon {
      color: #b94a48;
      background-color: #f2dede;
      border-color: #b94a48;
    }

您应该将其更改为:


    .error .help-bloc, .has-error .help-block,
    .error .control-label, .has-error .control-label {
      color: #b94a48;
    }

    .error .form-control, .has-error .form-control {
      border-color: #b94a48;
      -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    }

    .error .form-control:focus, .has-error .form-control:focus {
      border-color: #953b39;
      -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
    }

    .error .input-group-addon, .has-error .input-group-addon {
      color: #b94a48;
      background-color: #f2dede;
      border-color: #b94a48;
    }

答案 4 :(得分:0)

我从未使用过CakePHP,但我敢在这里发布答案。我认为message元素应该能够像任何其他元素那样携带多个类。

所以简单的编辑是:

'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-block has-error'))

我认为没有理由复制和粘贴css代码。

答案 5 :(得分:0)

我使用了jQuery。

<script>
$(document).ready(function() {
    $('.form-control').parent('.error').each(function() {
        $(this).addClass('has-error');
    });
});
</script>

答案 6 :(得分:0)

我使用为CSS框架定制的自定义Helper。在这种情况下,Bootstrap。

<?php

App::uses('AppHelper', 'View/Helper');

class UIHelper extends AppHelper
{
    public $helpers = array('Html', 'Form');

    public function textBox($fieldName, $options = array()) {
        $options += array('class' => 'form-control', 'div'=>false, 'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-block')));

        if (isset($options['label'])) {
            if (is_array($options['label'])) {
                $options['label'] += array('class' => 'control-label');
            } else {
                $options['label'] = array('text' => $options['label'], 'class' => 'control-label');
            }
        } else {
            $options['label'] = array('class' => 'control-label');
        }

        $divOptions = array('class' => "form-group has-feedback");
        if (isset($options['div'])) {
            if (is_array($options['div'])) {
                $divOptions += $options['div'];
            }
        }
        $options['div'] = false;                

        $divText = $this->Form->input($fieldName, $options);

        if ($this->Form->isFieldError($fieldName)) {
            $divOptions['class'] = "form-group has-error has-feedback";
            $divText .= $this->Html->tag('span', null, array('class' => "glyphicon glyphicon-remove form-control-feedback"));
        }

        return $this->Html->tag('div', $divText, $divOptions);
    }

}

?>

然后使用此代替标准Form助手

echo $this->UI->textBox('email'));