Is it possible to have dynamic rules with jquery validation?

Asked

Viewed 1,772 times

6

I got three fields, two inputs text and between them a select. If one of the first two is filled in the other becomes mandatory. The problem is that when a single value, in the latter case, of the select is filled the three become mandatory.

It is possible to have dynamic rules with this plugin, ie when checking the value of select make the third field mandatory?

HTML

<div id="msgErros"></div>
<form>
    <label for="tempoInicial">Tempo Inicial</label>
    <input type="text" name="filtro.tempoInicial" size="8" value="" id="tempoInicial" class="tempo" />
    <br />
    <label for="operadorTempo">Operador de Tempo</label>
    <select name="filtro.valorOperadorTempo" id="operadorTempo" class="tempo">
        <option value="">-- Selecione --</option>
        <option value="1">&gt; - Maior</option>
        <option value="2">&lt; - Menor</option>
        <option value="3">Entre</option>
    </select>
    <br />
    <label for="tempoFinal">Tempo Final</label>
    <input type="text" name="filtro.tempoFinal" size="8" value="" id="tempoFinal" />
    <br />
    <button>Enviar</button>
</form>

Javascript

$.validator.addMethod("skip_or_fill_minimum", function (value, element, options) {
    var $fields = $(options[1], element.form),
        $fieldsFirst = $fields.eq(0),
        validator = $fieldsFirst.data("valid_skip") ? $fieldsFirst.data("valid_skip") : $.extend({}, this),
        numberFilled = $fields.filter(function () {
            return validator.elementValue(this);
        }).length,
        isValid = numberFilled === 0 || numberFilled >= options[0];

    // Store the cloned validator for future validation
    $fieldsFirst.data("valid_skip", validator);

    // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
    if (!$(element).data("being_validated")) {
        $fields.data("being_validated", true);
        $fields.each(function () {
            validator.element(this);
        });
        $fields.data("being_validated", false);
    }
    return isValid;
}, jQuery.validator.format("Please either skip these fields or fill at least {0} of them."));

$("form").validate({
    errorContainer: "#msgErros ul",
    errorLabelContainer: "#msgErros",
    wrapper: "li",
    rules: {
        "filtro.tempoInicial": {
            skip_or_fill_minimum: [2, ".tempo"]
        },
            "filtro.valorOperadorTempo": {
            skip_or_fill_minimum: [2, ".tempo"]
        }
    },
    groups: {
        tempos: "filtro.tempoInicial filtro.valorOperadorTempo"
    },
    onfocusout: function (element, event) {
        var classeCSSElemento = $(element).attr("class");
        var classeCSSElementoIndefinida = typeof classeCSSElemento === "undefined";
        if (classeCSSElementoIndefinida || (!classeCSSElementoIndefinida && !classeCSSElemento.contains("tempo"))) {
            $.validator.defaults.onfocusout.call(this, element, event);
        }
    }
});

Fiddle

2 answers

1


It is possible to add and remove validation rules dynamically, as indicated by this response in SOEN: https://stackoverflow.com/a/4878858/195417

I am currently limited to internet, please check if this solves your problem... I can’t see the documentation to be sure.

  • Exactly what I needed, thank you!

  • One last question, do you know how to put this input to a group and dynamically pull it out?

  • @Philippegioseffi: from what I could see in the documentation and in the SOEN there is no way to dynamically change the group. I’m limited access, (no google, and some other sites), so it gets kind of complicated. =\

  • Someone screwed up in the Infra sector here! hehe

  • Good, then I will leave the group fixed with the three fields, I will leave now only the dynamic messages, thanks again for the help.

  • Arrange... I’ll keep trying later when the problem here is solved.

Show 1 more comment

1

It is possible to make this logic much simpler. Just add the following rules:

rules: {
    "filtro.tempoInicial": {
        required: function(element) {
            return $("#operadorTempo").val() == 3
                   || $('#tempoFinal').val() == '';
      }
    },
    "filtro.valorOperadorTempo": {
        required: true
    },
    "filtro.tempoFinal": {
        required: function(element) {
            return $("#operadorTempo").val() == 3 
                   || $('#tempoInicial').val() == '';
        }
    }
},

You don’t need that additional validator.

Functional demo in Jsfiddle

  • For this specific reality really works, but I was told to always put in my questions only the problem I am having, because usually nobody reads long Htmls or Scripts, with that said, I explain to you that your solution does not solve my problem, because I have more fields and more rules on this form, but the test I did met perfectly if it were only these.

  • In fact, if you edit your second rule of true to function(element) { return $('#tempoInicial').val() == ''; } I think it would work for my case.

  • @Philippegioseffi If the user can leave all fields blank, this solves.

  • The change I made in the second comment would already solve my problem. Thanks for the help anyway!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.