Ckeditor disappears when <textarea> is updated with ajax response

I am using ckeditor with jQuery adapter in ajax script. Ckeditor is bound to a textarea element using jQuery.

Application:

I am developing an eLearning application for a client. Each course has many steps taken from a database table.

The user interface of the application is just a form with the Previous and Next buttons for navigating the course.

The problem is with the administrator, where tutors can create and update steps in each course.

Again, the administration tool is just a form with the previous and next buttons. However, there is a field called StepText that I want to have html, not plain text. Hence the requirement for Rich Text Editor.

Scrolling from step by step with the help of Ajax calls that go to the controller, receive data for the next (or previous) step and enter it on the page. Ajax calls return html created from a partial view.

Problem:

The text box is in this partial view. CKEditor correctly binds on first page load, but not for subsequent ajax responses.

As a result, ckEditor does not appear with all its kindness, and I just get unattractive nudity in textarea.

Any ideas why this is happening?

SETUP (displayed to confirm) (Edited):

The following scenarios are used:

<script type="text/javascript" src="@Url.Content("~/ckeditor/ckeditor.js")"></script> <script type="text/javascript" src="@Url.Content("~/ckeditor/adapters/jquery.js")"></script> 

This allows me to use ckEditor with jQuery as follows:

 $(document).ready(function () { $('#StepText').ckeditor(function () { }, { toolbar: 'Basic' }); }); 

The text area is in the partial .cshtml file, in the div, which acts as the target for the ajax call:

Edited!! to show how an ajax call is made!

 <div id="ajaxEditor"> @using (Ajax.BeginForm(MVC.Admin.StepEditor.Edit(), new AjaxOptions { UpdateTargetId = "ajaxEditor", HttpMethod = "POST" }, new { @name = "EditStepForm", @id = "EditStepForm" })) { <div class="editor-label"> @Html.LabelFor(model => model.StepText) </div> <div class="editor-field"> @Html.TextAreaFor(model => model.StepText, 20, 68, null) @Html.ValidationMessageFor(model => model.StepText) </div> } </div> 

Answer to Chris Maris:

I tried reprogramming ckeditor in OnSuccess to call ajax, but when debugging jQuery in Chrome, I get the following error:

 Uncaught [CKEDITOR.editor] The instance "myTextArea" already exists. 

This is what you expect: the name of the control remains the same, and there was no page refresh.

+4
source share
3 answers

Chris Marisic's challenge:

If Chris Marisic wants to update his comment to an answer, I will give him cookies.

I decided the following:

Ajax Form:

 <div id="ajaxEditor"> @using (Ajax.BeginForm(MVC.Admin.StepEditor.Edit(), new AjaxOptions { UpdateTargetId = "ajaxEditor", HttpMethod = "POST", OnComplete="ReBindCKEditor" }, new { @name = "EditStepForm", @id = "EditStepForm" })) { <div class="editor-label"> @Html.LabelFor(model => model.StepText) </div> <div class="editor-field"> @Html.TextAreaFor(model => model.StepText, 20, 68, null) @Html.ValidationMessageFor(model => model.StepText) </div> } </div> 

JavaScript:

As the error returns (see the answer to the question by Chris Marisich) it says that the CKEDITOR instance already exists, I need to get rid of it. So:

 function BindCKEditor() { var elem = $('#StepText'); elem.ckeditor(function () {}, { toolbar: [ ['Source'], ['Preview'], ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Scayt'], ['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'], ['Image', 'Table', 'HorizontalRule'], ['Styles', 'Format'], ['Bold', 'Italic', 'Strike'], ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'], ['Link', 'Unlink', 'Anchor'] ] }); } 

BindCKEditor () just does what it says on a can. He customizes the editor and applies it.

Now when I overwrite the text area with ajax response, I need to delete this instance and recreate it. So:

 function ReBindCKEditor() { delete CKEDITOR.instances['StepText']; BindCKEditor(); } 

Note that I am using ReBindCKEditor () in OnComplete for Ajax Form. I use oncomplete, not onsuccess, because I want it to rebuild regardless of success or another ajax call.

SUCCESS:

I can not recommend ckeditor highly enough. I thought it would be a nightmare to solve, but as soon as I sat down and put aside such thoughts, I found that there was very concise documentation and good user forums.

I looked through many other Rich Text Editors and none of them were so good or supported. Yahoo looked good, but was a nightmare and poor documentation unless you are a javascript expert that I don't know.

I almost went with lwrte, it looked good, but there was no support.

I looked at another, which remains unnamed.

But ckEditor really impressed me. Now I can roll it where I want, without fear or trepidation.

Note:

I do not work for CKEditor and have no connection with them. This is real enthusiasm. Yes, such a thing exists.

+2
source

this worked best for me using the jquery ckeditor adapter. I just call it when I load some ajax using the ckeditor text box.

 function initCKEditor() { $('.wysiwyg').ckeditor(function(e){ delete CKEDITOR.instances[$(e).attr('name')]; },{ toolbar: [ ['Bold','Italic','Underline','Strike','-','NumberedList','BulletedList','-','Paste','PasteFromWord','-','Outdent','Indent','-','Link','-','Maximize','-','Source'] ], skin: 'office2003' } ); 

}

+1
source

I had this problem too, but the Senario was a little different, I used ckeditor in Ajax.BeginForm, but my form (partial view) appears in the jquery ui dialog, the first answer gave me a great idea to fix this. I did the transcoding for ckeditor when the dialogue draws near!

  • I edited this code and I added the required attribute / validation (the field has a required attribute in my model), it works great! look at the magic codes: $('input[type=submit]').bind('click', function () { $('.ckeditor').ckeditorGet().updateElement(); });
  • I also added some configuration codes for ckeditor! starts with CKEDITOR.editorConfig =
  • I have different dialogs appear on the parent page, and the only thing I need to do is add new { @class = "ckeditor" }) to TextAreaFor (partial view) and add this line to the parent page delete CKEDITOR.instances['FieldName'];
  • Bravo ckeditor team

on the parent page, I call the dialog:

 function openDialog() { $('#dialog').dialog('open'); delete CKEDITOR.instances['Ingredient']; CKEDITOR.editorConfig = function (config) { config.uiColor = "#EFEFEF"; config.toolbar = [{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']}]; config.width = 400; config.height = 100; config.autoParagraph = false; config.removePlugins = 'elementspath'; config.resize_enabled = false; config.enterMode = CKEDITOR.ENTER_BR; config.startupFocus = true; }; $('.ckeditor').ckeditor(); $('input[type=submit]').bind('click', function () { $('.ckeditor').ckeditorGet().updateElement(); }); } 

in my partial view with Ajax.BeginForm:

 <div class="editor-field"> @Html.TextAreaFor(model => model.Ingredient, new { @class = "ckeditor" }) @Html.ValidationMessageFor(model => model.Ingredient) </div> 

As you can see, I have NOT used OnCompelete or OnBegin. hope this helps someone!

+1
source

Source: https://habr.com/ru/post/1341855/


All Articles