Yesterday I had a very frustrating issue implementing CKEditor (an awesome open-source WYSIWYG editor) in a CakePHP 2.3.2 installation. I thought the issue had something to do with CakePHP … ow boy, was I wrong 🙂
CakePHP has been supporting HTML5 elements for a while now and when you generate form elements by using the FormHelper class it automatically adds the required attribute. What I didn’t know was that this triggers a ‘Please fill out this field’ message in certain browsers (Chrome 26 / Firefox 20, Safari 6 ignores this) when these fields are empty.
When you use CKEditor this raises an issue as CKEditor hides the textarea, so the input field will always be empty and always trigger this internal (browser-dependant) error message. Because my custom validation messages where practically the same as the internal one it was quite frustrating to find out the solutions was so simple!
Adding CKEditor to a CakePHP installation is a walk in the park.
- Download the latest version of CKEditor
- Expand the zip file in cake_installation_path/app/webroot/js
- Add the class HTML attribute to your textarea and set its value to ‘ckeditor‘ which you want to convert into a CKEditor
// using the CakePHP form helper echo $this->Form->textarea('biography', array( 'class' => 'ckeditor' ));
// using the CakePHP form helper (database field needs to be TEXT) echo $this->Form->input('biography', array( 'class' => 'ckeditor' ));
In my case, I added some validation rules to my model. This is also quite easy to do … just fill up the validates array with some rules.
public $validate = array( 'firstname' => array( 'notempty' => array( 'rule' => array('notempty'), ), ), 'lastname' => array( 'notempty' => array( 'rule' => array('notempty'), ), ), 'biography' => array( 'notempty' => array( 'rule' => array('notempty'), ), ), );
Try to load the project right now, you will see that your textarea is replaced by a CKEditor instance. If you try to save your record in Firefox or Chrome you will see the internal error message (Please fill out this field.). Now fill in some dummy data in the CKEditor and try to save again. You will see the internal error message again (try it in Safari and the form will be POSTED as expected). This is logical as the original textarea has been hidden by the CKEditor, but the required attributes block the POST of the form (check the browser source).
<div class="input textarea required"> <label for="PersonBiography">Biography</label> <textarea id="PersonBiography" class="ckeditor" required="required" rows="6" cols="30" name="data[Person][biography]" style="visibility: hidden; display: none;"></textarea> <div id="cke_PersonBiography" class="cke_1 cke cke_reset cke_chrome cke_editor_PersonBiography cke_ltr cke_browser_gecko" lang="en" aria-labelledby="cke_PersonBiography_arialbl" role="application" dir="ltr"> </div>
You can easily fix this by setting the required field to false on your input element.
echo $this->Form->input('biography', array( 'required' => false, 'class' => 'ckeditor' ));
Once you did this, you can try to save your record again. Now you will get the desired result. As you will see the fields will still be required (your label before your input field will be bold and you’ll see a red asteriks). You can control this by setting the allowEmpty and/or required fields on your validation array.
The allowEmpty key means that the field should not be empty. Set this to true if you want the label to appear in a regular font (not bold).
The required key means that the field name needs to be around in your request.
I’ve added the sample code on Github. So you can download it right here!