CKEditor and jQuery serialize() issue

12,937

Solution 1

As mentioned in the comments on your original post, I'm assuming you're using CKEditor and in your jQuery ready function (or somewhere after your document loaded) you replace a textarea with an editor instance. CKEditor, like most WYSIWYG editors likes to reformat the text that you pass to it, making it valid markup, replacing special characters with HTML entities, wrapping your content in a paragraph, etc. This means although you haven't changed anything, the original and the reformatted content can be different.

The initialisation of the editor instance is delayed and probably occurs after you've serialised your form. Even so, CKEditor is not strongly linked with the (now hidden) textarea that it's been created from, you need to call the editor's updateElement function to flush all changes. It usually does it automatically on form submit, that's why you're getting the reformatted content in your submit handler.

So you just need to make sure you call the updateElement function before you're serialising the first time, for which the best place is after the editor has loaded. Luckily there is an event for that, assuming the following HTML markup:

<form id="myForm">
   <textarea name="test" id="myEditor">My random text</textarea>
</form>

jQuery ready function:

$(function(){
   function SerializeForm(){
      // Make sure we have the reformatted version of the initial content in the textarea
      CKEDITOR.instances.myEditor.updateElement();

      // Save the initial serialization
      form_data.edit_initial = $('#myForm').serialize();
   }

   // You might as well leave it here in case CKEditor fails to load
   form_data.edit_initial = $('#myForm').serialize();

   // Create editor instance    
   CKEDITOR.replace('myEditor');

   // Tap into CKEditor's ready event to serialize the initial form state
   CKEDITOR.instances.myEditor.on("instanceReady", SerializeForm);
});

Solution 2

Thanks! I've had problems long time now with CKEditor textarea. I couldn't get changed value without a submit in cakephp.

But now all works. I had to call updateElement before serialize like this:

CKEDITOR.instances.SurveyBody.updateElement();
var formData = $("#surveyForm").serialize();

Solution 3

The values are URI-encoded because ".serialize()" is intended to be used when preparing HTTP parameters for transmission.

You can gather the values of all the form elements into a big string by just iterating over all the <input> elements (and <select> and <textarea> too, if applicable). Radio buttons get a little tricky but it's still a pretty minor effort.

Solution 4

If you're using several instances of CK Editor at a time, you can use a more generic method before serializing your form:

    for (var i in CKEDITOR.instances) {
        CKEDITOR.instances[i].updateElement();
    };
    var data = $('#my-form').serialize();
Share:
12,937

Related videos on Youtube

Alex
Author by

Alex

I'm a front-end &amp; javascript developer in London.

Updated on January 04, 2020

Comments

  • Alex
    Alex over 4 years

    I'm having trouble with the jQuery serialize() function.

    In context, I'm opening a form and checking for changes made to it, so when the form loads, I serialze the data and assign it to a global variable:

    form_data.edit_initial = $('#edit-job-form').serialize();
    

    That works fine.

    Then when I come to click a button to leave the form, it performs this check:

    var start = form_data.edit_initial;
    var end = $('#edit-job-form').serialize();
    
    if (start == end) 
    { 
        // Do button action 
    }
    else
    { 
        // Open confirm dialogue 
    }
    

    ANYWAY. Both serialize() functions work, but the second one has converted apostrophes etc into a series of numbers and percentage symbols (Which i can safely assume is some code for apostrophe).

    Any ideas why? It means even when no changes are made, the dialogue opens and moans that the form's been changed without saving.

    Help!

    Here's some sample data.

    I am using a CKEditor instance.

    Part of the first result:

    &edit_time_digital=60&edit_desc=%3Cp%3E%0D%0A%09They'd+like+the+share+their+site+incase+people+want+to+see+their+entire+collection+of+furnature.%3C%2Fp%3E%0D%0A%3Cp%3E%0D%0A%09The+site+needs+the+following%3A%3C%2Fp%3E%0D%0A%3Cul%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Home+page%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Standard+pages%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Galleries+(By+category)%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Contact+page%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09News+listings%3C%2Fli%3E%0D%0A%3C%2Ful%3E%0D%0A%3Cp%3E%0D%0A%09It+should+be+a+very+simple+generator+build.%3C%2Fp%3E%0D%0A&edit_status=active` 
    

    and the second:

    &edit_time_digital=60&edit_desc=%3Cp%3E%0D%0A%09They%26%2339%3Bd+like+the+share+their+site+incase+people+want+to+see+their+entire+collection+of+furnature.%3C%2Fp%3E%0D%0A%3Cp%3E%0D%0A%09The+site+needs+the+following%3A%3C%2Fp%3E%0D%0A%3Cul%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Home+page%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Standard+pages%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Galleries+(By+category)%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09Contact+page%3C%2Fli%3E%0D%0A%09%3Cli%3E%0D%0A%09%09News+listings%3C%2Fli%3E%0D%0A%3C%2Ful%3E%0D%0A%3Cp%3E%0D%0A%09It+should+be+a+very+simple+generator+build.%3C%2Fp%3E%0D%0A&edit_status=active
    
  • Alex
    Alex about 13 years
    My issue there is that if I change a field, name for example, from Alex to Mark and then back to Alex, with your way it would think it's changed but really the data is the same, it's a compromise I might have to make.
  • Alex
    Alex about 13 years
    Any idea why they're different though?
  • Pointy
    Pointy about 13 years
    You're absolutely certain that calling ".serialize()" twice on the same form, with the same field values, produces different results()? That seems pretty far-fetched.
  • Alex
    Alex about 13 years
    check the sample data in the question, an apostrophe on one is replaced by the html code (or whatever encoding it is) for it on the other
  • kapa
    kapa about 13 years
    Sounds like acceptable behaviour to me. Add and then delete a space in any text editor (at least the ones I use), they will say that it was changed.
  • SivaRajini
    SivaRajini about 10 years
    i tried this code.but it throws some ajax error ("500,internal server error")
  • DarthJDG
    DarthJDG about 10 years
    @SivaRajini: The above code is entirely client-side JavaScript, it could only cause JS errors. Error 500 is probably caused by an error in your server-side program.
  • SivaRajini
    SivaRajini about 10 years
    Yes you are right!!!i got it some validation problem in server side!!! Thank you very much for your prompt response
  • Timsta
    Timsta over 5 years
    8 years later still very usefull and true..you see quite not much progress on CK Editor in such ajax issues...