I\'m using Bootstrap 3.0RC1
with CakePHP 2.3.6
. Trying to take advantage of those beautiful looking classes like has-error
and has-w
I agree with Dereks first answer, adding your styles into the Bootstrap CSS file.
Lines 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; }
You should change this to:
.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; }
A slightly less ugly solution is to add your selector for that specific type of error div to your bootstrap's CSS file. That way you're not copying all the style values, you're simply adding your error divs to the existing style definitions.
Another option would be to use javascript to change those classes from 'error' to 'has-error' upon DOMREADY, though your page will look strange until that time. Not really a clean solution.
I use a custom Helper that is tailored to whatever the CSS framework is. In this case 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);
}
}
?>
Then use this instead of the standard Form
helper
echo $this->UI->textBox('email'));
If you introspect FormHelper
, you'll find in this line "ugly" code that do error magic.
Since original authors did not leave any chance to do this by configuration, I'm suggesting you writing own BootstrapFormHelper
, and override input function, by changing that single line.
Here is snippet:
//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;
}
}
}
Since I'm already using custom BootstrapFormHelper
, here is link to full gist.
Just copy file to app\View\Helper
, and add to ALL your Controllers this line:
public $helpers = array(
'Form' => array('className' => 'BootstrapForm')
);
assuming that you've saved gist as BootstrapFormHelper.php
.
SOLUTION I USE:
Everytime you create a new input, check if there are any errors for that field using CakePhp function isFieldError() and simply append "has-error" class to div just like i did below:
Just div setting:
'div' => array('class' => "form-group ".($this->Form->isFieldError('username') ? 'has-error' : '')),
Full code for one field:
<?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'))
)
); ?>
I have never used CakePHP, but I dare to post the answer here. I think the message element should be able to carry multiple classes like any other element does.
So the simple edit is:
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-block has-error'))
I see no reason to copy and paste the css code.