Как изменить класс ошибки обертки div при использовании CakePHP с помощью Bootstrap
Я использую Bootstrap 3.0RC1
с CakePHP 2.3.6
. Пытаясь воспользоваться преимуществами тех красиво выглядящих классов, как has-error
и has-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="[email protected]">
<span class="help-block">Email already in use.</span>
</div>
Все просто отлично, за исключением того, что мне нужно изменить класс error
в оберточном div на has-error
, поэтому для label
, input
и span
применяются новые стили. Пока не найдено чистого решения.
Уродливое решение, я думал, это скопировать стили has-error
из Bootstrap в класс error
в моем приложении.
Ответы
Ответ 1
Если вы закроете FormHelper
, вы найдете в этой строке "уродливый" код, делающий магию ошибок.
Поскольку исходные авторы не оставили никаких шансов сделать это по конфигурации, я предлагаю вам написать собственный 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;
}
}
}
Поскольку я уже использую пользовательские BootstrapFormHelper
, здесь ссылка на полный текст.
Просто скопируйте файл в app\View\Helper
и добавьте в ВСЕ свои контроллеры следующую строку:
public $helpers = array(
'Form' => array('className' => 'BootstrapForm')
);
предполагая, что вы сохранили gist как BootstrapFormHelper.php
.
Ответ 2
РЕШЕНИЕ я ИСПОЛЬЗОВАНИЕ:
Каждый раз, когда вы создаете новый ввод, проверяйте, есть ли какие-либо ошибки для этого поля, используя функцию 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'))
)
); ?>
Ответ 3
Несколько менее уродливое решение состоит в том, чтобы добавить ваш селектор для этого типа ошибки div в ваш загрузочный CSS файл. Таким образом, вы не копируете все значения стиля, вы просто добавляете свои разделители ошибок в существующие определения стиля.
Другим вариантом будет использование javascript для изменения этих классов с "error" на "has-error" на DOMREADY, хотя ваша страница будет выглядеть странно до этого времени. Не совсем чистое решение.
Ответ 4
Я согласен с первым ответом Дерека, добавив ваши стили в файл 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;
}
Ответ 5
Я никогда не использовал CakePHP, но я осмеливаюсь публиковать ответ здесь. Я думаю, что элемент сообщения должен иметь возможность переносить несколько классов, как и любой другой элемент.
Итак, простое редактирование:
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-block has-error'))
Я не вижу причин копировать и вставлять код css.
Ответ 6
Я использовал jQuery.
<script>
$(document).ready(function() {
$('.form-control').parent('.error').each(function() {
$(this).addClass('has-error');
});
});
</script>
Ответ 7
Я использую пользовательский помощник, который адаптирован к любой структуре CSS. В этом случае 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'));