Integrating FCKeditor with Zend_Form

April 5, 2009 – 1:08 pm 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.

Share this:
  1. 17 Responses to “Integrating FCKeditor with Zend_Form”

  2. Good stuff. Always find your articles informative.

    By Zachary Snow on Apr 5, 2009

  3. Jani,
    I just wrote something very similar to this Friday for an app I’m working on. I used this and HTMLPurifier to filter it out as well. Thanks for the post.

    By Jay M. Keith on Apr 5, 2009

  4. You could also create a MyForm_Form_Element_Fck extending the Zend_Form_Element_Textarea like this:

    class MyForm_Form_Element_Case extends Zend_Form_Element_Textarea
    {

    public $helper = ‘formFck’;

    }

    And then create the corresponding viewHelper:

    class Insmv_View_Helper_FormFck extends Zend_View_Helper_FormTextarea
    {
    public function formFck(/*usal params*/)
    {
    $string = parent::formTextarea(/*usal params*/);
    $string.=’add you JS here’;
    return $string;
    }
    }

    By Cadrach on Apr 6, 2009

  5. I got the fckeditor to work nicely using method 1 (actually this was via some help on another forum).

    However, when I try to apply this decorator class to the form I was using, it just doesn’t work. The same goes when I try to use the MyForm example given here. That doesn’t even render a form in the first place. Maybe I should give my code so you can see what the deal is.

    I based my site on Akra’s tutorial, so the set up of my form, called TextForm, is extrapolated from that:

    setName(‘content’);

    $id = new Zend_Form_Element_Hidden(‘id’);

    $content1 = new Zend_Form_Element_TextArea(‘content1′);
    $content1->setLabel(‘Content1′)
    ->setRequired(true)
    ->addValidator(‘NotEmpty’);

    $content2 = new Zend_Form_Element_TextArea(‘content2′);
    $content2->setLabel(‘Content2′)
    ->setRequired(true)
    ->addValidator(‘NotEmpty’);

    $content3 = new Zend_Form_Element_TextArea(‘content3′);
    $content3->setLabel(‘Content3′)
    ->setRequired(true)
    ->addValidator(‘NotEmpty’);

    $submit = new Zend_Form_Element_Submit(‘submit’);
    $submit->setAttrib(‘id’, ‘submitbutton’);

    $this->addElements(array($id, $content1, $content2, $content3, $submit));
    }
    }

    Then in my IndexController I instantiate the form in the relevant action and apply the decorator class:

    function editAction()
    {
    $form = new TextForm();
    $form->content->addDecorator(new My_Form_Decorators_FckEditor());

    ……

    Now I know I’m getting snagged on something having to do with targeting my form because its giving me a fatal error claiming ‘Call to a member function addDecorator() on a non-object’. As far as I know it uses the ‘name’ of the form/s to target the decorator, but it claims it’s a non-object. Unlike the js itself, it doesn’t refer to the id so those seems irrelevant with the decorator, unless I’m missing something.

    Any suggestions?

    By Benj_em on May 6, 2009

  6. You have a typo ;) None of your form elements is called just “content”, they all have a number after them.

    By Jani Hartikainen on May 7, 2009

  7. Actually I tried applying the decorator to each of them in the controller like:
    $form->content1->addDecorator(new My_Form_Decorators_FckEditor());
    $form->content2->addDecorator(new My_Form_Decorators_FckEditor());
    etc.

    But that still doesn’t apply the decorator. I guess it’s so hard to tell with this because if there’s an error, it simply doesn’t render the Fckeditor.
    I’ll monkey around with it and see what I come up with.

    By Benj_em on May 8, 2009

  8. Maybe you forgot to include the fckeditor script or didn’t output the inlineScript helper in your layout in the end?

    By Jani Hartikainen on May 8, 2009

  9. Actually, the fckeditor js script is being loaded into the header, and I’ve gotten it to work great by putting the javascript directly in the view script. As far as I can tell, the basepath is set correctly. I wish I could test that the script is there somehow with a load.window alert, but even using that doesn’t work. The locally inserted scripts are viewable in the source, but there’s no way of telling if the one appended from the decorator is there.

    By Benj_em on May 11, 2009

  10. by the way, I’m actually calling the decorator in my view script, not the controller, so it looks like this:

    echo $this->form->getElement(‘content1′)->addDecorator(new My_Form_Decorators_FckEditor());
    or
    echo $this->form->content1->addDecorator(new My_Form_Decorators_FckEditor());

    Like I said I can easily use a javascript placed in the view file triggered by window.onload, and it replaces the form element with a fckeditor like a charm, but the script within the decorator is ignored when testing with the local scripts commented out.

    By Benj_em on May 11, 2009

  11. Hi

    I’m trying method 2 with no success. Method 1 works fine but I have many forms with textareas and I would like to use method 2.

    I’m getting a an alert window from fckeditor: Error: The TEXTAREA with id or name set to “text” was not found.

    After closing the alert and inspecting the page source code, the element is there

    What could be the problem here?

    Cheers
    holo

    By holo on Aug 10, 2009

  12. A short article on the free version of CKEditor and Zend Form.

    By Henry on May 24, 2011

  13. That was so helpful, but I also would like to add the include script and enhance the include path

    $this->setBasePath($view->baseUrl().$this->_basePath);
    if(!self::$included){
        $view->headScript()->appendFile($this->_basePath.'fckeditor.js');
        self::$included= 1;
    }

    By Omar Abdallah on Aug 14, 2011

  14. Hi,

    Thanks for this stuff. I am trying to implement fck in zend 1.12.

    I couldn’t find neither CU_Form_Decorator_FckEditor nor FCKeditor on my project folder. Is there any plugin to run.

    I am completely new to zend.

    Thanks in advance.

    By Prabhu on Aug 22, 2014

  15. Hey Prabhu, you need to copy the code for the class from the post. It’s not included with the framework.

    By Jani Hartikainen on Aug 22, 2014

  16. Hey there! Would you mind if I share your blog with my facebook group?
    There’s a lot of people that I think would really enjoy your content.
    Please let me know. Thank you

    By galaxy empire cheats on Sep 16, 2014

  1. 2 Trackback(s)

  2. Apr 5, 2009: Integrating FCKeditor with Zend_Form « Dailytuts.net - Daily tutorial for the people
  3. Apr 6, 2009: Jani Hartikainen’s Blog: Integrating FCKeditor with Zend_Form | Cole Design Studios

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)