CKEditor widget in a CActiveForm

I would like to use the CKEditor widget in forms for textareas. I’m using Yii 1.1.2 and have installed the NHCKEditor extension and can use it in my CForm configurations. This works just fine.

When I change the CForm to a CActiveForm, it doesn’t work. The content of the CKEditor textarea is not part on the ajax-submit. If the CKEditor widget is used for a required field, it returns the error notification that the field cannot be empty. It actually works when I submit it again after getting that error notification, so I guess this is a client-side javascript issue.

I’m a complete noob when it comes to javascript so I hope somebody is able and willing to help me out on this issue. How could I fix this?

Thanks!

You need to ensure you have coded it like this:


'model' => $model,

'attribute' => 'your_attribute_name',

If there is still a problem can you post your code.

Well, here’s the different versions I’ve tested:

[size="3"]The basic code[/size]

The form (e.g. ‘application.forms.challenge.userForm’):


<?php return array(

    'title'=>yii::t('main','Please provide the challenge description'),


    'attributes' =>array(

        'enctype' => 'multipart/form-data',

    ),


    'elements'=>array(

        'title'=>array(

            'type'=>'text',

            'size'=>60,

        ),

        'client'=>array(

            'type'=>'text',

            'size'=>60,

        ),

        'content'=>array(

            'type'=>'textarea',

        ),

        'avatarFile'=>array(

            'type'=>'file',

        ),

    ),


    'buttons'=>array(

        'submit'=>array(

            'type'=>'submit',

            'label'=>yii::t('core','Submit'),

        ),

        CHtml::link(yii::t('core','Cancel'),yii::app()->homeUrl),

    ),

);

The controller action:


<?php class CreateAction extends CAction

{

    public function run()

    {

        /**

         * @var string the default layout for the view.

         */

        $this->controller->layout='column1';


        $model = new Challenge;

        $form = new CForm('application.forms.challenge.userForm', $model);


        // Uncomment the following line if AJAX validation is needed

        // $this->controller->performAjaxValidation($model);


        if(isset($_POST['Challenge']))

        {

            $model->setScenario('create');

            $model->attributes=$_POST['Challenge'];


            // Set status

            $model->status=Challenge::STATUS_PROPOSED;

            // Set user

            $model->user_id = Yii::app()->user->id;

            

            if($model->save())

            {

                $this->controller->redirect(Yii::app()->homeUrl);

            }

        }

        else

        {

            $this->controller->render('create',array('form'=>$form));

        }

    }

}

ChallengeController’s performAjaxValidation function (used by the action):




    public function performAjaxValidation($model)

    {

        if(isset($_POST['ajax']) && $_POST['ajax']==='challenge-form')

        {

            echo CActiveForm::validate($model);

            Yii::app()->end();

        }

    }

[size="3"]Attempt 1: regular CForm - this works[/size]

The form: the basic form as given at the beginning of this post.

The controller action: the basic action as given at the beginning of this post.

[size="3"]Attempt 2: CForm with CKEditor - this works[/size]

The form: as given at the beginning of this post, but with the CKEditor widget as the ‘content’ field element:




        'content'=>array(

            'type'=>'application.extensions.NHCKEditor.CKEditorWidget',

            'editorOptions' => array(

                'removePlugins' => 'elementspath,save,font',

                'toolbarCanCollapse'=>'false',

                'bodyClass'=>'formWidget',

                'resize_maxWidth'=>'600px',

                'toolbar' => array(

                    array('Bold','Italic','Underline','Strike','-','NumberedList','BulletedList','-','Outdent','Indent','Blockquote','-','Link','Unlink','-','Table','SpecialChar','-','Cut','Copy','Paste','-','Undo','Redo','-','Maximize',),

                ),

                'format_p' => array(

                    'element' => 'p',

                    'attributes' > null,

                ),

                'ignoreEmptyParagraph' => true,

                'font_style' => array(

                    'element' => null,

                ),

            ),

            'htmlOptions' => array('class'=>'formWidget'),

        ),



The controller action: same as given at the beginning of this post.

[size="3"]Attempt 3: regular CActiveForm - this works[/size]

