在具有多个部分和未知输入字段的表单上触发验证

时间:2013-10-08 16:01:13

标签: jquery jquery-validate

我正在尝试验证一个复杂的表单,而复杂的表示形式只是一个,但它已分为四个部分,我做了一个简单的向导来显示它们。我正在使用jQuery Validation,但它没有按照我的意愿工作,也有一些疑问。基于this example(第二种形式),我制作了如下代码:

$("#product_create").validate({
    rules: {
        product_name: {
            required: true,
            minlength: 10,
            maxlength: 50
        },
        product_price: {
            required: true,
            number: true,
            minlength: 2
        },
        product_quantity: {
            required: true,
            digits: true,
            minlength: 1
        }
    },
    messages: {
        product_name: {
            required: "El nombre del producto no se puede dejar vacío",
            minlength: "El nombre del producto no puede tener menos de 10 carácteres",
            maxlength: "El nombre del producto no puede tener más de 50 carácteres"
        },
        product_price: {
            required: "Debes introducir un precio",
            number: "El precio debe ser un número decimal o no"
        },
        product_quantity: {
            required: "Debes introducir una cantidad",
            number: "La cantidad debe ser un número"
        }
    }
});

如果我理解为好,那么keyup事件字段应该验证并且它们不是因为错误没有出现。所以关于这个的第一个问题是:为什么它不验证?我的解决方案有什么问题?第二个是我如何验证product_priceproduct_quantity只有在可见的情况下?

现在关于同样的话题,我有另一个疑问,我会动态创建几个字段,是的,我每次都知道他们的ID,在这种情况下我是如何将规则应用于这些字段的?

更新

我找出keyup的问题所在,验证是通过输入名称进行的,而不是输入ID,因为我很难,所以这部分完成了。

第二个问题仍未解决。例如,我可以生成名称为variation[pprice][]的三个字段和苍蝇,但可以是五个或更多或者其他,我如何将这些字段添加到规则和验证部分?我可以只添加variation[pprice][]的规则,无论表单中有多少具有相同名称的元素,它都会验证吗?

还在等待验证字段的部分,只要它们可见

更新2

由于variation[pprice][]是一个项目数组,我可以使用$.each移动它们并分配规则吗?

更新3

根据@Sparky的建议,我将我的代码更改为:

$('#variations_holder input.pprice').each(function() {
    $(this).rules('add', {
        required: true,
        number: true,
        messages: {
            required: "Debes introducir un precio de la variación",
            number: "El precio de la variación debe ser un valor numérico o decimal"
        }
    });
});

但是在Firebug中我收到了这个错误:

  

TypeError:e.validator.methods [o]未定义

这会阻止代码执行脚本,在这种情况下我想念的是什么?

更新4

假设我不能使用多个表单,所以我只有一个表单有很多部分(使用section标签),我处理每个表单之间的移动。我试图以相同的形式调用validate()但是两次,step5的验证在字段通过后无法正常工作。这是我正在使用的代码:

function validateWizard(step){     var is_valid = true;

switch (step) {
    case 1:
        if ($("#selected_category").val() === '' || $("#selected_category").val().length === 0) {
            alert("Debes seleccionar una categoría antes de continuar");
            is_valid = false;
        }
        break;
    case 2:
        $("#product_create").validate({
            rules: {
                "product[name]": {
                    required: true,
                    minlength: 10,
                    maxlength: 50
                },
                "product[price]": {
                    required: true,
                    number: true,
                    minlength: 2
                },
                "product[quantity]": {
                    required: true,
                    digits: true,
                    minlength: 1
                },
                "product[description]": {
                    required: true
                }
            },
            messages: {
                "product[name]": {
                    required: "El nombre del producto no se puede dejar vacío",
                    minlength: "El nombre del producto no puede tener menos de 10 carácteres",
                    maxlength: "El nombre del producto no puede tener más de 50 carácteres"
                },
                "product[price]": {
                    required: "Debes introducir un precio",
                    number: "El precio debe ser un valor numérico o decimal"
                },
                "product[quantity]": {
                    required: "Debes introducir una cantidad",
                    number: "La cantidad debe ser un número"
                },
                "product[description]": {
                    required: "Debes introducir una descripción del producto"
                }
            }
        });

        is_valid = $("#product_create").valid();

        if (is_valid) {
            $('#variations_holder input.pprice').each(function() {
                pprice = $.trim(this.value);
                if (!pprice.length) {
                    $(this).focus();
                    $(this).addClass('error');
                    is_valid = false;
                } else if (!/^[1-9]\d*(\.\d+)?$/.test(pprice)) {
                    $(this).addClass('error');
                    is_valid = false;
                }
            });

            // Validate quantity in variation
            $('#variations_holder input.pqty').each(function() {
                pqty = $.trim(this.value);
                if (!pqty.length) {
                    $(this).focus();
                    $(this).addClass('error');
                    is_valid = false;
                } else if (!/^[1-9]\d*$/.test(pqty)) {
                    $(this).addClass('error');
                    is_valid = false;
                }
            });
        }
        break;
    case 3:
        break;
    case 5:
        $("#product_create").validate({
            rules: {
                "stock[sku]": {
                    required: true,
                    minlength: 10,
                    maxlength: 20
                },
                "stock[width]": {
                    required: true,
                    number: true,
                    minlength: 1
                },
                "stock[height]": {
                    required: true,
                    number: true,
                    minlength: 1
                },
                "stock[length]": {
                    required: true
                },
                "stock[weight]": {
                    required: true,
                    number: true,
                    minlength: 1
                },
                "stock[description]": {
                    required: true
                },
                "warranty[description]": {
                    required: true
                },
                "warranty[valid_time]": {
                    required: true,
                    digits: true
                }
            },
            messages: {
                "stock[sku]": {
                    required: "El SKU no se puede dejar vacío",
                    minlength: "El SKU no puede tener menos de 10 carácteres",
                    maxlength: "El SKU no puede tener más de 50 carácteres"
                },
                "stock[width]": {
                    required: "Debes introducir un ancho",
                    number: "El ancho debe ser un número"
                },
                "stock[height]": {
                    required: "Debes introducir una altura",
                    number: "La altura debe ser un número"
                },
                "stock[length]": {
                    required: "Debes introducir una longitud",
                    number: "La longitud debe ser un número"
                },
                "stock[weight]": {
                    required: "Debes introducir un peso",
                    number: "El peso debe ser un número"
                },
                "stock[description]": {
                    required: "Debes introducir una descripción del stock del producto"
                },
                "warranty[description]": {
                    required: "Debes introducir una descripción de la garantía para este producto"
                },
                "warranty[valid_time]": {
                    required: "Debes introducir un período de validez",
                    digits: "El período de validez no es válido"
                },
            }
        });

        is_valid = $("#product_create").valid();
        break;
}

return is_valid;

}

