﻿/*
*   xVal / jquery.validate remote validation adaptor functions 
*   Version: v1.0 beta (7-June-2009)
*   Copyright 2009 by Adrian Grigore
*   http://www.devermind.com
*
*   Tested with jquery 1.3.2, jquery.validate 1.5.2 and xVal 0.8
*
*   Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*/


//xVal / jquery.validate remote rule adaptor functions
//validates this element only
function RemotePropertyValidation(value, element, params) {
    var wrappedElement = $(element);
    if (wrappedElement.rules()["remote"] === undefined) {
        //add optional regEx validator to minimize ajax requests
        if (params.regEx !== null && wrappedElement.rules()["xVal_regex"] === undefined) {
            wrappedElement.rules("add", {
                xVal_regex: [params.regEx],
                messages: {
                    xVal_regex: params.errorMessage
                }
            });
        }
        var remoteRule =
        //add a new remote validation rule
        wrappedElement.rules("add", {
            remote: {
                url: "/RemoteValidation/Property",
                data: {
                    value: new CreateInputValueAccessor(wrappedElement.attr("name")),
                    validator: params.validator
                }
            },
            messages: {
                remote: params.errorMessage
            }
        });

        //validate element again to trigger the new rule(s)
        $("form").validate().element(wrappedElement);

    }
    return true;
}

//validates this element plus some other relevant ones from the same entity
function RemoteEntityValidation(value, element, params) {
    var wrappedElement = $(element);
    if (wrappedElement.rules()["remote"] === undefined) {

        //add optional regEx validator to minimize ajax requests
        if (params.regEx !== null && wrappedElement.rules()["xVal_regex"] === undefined) {
            wrappedElement.rules("add", {
                xVal_regex: [params.regEx],
                messages: {
                    xVal_regex: params.errorMessage
                }
            });
        }

        //build request data for the new remote rule
        var remoteRuleData = {
            validator: params.validator
        };

        //match element name prefix so we can find the other
        //relevant entity properties in the form
        $(element).attr("name").match(/^(.*\.).+$/, "");

        var relevantProperties = params.relevantProperties.split(",");

        for (var i in relevantProperties) {
            var nextProperty = relevantProperties[i].toString();
            if (nextProperty !== "") {
                remoteRuleData[nextProperty] = new CreateInputValueAccessor(RegExp.$1 + nextProperty);
            }
        }

        //create a new remote rule
        var remoteRule = {
            remote: {
                url: "/RemoteValidation/Entity",
                data: remoteRuleData
            },
            messages: {
                remote: params.errorMessage
            }
        };

        //add the new remote validation rule to the element
        wrappedElement.rules("add", remoteRule);

        //validate element again to trigger the new rule(s)
        $("form").validate().element(wrappedElement);
    }
    return true;
}

//Using this function to avoid problems with local variable values embedded into closure 
function CreateInputValueAccessor(inputName) {
    return function() {
        return $("[name=" + inputName + "]").val();
    };
}