﻿// Timothy Alford
// 25/1/2011
// Convention validation system for client validation
// inputs can use validation by being marked with the validation class name
// the error messages are determined by the combination of the validation class
// name and the inputs id
// Validation can be activated and deactivated on selectors when validation rules
// only apply in certain conditions

// Example:
// <input type="text" id="FirstName" class="required" />
// <div id="FirstName_required">You must provide a first name.</div>

// Validation class
function Validation() {
    var validationProcesses = new Array();
    var inactiveIds = new Array();

    this.ErrorIdFormat = "[InputId]-[ValidationClass]";

    // Add custom validators 
    this.AddValidator = function (classname, validationMethod, noChangeValidation) {
        validationProcesses.push(new ValiationProcess(classname, validationMethod, this.ErrorIdFormat, noChangeValidation, inactiveIds));
    }

    // Add regular expression validator, empty values are considered valid
    this.AddRegularExpressionValidator = function (classname, regularExpression, noChangeValidation) {
        this.AddValidator(classname, function (input) {
            var isValid = true;
            if ($(input).val() != "") {
                if (regularExpression.test($(input).val()) == false) {
                    isValid = false;
                }
            }
            return isValid;
        }, noChangeValidation);
    }

    // Deactivate an ID
    this.DeactivateValidation = function (selector) {
        var errorFormat = this.ErrorIdFormat;
        $(selector + "," + selector + " input").each(function () {
            var id = this.id;
            inactiveIds.push(id);
            var classes = $(this).attr("class").split(" ");
            for (var i = 0; i < classes.length; i++) {
                var errorId = errorFormat.replace("[InputId]", id).replace("[ValidationClass]", classes[i]);
                $("#" + errorId).hide();
            }
        });
    }

    // Activate an ID
    this.ActivateValidation = function (selector) {
        $(selector + "," + selector + " input").each(function () {
            var id = this.id;
            inactiveIds.pop(id);
        });
    }

    // Check if an ID is active
    this.IsIdActive = function (id) {
        var isActive = true;
        if (inactiveIds != null) {
            for (var j = 0; j < inactiveIds.length; j++) {
                if (inactiveIds[j] == id) {
                    isActive = false;
                    break;
                }
            }
        }
        return isActive;
    }

    // Validate form
    this.ValidateForm = function (outerSelector, summaryId) {
        if (outerSelector == undefined) {
            outerSelector = "";
        }

        var classThis = this;

        var isValid = true;
        var formatTemplate = this.ErrorIdFormat;
        if (summaryId != undefined) {
            $("#" + summaryId).html("");
        }
        for (var i = 0; i < validationProcesses.length; i++) {
            $(outerSelector + "." + validationProcesses[i].Classname + "," + outerSelector + " ." + validationProcesses[i].Classname).each(function () {
                var isActive = classThis.IsIdActive(this.id + "");

                if (this.id == null || this.id == "" || !isActive) {
                    // control doesn't have an id
                }
                else {
                    var errorID = this.id + validationProcesses[i].Classname;
                    if (formatTemplate != "") {
                        errorID = formatTemplate.replace("[InputId]", this.id).replace("[ValidationClass]", validationProcesses[i].Classname);
                    }
                    $("#" + errorID).hide();
                    $("." + errorID).hide();
                    if (!validationProcesses[i].ValidationMethod(this)) {
                        $("#" + errorID).show();
                        $("." + errorID).show();
                        if (summaryId != undefined) {
                            switch ($("#" + summaryId).get(0).tagName.toLowerCase()) {
                                case "div":
                                    $("#" + summaryId).append("<div class=\"" + errorID + "\">" + $("#" + errorID).html() + "</div>");
                                    break;
                                case "ul":
                                    $("#" + summaryId).append("<li class=\"" + errorID + "\">" + $("#" + errorID).html() + "</li>");
                                    break;
                                case "span":
                                    $("#" + summaryId).append("<span class=\"" + errorID + "\">" + $("#" + errorID).html() + "</span>");
                                    break;
                            }
                        }
                        isValid = false;
                    }
                }
            });
        }
        return isValid;
    }
}

// Validation process class
function ValiationProcess(classname, validationMethod, errorIdTemplate, noChangeValidation, inactiveIds) {
    this.NoChangeValidation = noChangeValidation;
    this.Classname = classname;
    this.ValidationMethod = validationMethod;
    if (!this.NoChangeValidation) {
        $("." + this.Classname).change(function () {
            var isActive = true;
            if (inactiveIds != null) {
                for (var j = 0; j < inactiveIds.length; j++) {
                    if (inactiveIds[j] == this.id) {
                        isActive = false;
                        break;
                    }
                }
            }
            if (isActive) {
                var errorID = this.id + classname;
                if (errorIdTemplate != "") {
                    errorID = errorIdTemplate.replace("[InputId]", this.id).replace("[ValidationClass]", classname);
                }
                $("#" + errorID).hide();
                if (!validationMethod(this)) {
                    $("#" + errorID).show();
                }
            }
        });
    }
}