The form: as given at the beginning of this post, but with addition of the ‘activeForm’ definition:




    'activeForm' => array(

        'class' => 'CActiveForm',

        'enableAjaxValidation' => true,

        'id' => 'challenge-form',

        'clientOptions'=>array(

            'validateOnSubmit'=>true,

            'validateOnChange'=>false,

            'validateOnType'=>false,

        ),

    ),

The controller action: as given at the beginning of this post, but with this line enabled:




        // Uncomment the following line if AJAX validation is needed

        $this->controller->performAjaxValidation($model);



[size="3"]Attempt 4: CActiveForm with CKEditor - this does not work![/size]

The form: as given at the beginning of this post, but with addition of the ‘activeForm’ definition and with the CKEditor widget as the ‘content’ field element. This results in the following form:


<?php return array(

    'title'=>yii::t('main','Please provide the challenge description'),


    'attributes' =>array(

        'enctype' => 'multipart/form-data',

    ),


    'activeForm' => array(

        'class' => 'CActiveForm',

        'enableAjaxValidation' => true,

        'id' => 'challenge-form',

        'clientOptions'=>array(

            'validateOnSubmit'=>true,

            'validateOnChange'=>false,

            'validateOnType'=>false,

        ),

    ),


    'elements'=>array(

        'title'=>array(

            'type'=>'text',

            'size'=>60,

        ),

        'client'=>array(

            'type'=>'text',

            'size'=>60,

        ),

        'content'=>array(

            'type'=>'application.extensions.NHCKEditor.CKEditorWidget',

            'editorOptions' => array(

                'removePlugins' => 'elementspath,save,font',

                'toolbarCanCollapse'=>'false',

                'bodyClass'=>'formWidget',

                'resize_maxWidth'=>'600px',

                'toolbar' => array(

                    array('Bold','Italic','Underline','Strike','-','NumberedList','BulletedList','-','Outdent','Indent','Blockquote','-','Link','Unlink','-','Table','SpecialChar','-','Cut','Copy','Paste','-','Undo','Redo','-','Maximize',),

                ),

                'format_p' => array(

                    'element' => 'p',

                    'attributes' > null,

                ),

                'ignoreEmptyParagraph' => true,

                'font_style' => array(

                    'element' => null,

                ),

            ),

            'htmlOptions' => array('class'=>'formWidget'),

        ),

        'avatarFile'=>array(

            'type'=>'file',

        ),

    ),


    'buttons'=>array(

        'submit'=>array(

            'type'=>'submit',

            'label'=>yii::t('core','Submit'),

        ),

        CHtml::link(yii::t('core','Cancel'),yii::app()->homeUrl),

    ),

);

The controller action: as given at the beginning of this post, but with this line enabled:




        // Uncomment the following line if AJAX validation is needed

        $this->controller->performAjaxValidation($model);



It seems that even when I enter some text in the CKEditor decorated ‘content’ textarea field it is empty on the first submit, thus creating a validation error. If I then submit the form again it is accepted, e.g. the text now is part of the posted content.

Seems logical to me that this is a conflict between JS scripts. Both the client-side validation by CActiveForm and CKEditor are JS-based. I’m not skilled at javascript though, so I’m kind of stuck here…

Any suggestions?

bump

There is the same problem with tinyMCE editor. And I don’t know why :unsure:

Looks like adding ‘onclick’=>‘tinyMCE.triggerSave()’ to submit button solves the problem in the case of tinyMCE. As I understand, the editor saves it’s contents to textarea only onsubmit event, but Yii uses some event which happens earlier to perform ajax request.

I didn’t work with CKEditor, so I don’t know if it has a triggerSave()'s like function.

Nice!

Google, and the CKEditor forum, was my friend today… the solution for CKEditor is to add the following onclick code to submit button:




'submit'=>array(

            'type'=>'submit',

            'label'=>yii::t('core','Submit'),

            'onclick'=>'CKEDITOR.instances.TEXTAREA_ID.updateElement()',

        ),



