Integrating qTip with MVC3 and jQuery Validation (errorPlacement)

[亡魂溺海] 提交于 2019-11-28 06:59:31

Great solution thanks, I've used this im my application.

...To further add, instead of modifying the jquery.validate.unobtrusive.min.js file directly I used the following to modify the default behaviour of unobtrusive validation.

$(document).ready(function () {

            var settngs = $.data($('form')[0], 'validator').settings;
            settngs.errorPlacement = function(error, inputElement) {
                // Modify error placement here
            };
});

Eagerly Performing ASP.NET MVC 3 Unobtrusive Client Side Validation

Alternate Solution

My first solution worked, but also caused some unexpected behaivior in certain situation. I fixed by including the errorPlacement code on the onError function in the same js file:

function onError(error, inputElement) {  // 'this' is the form element
    var container = $(this).find("[data-valmsg-for='" + inputElement[0].name + "']"),
        replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;

    container.removeClass("field-validation-valid").addClass("field-validation-error");
    error.data("unobtrusiveContainer", container);

    if (replace) {
        container.empty();
        error.removeClass("input-validation-error").appendTo(container);
    }
    else {
        error.hide();
    }

    var element = inputElement;
    // Set positioning based on the elements position in the form
    var elem = $(element),
                        corners = ['left center', 'right center'],
                        flipIt = elem.parents('span.right').length > 0;

    // Check we have a valid error message
    if (!error.is(':empty')) {
        // Apply the tooltip only if it isn't valid
        elem.filter(':not(.valid)').qtip({
            overwrite: false,
            content: error,
            position: {
                my: corners[flipIt ? 0 : 1],
                at: corners[flipIt ? 1 : 0],
                viewport: $(window)
            },
            show: {
                event: false,
                ready: true
            },
            hide: false,
            style: {
                classes: 'ui-tooltip-red' // Make it red... the classic error colour!
            }
        })

        // If we have a tooltip on this element already, just update its content
        .qtip('option', 'content.text', error);
    }

    // If the error is empty, remove the qTip
    else { elem.qtip('destroy'); }
}

And then you can submit a form, checking for validation this way:

$('#frm').submit(function () {
    if (!$(this).valid())
        return false;

    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(),
        beforeSend: function () {
        },
        success: function (result) {
        },
        error: function (result) {
        }
    });
    return false;
});

My solution - can be used in separate .js file and if placed in master page, works for whole site.

$(document).ready(function () {
    //validation - make sure this is included after jquery.validate.unobtrusive.js
    //unobtrusive validate plugin overrides all defaults, so override them again
    $('form').each(function () {
        OverrideUnobtrusiveSettings(this);
    });
    //in case someone calls $.validator.unobtrusive.parse, override it also
    var oldUnobtrusiveParse = $.validator.unobtrusive.parse;
    $.validator.unobtrusive.parse = function (selector) {
        oldUnobtrusiveParse(selector);
        $('form').each(function () {
            OverrideUnobtrusiveSettings(this);
        });
    };
    //replace validation settings function
    function OverrideUnobtrusiveSettings(formElement) {
        var settngs = $.data(formElement, 'validator').settings;
        //standard qTip2 stuff copied from sample
        settngs.errorPlacement = function (error, element) {
            // Set positioning based on the elements position in the form
            var elem = $(element);


            // Check we have a valid error message
            if (!error.is(':empty')) {
                // Apply the tooltip only if it isn't valid
                elem.filter(':not(.valid)').qtip({
                    overwrite: false,
                    content: error,
                    position: {
                        my: 'center left',  // Position my top left...
                        at: 'center right', // at the bottom right of...
                        viewport: $(window)
                    },
                    show: {
                        event: false,
                        ready: true
                    },
                    hide: false,
                    style: {
                        classes: 'qtip-red' // Make it red... the classic error colour!
                    }
                })
                // If we have a tooltip on this element already, just update its content
                .qtip('option', 'content.text', error);
            }

            // If the error is empty, remove the qTip
            else { elem.qtip('destroy'); }
        };

        settngs.success = $.noop;
    }
});

Found the answer... posting for reference.

1) First, locate the script jquery.validate.unobtrusive.js provided by microsoft.

2) Second, on the script locate the function validationInfo(form) and replace the errorPlacement instruction in the options structure with the one provided by qTip, or any of your choice.

3) Same goes for style and other options you wish to change in how validation is handled.

4) Include all necessary files were needed.

Hope this helps someone having a similar problem.

Example Code:

function validationInfo(form) {
    var $form = $(form),
        result = $form.data(data_validation);

    if (!result) {
        result = {
            options: {  // options structure passed to jQuery Validate's validate() method
                //errorClass: "input-validation-error",
                errorClass: "error",
                errorElement: "span",
                //errorPlacement: $.proxy(onError, form),
                errorPlacement: function (onError, form) {
                    var error = onError;
                    var element = form;
                    // Set positioning based on the elements position in the form
                    var elem = $(element),
                        corners = ['left center', 'right center'],
                        flipIt = elem.parents('span.right').length > 0;

                    // Check we have a valid error message
                    if (!error.is(':empty')) {
                        // Apply the tooltip only if it isn't valid
                        elem.filter(':not(.valid)').qtip({
                            overwrite: false,
                            content: error,
                            position: {
                                my: corners[flipIt ? 0 : 1],
                                at: corners[flipIt ? 1 : 0],
                                viewport: $(window)
                            },
                            show: {
                                event: false,
                                ready: true
                            },
                            hide: false,
                            style: {
                                classes: 'ui-tooltip-red' // Make it red... the classic error colour!
                            }
                        })

                        // If we have a tooltip on this element already, just update its content
                        .qtip('option', 'content.text', error);
                    }

                    // If the error is empty, remove the qTip
                    else { elem.qtip('destroy'); }
                },
                invalidHandler: $.proxy(onErrors, form),
                messages: {},
                rules: {},
                success: $.proxy(onSuccess, form)
            },
            attachValidation: function () {
                $form.validate(this.options);
            },
            validate: function () {  // a validation function that is called by unobtrusive Ajax
                $form.validate();
                return $form.valid();
            }
        };
        $form.data(data_validation, result);
    }

    return result;
}

With Mantisimo & AJC answers (thanks to him), I written the following script, it's OK and it works without any problems but jquery.validate.unobtrusive.js throws an error as the following in each submitting form :

$(document).ready(function () {
    var $forms = $.data($('form')[0], 'validator');
    if ($forms == undefined) return;
    var settngs = $forms.settings;
    settngs.errorPlacement = function (error, inputElement) {
        var element = inputElement;
        var elem = $(element),
            corners = ['left center', 'right center'],
            flipIt = elem.parents('span.right').length > 0;
        if (!error.is(':empty')) {
            elem.filter(':not(.valid)').qtip({
                overwrite: false,
                content: error,
                position: {
                    my: corners[flipIt ? 0 : 1],
                    at: corners[flipIt ? 1 : 0],
                    viewport: $(window)
                },
                show: {
                    event: false,
                    ready: true
                },
                hide: false,
                style: {
                    classes: 'qtip-red',
                }
            })
            .qtip('option', 'content.text', error);
        }
        else { elem.qtip('destroy'); }
    };
});

I've tested with MVC 5 and qtip 2.2.0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!