Search code examples
jqueryvalidationasp.net-mvc-3qtiperrorplacement

Integrating qTip with MVC3 and jQuery Validation (errorPlacement)


I am working on a proyect with MVC3 and I am trying to integrate qTip2 with jQuery validation in order to show errors as floating tips. The problem I am having is that apparently calling errorPlacement on form validation is not doing anything, guess it has something to do with the way MVC handles it.

Basically, what I want to do is use the integrated validation between MVC3 and jQuery (annotations) but also integrated with qTip to change how the error msg is shown.

I have searched all over and the best I could find was someone suggesting modifying the jquery.validate.unobtrusive.js - onError function, but I checked it out and had no idea how to modify it properly, plus would prefer a solution that did not require me to alter existing scripts.

Thank you for your help.

What I have so far:

My Model:

public class User
{
    [Required]
    public string Id { get; set; }

        [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    public string FirstName { get; set; }

    public string SecondName { get; set; }

    public string LastName { get; set; }
}

My javascript in my view:

$('#Form').validate({
    errorClass: "errormessage",
    errorClass: 'error',
    validClass: 'valid',
    errorPlacement: function (error, element) {
        // 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 (true) {
            // 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'); }
    },
    success: $.noop // Odd workaround for errorPlacement not firing!
})

$('#Form').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;
});

Solution

  • 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;
    });