Replace TEXTAREA_ID by the id of the textarea that you’ve used CKEditor on. It’s usually in the Model_field format. In my case (see post #3) it is this:




            'onclick'=>'CKEDITOR.instances.Challenge_content.updateElement()',



I guess if you have multiple CKEditor instances in one form you have to copy this multiple times like this:




            'onclick'=>'CKEDITOR.instances.TEXTAREA1_ID.updateElement();CKEDITOR.instances.TEXTAREA2_ID.updateElement();CKEDITOR.instances.TEXTAREA3_ID.updateElement()',



If anybody has a version that doesn’t require the textarea ID’s (e.g. call all CKEditor instances at once) I’d be very interested! More generic code means less risk of bugs!

I have the same problem too!

i try called ckeditor with class name since its not reuire id, but doesnt work too.

Load ckeditor in multiple form post #7

any advice welcome.

I see you’re manually loading CKEditor using some Javascript code. Consider using the NHCKEditor extension so you can call a Yii widget. Seems to me like a cleaner way to do it.

Also I noticed ‘value’=>’" which is a single quote and a double quote. That doesn’t work. Probably the reason why you’re having this issue.

To be honest your code looks like a mess. I recommend you use


 'value' => 'your code here',

this way you don’t have to put a slash in front of every double quote (") inside the HTML code you’re trying to parse. You can call variables by interrupting the quotes, e.g. like this:


 'value' => 'your' . $code . 'here',

which you didn’t do in the form, textarea and replace line, but did do in the SetupCKEditor line. Sort that stuff out and it will probably work just fine.

Ok, thanks for your advice toMeloos.

i will try this snippet from you.




        'content'=>array(

            'type'=>'application.extensions.NHCKEditor.CKEditorWidget',

            'editorOptions' => array(

                'removePlugins' => 'elementspath,save,font',

                'toolbarCanCollapse'=>'false',

                'bodyClass'=>'formWidget',

                'resize_maxWidth'=>'600px',

                'toolbar' => array(

                    array('Bold','Italic','Underline','Strike','-','NumberedList','BulletedList','-','Outdent','Indent','Blockquote','-','Link','Unlink','-','Table','SpecialChar','-','Cut','Copy','Paste','-','Undo','Redo','-','Maximize',),

                ),

                'format_p' => array(

                    'element' => 'p',

                    'attributes' > null,

                ),

                'ignoreEmptyParagraph' => true,

                'font_style' => array(

                    'element' => null,

                ),

            ),

            'htmlOptions' => array('class'=>'formWidget'),

        ),



probbably, the error come when i click page two or try ajax search function.

is there any method to set this behavior (after ajax call)?

i try renderpartial but not work to.




$this->renderPartial('_search',array('model'=>$model,),false,true);



btw, i will try your versions, i hope it works well. :rolleyes:

Hi everyone,

I had the problem to put a (dynamic) initial value from a model into the content field.

For example like it is in a field if you click "update view".

I found out that this can be achieved like this:

[font=&quot;Courier New&quot;][color=&quot;#FF0000&quot;]&#036;defaultvalue = &#036;model-&gt;content_field


    


       &quot;defaultValue&quot;=&gt;&#036;defaultvalue,     # Optional[/code][/font][/color]



	$defaultvalue = $model->content_field


		$this->widget('ext.ckeditor.CKEditorWidget',array(

		

		"model"=>$model,                 # Data-Model

		"attribute"=>"content_field",          # Attribute in the Data-Model

		"defaultValue"=>$defaultvalue,     # Optional

HTH ;)

I already use this extension, and it work very well… thanks to everyone… this is my steps while installing and managing this extension

  1. Download CKEditor.zip

  2. Extract and release it under protected/extensions

  3. Paste following code in view/issue/_form.php


<div class="row">

            <?php echo $form->labelEx($model,'content'); ?> 

            <?php //echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50));

                    $this->widget('application.extensions.editor.CKkceditor',array(

                                "model"=>$model,                # Data-Model

                                "attribute"=>'content',         # Attribute in the Data-Model

                                "height"=>'400px',

                                "width"=>'100%',

                                "filespath"=>(!$model->isNewRecord)?Yii::app()->basePath."/../media/paquetes/".$model->idpaquete."/":"",

                                "filesurl"=>(!$model->isNewRecord)?Yii::app()->baseUrl."/media/paquetes/".$model->idpaquete."/":"",

                                )

                            ); 

                ?>

            <?php echo $form->error($model,'content'); ?>

      </div> 



  1. Make sure that our path and the file name is correct

$this->widget('application.extensions.ckeditor.CKEditor',array(

....

....

....

  1. Modify code in CKEditor.php

72:  private $skin='kama'; 

=> public $skin='kama';

90: if(isset($this->allowedLanguages[$language])) 

=> if(isset($this->allowedLanguages[$this->language]))

Good luck everyone and enjoy our day with Yii… :D

I get the html tags in ckeditor.

And I dnt want to store in db like this.

Is there any solution for this…

I Got like this:

eg:


<p> dfsfsdf testing for<strong> edit</strong></p> <ul> <li> abc <table border="1" cellpadding="1" cellspacing="1" style="width: 200px"> <tbody> <tr> <td> 1</td> <td> 2</td> </tr> <tr> <td> 3</td> <td> 4</td> </tr> <tr> <td> 5</td> <td> 6</td> </tr> </tbody> </table> </li> </ul> 

but i dnt wnat like this… :(

output:

dfsfsdf testing for <-like this

html tags like <p><strong> should not come…

Thanks in advance!!!!

But like what do you want?

html tags like <p><strong> should not come…

THanks!!

If you want to cut off all tags, then you can use a filter rule in a model:




public function rules()

{

    return array(

        array('attribute_name', 'filter', 'filter'=>'strip_tags'),

    );

}



If you want to allow some tags, then you should use php strip_tags function and specify the 2nd paramater (e.g. in beforeValidate() method).

If you want more complex logic (delete styles, css classes etc), then use CHtmlPurifier.

Why are you using a HTML editor then??

If you don’t want to store html, then do use an editor which works in plain text mode, like Markitup! :

http://markitup.jaysalvat.com/home/

There is at least one (two IIRC) extensions for Markitup already.

As you can see from browsing the site, you can get Markitup in markdown, bbcode, textile - even html mode.

Try that. ;)

But, I understand why you’re using it…

You can probably try to convert the HTML to markdown:

http://milianw.de/projects/markdownify/

Here is another interesting alternative:

http://code.google.c…n/wiki/PageDown

A visual Markdown editor… the one [font=arial, sans-serif][size=2]Stack Exchange uses.[/size][/font]

Hello,

There is another problem occured in ckeditor

i.e

in_form.php


<?php 	$this->widget('application.extensions.NHCKEditor.CKEditorWidget', 

			    array(

			        //  [Required] CModel object

				        'model' => $model,

				        'attribute' => 'content',

						//[Optional] Options based on CKEditor API documentation

				       	'editorOptions' => array(

			                'removePlugins' => 'elementspath,save,font',

			                'toolbarCanCollapse'=>'false',

			                'bodyClass'=>'formWidget',

			                'resize_maxWidth'=>'600px',

			                'toolbar' => array(

			                    array('Bold','Italic','Underline','Strike','-','NumberedList','BulletedList','-','Outdent','Indent','Blockquote','-','Link','Unlink','-','Table','SpecialChar','-','Cut','Copy','Paste','-','Undo','Redo','-',),

			                ),

			            ),

				        //  [Optional] htmlOptions based on Yii implementation

				        'htmlOptions' => array('class'=>'text'),

						

					    )

			);?>   

I had writen like this

but when i use table in ckeditor then it does nt get update.means when i click on update button then 1 pop up will open(fancy box) and when i click on save button then another page is opening and it does not get update at the time when i have used table in ckeditor.in bold ,italic,underline all is perfect…

suppose

  1. if i am writing content as <p><strong>hii</strong></p>

and when i click on update button fancy box is opened.and then i click on save button then i got the msg as ur record is updated succesfull and it is redirected to listing page.

  1. if i m writing content as <table border="1" cellpadding="1" cellspacing="1" style="width: 200px"> <tbody> <tr> <td> 1</td> <td> 2</td> </tr> <tr> <td> 3</td> <td> 4</td> </tr> <tr> <td> 5</td> <td> 6</td> </tr> </tbody> </table>

and when i click on update button fancy box is opened and then i click on save button then it is redirected to update/specific<id> url.

but i want to redirect to listing page with updated msg as per point 1