Integrating FCKeditor with Zend_Form

Tags:

How to use FCKeditor, or any other WYSIWYG editor, with Zend_Form? Another relatively common question.

There are many ways you can do this, but let’s look at these two as they are the best in my opinion:

  • Adding some JavaScript to your view script
  • Creating a Zend_Form_Decorator

We’ll be using FCKeditor, but you can apply the techniques shown to others, such as TinyMCE, as well.

Setting up

We’ll look at each method for setting up FCKeditor with Zend_Form. Let’s assume you have some controller with a view script, to which you assign some kind of a simple form class like this one:

class MyForm extends Zend_Form {
  public function init() {
    //We'll just add a simple textarea element to the form
    $this->addElement('textarea', 'content', array(
      'id' => 'txtContent',
      'label' => 'Contents'
    ));
  }
}

Note that we give the form element an ID – you need to give the element an ID for this to work, so don’t forget it!

Method 1: adding JavaScript to the view

This is probably the simplest approach of the two, but isn’t very reusable and always requires you to manually perform this step.

Basically, we’ll echo the form in the view script and we’ll include some JavaScript code that will replace the textarea with an FCKeditor box.

<?php echo $this->form; ?>
 
<script type="text/javascript">
var editor = new FCKeditor('txtContent') ;
editor.BasePath = 'fckeditor/'; //replace this with path to fckeditor's files
editor.ReplaceTextarea() ;
</script>

When the page is loaded, the JavaScript code in the above snippet runs and replaces the textarea with a WYSIWYG editor. Note that for the JavaScript code to work, you need to include FCKeditor’s scripts in the head section of the markup. Also, if you want to place the script-block into the site’s head section, remember to put it inside window.onload or it won’t work.

Method 2: creating a custom decorator

This approach requires a custom decorator class. It is a bit more complex than the first method, but after we have created the decorator, it’s very easy to reuse.

The decorator won’t actually change the markup of the element – instead, we’ll append some JavaScript code to the inlineScript helper.

The benefit of this approach is that the editor will work even if something goes wrong – you’ll just get a simple textbox. If we had used, say the FCKeditor PHP integration library, there would be nothing at all.

class CU_Form_Decorator_FckEditor extends Zend_Form_Decorator_Abstract {
  private $_basePath = 'fckeditor/';
 
  public function setBasePath($path) {
    $this->_basePath = $path;
  }
 
  public function render($content) {
    $view = $this->getElement()->getView();
    $view->inlineScript()->appendScript("
      var editor = new FCKeditor('" . $this->getElement()->getId() . "');
      editor.BasePath = '" . $this->_basePath . "';
      editor.ReplaceTextarea();
    ");
    return $content;
  }
}

Get the source for the class here

As you can see, the decorator is relatively simple. It just appends the JS code needed to inlineScript and then returns the content unmodified. We also have a method for setting the FCKeditor base path, in case it’s different.

Using this decorator is very simple:

//Let's append the decorator to our previously created form class
$form = new MyForm();
//The textarea's name was content so we can access it like this
$form->content->addDecorator(new CU_Form_Decorator_FckEditor());

Now, when we render that form in a view, and then render inlineScript in our layout’s end before closing the body, we’ll get a nice FCKeditor box!

Troubleshooting

If you’re having problems getting the FCKeditor scripts to run, make sure to confirm that they are accessible. Sometimes your .htaccess file’s rewrite rules may be too strict, and stopping access to the script files.

The easiest way to find out if this is the case is by opening the URL to the script in your browser and seeing if you can access it.

Conclusion

Integrating FCKeditor to Zend_Form is a very simple task. We can even make it easy to reuse by creating a custom decorator.