Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Validator - How to validate against non-form items?

I have a form where a user can keep adding items to a list. When they go to submit this page, I want to validate that this list actually has items in it (not the individual items as they've already been validated). Each item gets added to a new row in a table with the TR having an extra attribute of "action"... so it looks like:

<tr action="whatever">...</tr>

What I was attempting to do is add a custom addMethod that called a function which would count the number of rows with action as an attribute:

$("#tableID").find("tr[action]").length

and if that length is greater than 0, it returns true, otherwise, false.

This works fine outside of the validator calls but for some reason it completely skips over it.

I could really use an example or some insight into how to make it validate this rule even though it is not a form element specifically.

Scaled down code:

*note that I already have defaults being setup for messages and what not.

$.validator.addMethod("validProductList", function (value, element) {
        return this.optional(element) || validateProductList();
    }, "You have no products in your list");

$("#processForm").click(function () {
        $("#pageForm").validate({
            submitHandler: function () {
                $("#errors").hide();
                //processPage();
            },
            rules: {
                //other rules,
                validProductList: true
            }
        });
    });

function validateProductList() {
    var isValid = false;
    var useList = $("#tblAddedProducts").find("tr[action]").length;
    if (useList > 0) { isValid = true; }
    return isValid;
}
like image 846
Joshua Avatar asked Jul 07 '11 21:07

Joshua


2 Answers

The reason this doesn't work is because the rules object expects its children to be form field names (not rule names). It looks like validate isn't capable of validating non-form elements. However, there's a way you can get around this:

  1. Add an <input type='hidden' /> to your form that you update depending on the state of the list. In other words, every time you add or remove a list item, set the value of that input. This has an obvious disadvantage; your validation code is now spread across two actions (adding and removing list items). However, I imagine you already have code that handles adding/removing, you could add a common method that re-evaluates the state of the aforementioned input.

  2. Make that input required and use .validate() normally.

Here's a really rough working example: http://jsfiddle.net/dT6Yd/

You can make item (1) a little easier if you use a framework like knockoutjs. You could tell that framework to "observe" your list and update the input automatically without you having to keep track of it.

Not the cleanest way of handling the problem, but I've seen it done this way before and it seems to work well enough.

like image 119
Andrew Whitaker Avatar answered Sep 28 '22 00:09

Andrew Whitaker


I've found a solution in the source code:

return $( this.currentForm )
        .find( "input, select, textarea, [contenteditable]" )

So jquery-validation takes only these types of elements.. I simply added the attribute "contenteditable" to the element I want to validate and added a custom validator.

<div contenteditable data-rule-raty="true" data-score="0" data-plugin="rating"></div>

$.validator.addMethod("raty-required", function (value, element, regexpr) {
  return $(element).raty("score") >= 0;
}, "Bitte Bewertung abgegeben");
like image 25
Simon Ludwig Avatar answered Sep 28 '22 02:09

Simon Ludwig