Sean
Sean

Reputation: 1888

jQuery Validation plugin with CKEditor

I know this question has been asked before and I have read all the previous questions and I still can't get the jQuery validator to properly validate CKEditor fields.

My form is below:

<form id="faq-form">
    <p>
        <label>Title:</label>
        <input type="text" id="faq-title" name="faq-title" class="faq-title" />
    </p>
    <p>
        <label for="question">Question:</label>
        <textarea name="question" id="question"></textarea>
    </p>
    <p>
        <label for="answer">Answer:</label>
        <textarea name="answer" id="answer"></textarea>
    </p>            
    <p>
        <input id="submit-faq" name="submit-faq" type="submit" value="Submit" />
    </p>
</form>

Both textareas are converted to CKEditor fields using:

<script>
CKEDITOR.replace('question', { toolbar : 'forum' });
CKEDITOR.replace('answer', { toolbar : 'forum' });
</script>

When I try to validate, only the title field gets validated. I am not sure what I am doing wrong. Here is my javascript code for validating (the following sits in a jQuery document ready function).

$('#faq-form').submit(function() {
    // Update textareas with ckeditor content
    for (var i in CKEDITOR.instances) {
        CKEDITOR.instances[i].updateElement();
        $.trim($('#' + i).val());
    }

    // Validate the form
    if ( ! $('#faq-form').validate({
        rules: {
            'faq-title': {
                required: true,
                minlength: 5
            },
            answer: {
                required: true,
                minlength: 20
            },
            question: {
                required: true,
                minlength: 20
            }
        }
    }).form()) {
        console.log('Form errors');
        return false;
    }

Once the validation is complete, I will use a $.post method instead of a normal form get or post so I can update my page without reloading. The $.post comes after the validation method but I didn't think it was necessary to show.

Upvotes: 2

Views: 8471

Answers (6)

kavitha Reddy
kavitha Reddy

Reputation: 3333

    <form>
        <textarea class="ckeditor" id="noticeMessage" name="message"></textarea>
    </form>
    <script type="text/javascript" src="ckeditor/ckeditor.js"></script>



    <form>
        <textarea class="ckeditor" id="noticeMessage" name="message"></textarea>
    </form>
    <script type="text/javascript" src="ckeditor/ckeditor.js"></script>
    <script type="text/javascript">
        $("form").submit( function() {
            var messageLength = CKEDITOR.instances['noticeMessage'].getData().replace(/<[^>]*>/gi, '').length;
            if( !messageLength ) {
                alert( 'Please enter a message' );
            }
        }
    </script>

see for full reference
----------------------

http://christierney.com/2012/12/14/ckeditor-4-required-field-validation/

Upvotes: 0

Sean
Sean

Reputation: 1888

I was finally able to get it working. CKEditor hides the textareas when it runs and the jQuery validator ignores hidden elements. In the validate function, this can be changed. So my new code is below:

if ( ! $('#faq-form').validate({
    ignore: "input:hidden:not(input:hidden.required)",
    rules: {
        'faq-title': {
            required: true,
            minlength: 5
        },
        answer: {
            required: true,
            minlength: 20
        },
        question: {
            required: true,
            minlength: 20
        }
    },
    messages: {
        'faq-title': {
            required: "The title field is required"
        },
        answer: {
            required: "The answer field is required"
        },
        question: {
            required: "The question field is required."
        }
    },
    errorElement: "span",
    errorPlacement: function (error, element) {
        error.appendTo(element.prev());
    }
}).form()) {
    console.log('Form errors');
    return false;
}

I also added messages and modified the element and location of the errors when they are displayed. I figured that might be helpful to anyone else who stumbles across this.

Upvotes: 7

kausar ahmed
kausar ahmed

Reputation: 239

Ok lets cut it down, I have spent hours to get the error message of CKEditor in the right place, because every time it showing up on top of the CKEditor or just after the label which is not look nice.

As CKEditor hides the textarea and put its span tag right after the textarea. Please use browser tool to inspect the dom elements, then you can see the textarea is hidden.

I just adjusted the code to get the error message label/span just under the CKEditor.

        $('#messageForm').validate(
          {
              ignore: 'input:hidden:not(input:hidden.required)',
              rules: {
                  msgTitle: {
                      minlength: 2,
                      required: true
                  },
                  msgText: {
                      minlength: 2,
                      required: true
                  }
              },
              errorElement: "span", // can be 'label'
              errorPlacement: function (error, element) {
                  if ($(element).attr('id') == 'msgText') {
                      $('#cke_msgText').after(error);
                  } else {
                      element.after(error);
                  }
              },
              highlight: function (element) {
                  $(element).closest('.form-group').removeClass('text-success').addClass('error');
              },
              success: function (element) {
                  element
                      .closest('.form-group').removeClass('error').addClass('text-success');
              }
          });

Here, 'msgText' is the id of the textarea which is hidden, and cke_msgText id of the ckeditor, you can find the id by inspecting the dom element, perhaps ckeditor takes the id attribute of textarea and prefix 'cke_' with it.

Upvotes: 1

Aline Matos
Aline Matos

Reputation: 497

Best solution I found so far, simple and elegant:

    $('#form1').validate({
        ignore: [],
        rules: {
            corpo : {
                required: function()
                {
                    CKEDITOR.instances.corpo.updateElement();
                }
            }
        }
    })

Font: http://devlog.waltercruz.com/usando-ckeditor-e-jquery-validate-juntos

Upvotes: 0

Sparky
Sparky

Reputation: 98728

Your code:

$('#faq-form').submit(function() {

    // Update textareas with ckeditor content
    for (var i in CKEDITOR.instances) {
        CKEDITOR.instances[i].updateElement();
        $.trim($('#' + i).val());
    }

    if ( ! $('#faq-form').validate({
        rules: {
            'faq-title': {
                required: true,
                minlength: 5
            },
            answer: {
                required: true,
                minlength: 20
            },
            question: {
                required: true,
                minlength: 20
            }
        }
    }).form()) {
        console.log('Form errors');
        return false;
    }
    ....

You should not use .validate() inside a conditional. That's what the .valid() method is for. .validate() is only used for initializing the plugin once on DOM ready with your rules & options. Once initialized, then .valid() can be used inside conditionals to trigger a test and return a boolean.

Also, you should not have .validate() inside of submit handler. The plugin has it's own submitHandler callback function.

Your code should be changed into something like:

$(document).ready(function() {

    $('#faq-form').validate({ // initialize the plugin
        // rules & options,
        rules: {
            'faq-title': {
                required: true,
                minlength: 5
             },
             answer: {
                required: true,
                minlength: 20
             },
             question: {
                required: true,
                minlength: 20
             }
        },
        submitHandler: function (form) {
             // Update textareas with ckeditor content
             for (var i in CKEDITOR.instances) {
                 CKEDITOR.instances[i].updateElement();
                 $.trim($('#' + i).val());
             }
        }
    })

    if ( ! $('#faq-form').valid() ) { // test the form for validity
        console.log('Form errors');
        return false;
    }

});

Upvotes: 0

podperson
podperson

Reputation: 2383

My guess is that CKEditor doesn't play nicely with validation, at least by default. You'd need to remove the editors before validation (CKEditor works by hiding the thing being edited and then inserting an iframe and sticking the editable content in there; when you remove the editor it shuts down the iframe and copies over the content -- at least that's from memory). My guess is that if you inspect the DOM you'll see that the content of the textareas isn't changing.

You may find NicEdit more useful in this context -- see this thread:

https://stackoverflow.com/questions/3914510/wysiwyg-editor-without-iframe

Upvotes: 0

Related Questions