CKEditor and ASP.Net MVC 3 RequiredAttribute

2019-01-17 07:54发布

问题:

I've integrated CKEditor 3 (formerly FCKEditor) into my asp.net MVC (v3 to be specific) application. I have a RequiredAttribute in my model for the field that needs the editor but the client side validation doesn't work correctly with CKEditor. When I try to submit and I've entered data into CKEditor the required validation doesn't see the data. If I try resubmitting again, then it works. I've looked around online and can't find a solution. I am also using Jquery and using the Jquery adapter

http://docs.cksource.com/CKEditor_3.x/Developers_Guide/jQuery_Adapter

回答1:

If someone is looking for a more generic way to do this you can add this javascript :

    $(document).ready(function () {
    if ($('.text-editor')) {
        $('.text-editor').ckeditor();
        $('input[type=submit]').bind('click', function() {
            $('.text-editor').ckeditorGet().updateElement();
        });
    }
    });

And use .text-editor css class on a textarea and it works just fine.

@Html.TextAreaFor(model => model.Description, new { @class = "text-editor" })

I find this solution eazyer than the other one, hope it can helps!



回答2:

It is even simpler if you don't use the jQuery adapter:

$(function () {
    $('input[type="submit"]').click(function () {
        CKEDITOR.instances.Body.updateElement();
    });
});

Where Body is the ID of the textarea.



回答3:

For me this code does the trick, it could probably be optimized a bit but it works:

$('#newsForm').submit(function (event) {
     var editor = $('#Body').ckeditorGet();
     editor.updateElement();
     $(this).validate().form();
});

Because I don't know in which order the eventhandlers for submit runs I make sure to both update the value and refresh the validation result.

EDIT: Updated solution

<script type="text/javascript">
    //<![CDATA[
    $(document).ready(function () {
        $('#Body').ckeditor();
        $('#newsForm').bind('submit', onFirstSubmit);
    });

    function onFirstSubmit(event) {
        var editor = $('#Body').ckeditorGet();
        editor.updateElement();
        $(this).validate().form();
        $(this).unbind('submit', onFirstSubmit).submit();
    }

    //]]>
</script>


回答4:

I couldn't get it fixed with the above solutions, but this worked for me;

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

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

<script type="text/javascript">

    $(function () {

        CKEDITOR.replace("activiteit_details", { toolbar: 'Basic' });
        CKEDITOR.replace("activiteit_verslag", { toolbar: 'Full' });


        // Bind CKeditor fields on submit (To avoid problems with the RequiredAttribute)
        $('input[type=submit]').bind('click', function () {

            var CKactiviteit_details = CKEDITOR.instances.activiteit_details.getData();
            $("#activiteit_details").val(CKactiviteit_details);

            var CKactiviteit_verslag = CKEDITOR.instances.activiteit_verslag.getData();
            $("#activiteit_verslag").val(CKactiviteit_verslag);
        });

    });


</script>


@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>

...

    <div class="editor-label">
        @Html.LabelFor(model => model.activiteit_details)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.activiteit_details)
        @Html.ValidationMessageFor(model => model.activiteit_details)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.activiteit_verslag)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.activiteit_verslag)

        @Html.ValidationMessageFor(model => model.activiteit_verslag)
    </div>

...
        <p>
            <input type="submit" value="Opslaan" />
        </p>
    </fieldset>


回答5:

I also tried to use CKEditor but with no luck. I've been using CLEditor instead (along with the required attribute) and it works fine for me.

Ever thought of trying this instead?



回答6:

Thanks for the answers. Thanks to this post I've found my own solution which suits my case perfectly.

If you don't want to use click/mousedown event, but instead, want to trigger the validation on the right form-submit event you can use the following approach.

It doesn't use neither jQuery-Adapter CKEditor plugin nor click event. And it's possible to apply it to all forms with ckeditor.

$('form').on('submit.ckeditorValidation', function () {
    var $this = $(this);
    var $ckeditor = $this.find('textarea.ckeditor');

    // if no ckeditor for this form then do nothing
    if (!$ckeditor || !$ckeditor.length) {
        return true;
    }

    // update content from CKEditor to TextArea
    var textAreaId = $ckeditor.attr('id');
    CKEDITOR.instances[textAreaId].updateElement();

    // trigger validation and check if the form is valid
    if (!$this.valid()) {
        return false;
    }

    // if form is valid then
    // unsubscribe current event handler to avoid endless recursion
    // and re-trigger form submit
    $(this).off('submit.ckeditorValidation').submit();
    return true;
});


回答7:

i have been through the same issue and i was unable to resolve it because of one more issue that is related to it.

When ckeditor replaces the textarea, it makes it hidden and i found out that the default settings for jquery validator was to ignore the hidden elements with ":hidden" selector.

To resolve the issue, i have to update the hidden selector and update the element value. here is my code that does this in document ready event and is now working

$('#frmid').validate().settings.ignore = "input:hidden";
            $('input[type="submit"]').click(function () {
                $("#txtarea").val(CKEDITOR.instances["txtarea"].getData());
            });