<#--
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
-->
<#--
START SNIPPET: supported-validators
Only the following validators are supported:
* required validator
* requiredstring validator
* stringlength validator
* regex validator
* email validator
* url validator
* int validator
* double validator
END SNIPPET: supported-validators
-->
<#if ((parameters.validate!false == true) && (parameters.performValidation!false == true))>
<script type="text/javascript" <#include "/${parameters.templateDir}/simple/nonce.ftl" /> >
    function validateForm_${parameters.escapedId}() {
        <#--
            In case of multiselect fields return only the first value.
        -->
        var getFieldValue = function(field) {
            var type = field.type ? field.type : field[0].type;
            if (type === 'select-one' || type === 'select-multiple') {
                return (field.selectedIndex === -1 ? "" : field.options[field.selectedIndex].value);
            } else if (type === 'checkbox' || type === 'radio') {
                if (!field.length) {
                    field = [field];
                }
                for (var i = 0; i < field.length; i++) {
                    if (field[i].checked) {
                        return field[i].value;
                    }
                }
                return "";
            }
            return field.value;
        }
        form = document.getElementById("${parameters.id?js_string}");
        clearErrorMessages(form);
        clearErrorLabels(form);

        var errors = false;
        var continueValidation = true;
    <#list parameters.tagNames as tagName>
        <#list tag.getValidators("${tagName}") as aValidator>
        // field name: ${aValidator.fieldName?js_string}
        // validator name: ${aValidator.validatorType}
        if (form.elements['${aValidator.fieldName?js_string}']) {
            field = form.elements['${aValidator.fieldName?js_string}'];
            <#if aValidator.validatorType = "field-visitor">
                <#assign validator = aValidator.fieldValidator >
                //visitor validator switched to: ${validator.validatorType}
            <#else>
                <#assign validator = aValidator >
            </#if>

            var error = "${validator.getMessage(action)?js_string}";
            var fieldValue = getFieldValue(field);
            
            <#if validator.validatorType = "required">
            if (fieldValue === "") {
                addError(field, error);
                errors = true;
                <#if validator.shortCircuit>continueValidation = false;</#if>
            }
            <#elseif validator.validatorType = "requiredstring">
            if (continueValidation && fieldValue !== null && (fieldValue === "" || fieldValue.replace(/^\s+|\s+$/g,"").length === 0)) {
                addError(field, error);
                errors = true;
                <#if validator.shortCircuit>continueValidation = false;</#if>
            }
            <#elseif validator.validatorType = "stringlength">
            if (continueValidation && fieldValue !== null) {
                var value = fieldValue;
                <#if validator.trim>
                    //trim field value
                    while (value.substring(0,1) === ' ')
                        value = value.substring(1, value.length);
                    while (value.substring(value.length-1, value.length) === ' ')
                        value = value.substring(0, value.length-1);
                </#if>
                if ((${validator.minLength?c} > -1 && value.length < ${validator.minLength?c}) ||
                    (${validator.maxLength?c} > -1 && value.length > ${validator.maxLength?c})) {
                    addError(field, error);
                    errors = true;
                    <#if validator.shortCircuit>continueValidation = false;</#if>
                }
            }
            <#elseif validator.validatorType = "regex">
            if (continueValidation && fieldValue !== null && !fieldValue.match("${validator.regex?js_string}")) {
                addError(field, error);
                errors = true;
                <#if validator.shortCircuit>continueValidation = false;</#if>
            }
            <#elseif validator.validatorType = "email" || validator.validatorType = "creditcard">
            if (continueValidation && fieldValue !== null && fieldValue.length > 0 && fieldValue.match(/${validator.regex}/i) === null) {
                addError(field, error);
                errors = true;
                <#if validator.shortCircuit>continueValidation = false;</#if>
            }
            <#elseif validator.validatorType = "url">
            if (continueValidation && fieldValue !== null && fieldValue.length > 0 && fieldValue.match(/${validator.urlRegex}/i) === null) {
                addError(field, error);
                errors = true;
                <#if validator.shortCircuit>continueValidation = false;</#if>
            }
            <#elseif validator.validatorType = "int" || validator.validatorType = "short" || validator.validatorType = "long">
            if (continueValidation && fieldValue !== null) {
                if (<#if validator.min??>parseInt(fieldValue) <
                     ${validator.min?c}<#else>false</#if> ||
                        <#if validator.max??>parseInt(fieldValue) >
                           ${validator.max?c}<#else>false</#if>) {
                    addError(field, error);
                    errors = true;
                    <#if validator.shortCircuit>continueValidation = false;</#if>
                }
            }
            <#elseif validator.validatorType = "double">
            if (continueValidation && fieldValue !== null) {
                var value = parseFloat(fieldValue);
                if (<#if validator.minInclusive??>value < ${validator.minInclusive?c}<#else>false</#if> ||
                        <#if validator.maxInclusive??>value > ${validator.maxInclusive?c}<#else>false</#if> ||
                        <#if validator.minExclusive??>value <= ${validator.minExclusive?c}<#else>false</#if> ||
                        <#if validator.maxExclusive??>value >= ${validator.maxExclusive?c}<#else>false</#if>) {
                    addError(field, error);
                    errors = true;
                }
            }
            </#if>
        }
        </#list>
    </#list>

        return !errors;
    }
</script>
</#if>