我的问题是,如果表格在step5通过时无效?不应该失败吗?

2 个答案:

答案 0 :(得分:1)

Quoet OP

  

“由于variation[pprice][]是一个项目数组,我可以使用$.each移动它们并分配规则吗?”

当jQuery选择器针对多个输入元素时,您必须使用.each()但是,这并不能解决 jQuery Validate插件要求每个输入元素包含唯一name属性的事实。这就是插件跟踪元素的方式。 (一组具有相同名称的无线电或复选框元素不是问题,因为当它们被分组时,它们应该具有相同的名称......该组充当单个数据输入。

不会 有效,因为有多个输入元素具有相同的name ...

$('input[name="something"]').each(function() {
    $(this).rules('add', function() {
        required: true,
        // another rule, etc,
    });
});

只要每个输入元素包含唯一的name ...

就会工作
$('input.class').each(function() {
    $(this).rules('add', function() {
        required: true,
        // another rule, etc,
    });
});

有关可以定义和应用规则的各种方法,请参阅this answer


步骤表单有各种方法。

当我创建多步骤表单时,我为每个部分使用一组唯一的<form>标记。然后我使用the .valid() method测试该部分,然后再移动到下一部分。 (不要忘记首先初始化插件;在DOM准备好的所有表单上调用.validate()。)

然后在最后一节,我在每个表单上使用.serialize()并将它们连接成一个要提交的数据查询字符串。

像这样......

$(document).ready(function() {

    $('#form1').validate({ // initialize form 1
        // rules
    });

    $('#gotoStep2').on('click', function() { // go to step 2
        if ($('#form1').valid()) {
            // code to reveal step 2 and hide step 1
        }
    });

    $('#form2').validate({ // initialize form 2
        // rules
    });

    $('#gotoStep3').on('click', function() { // go to step 3
        if ($('#form2').valid()) {
            // code to reveal step 3 and hide step 2
        }
    });

    $('#form3').validate({ initialize form 3
        // rules,
        submitHandler: function (form) {
           // serialize and join data for all forms
           // ajax submit
           return false;
        }
    });

    // there is no third click handler since the plugin takes care of this 
    // with the built-in submitHandler callback function on the last form.

});

重要的是要记住上面的click处理程序没有使用type="submit"按钮。这些是常规按钮,form代码的外部type="button"

只有最后一个表单上的按钮才是常规type="submit"按钮。那是因为我只在最后一种形式上利用插件的内置submitHandler回调函数。

“概念证明”DEMO:http://jsfiddle.net/N9UpD/

另外,请参阅参考:

https://stackoverflow.com/a/17975061/594235

答案 1 :(得分:0)

假设您每次加载步骤时都设置了配置规则,那么您可以为每个步骤保留一个配置规则。

要删除隐藏字段的验证,您可以创建每次更改可见性字段时调用的JavaScript函数,在此函数中您可以再次设置配置规则,或者您可以删除配置规则和字段之间的链接元素,仅用于隐藏字段。我知道此链接是标记名称,要设置标记名称,您可以使用此代码$('#element').attr('name',null)