How to validate format and compare two dates to enable buttons

6

I'm using a script * to enable a button when two validations are done. The first one checks the format, and the second if the start date is smaller than the final one, but I'm having some problems adding more fields with the same functionality, and correcting some inconsistencies.

I've created a FIDDLE to demonstrate how it works in practice, and the sample code below verifiable. The script already does the validation (both formatting and comparison) before opening the button, but:

  • Only works when you lose focus, you want it to be as with onkeyup (when you release the key), but if you have no way it can be only when you lose the same focus;
  • If the user, after the button has been opened, changes the date to an invalid format (or that is shorter than another that should be larger), the no button is disabled (and I need it to be). I need not to be able to "go on screen" (change from div , see fiddle) without the format to be correct, and observe the start date condition < final date;
  • The last date, which makes the comparison with the second, even opens div with the error message (when the date is smaller or is in the wrong format), but still sends the form ( which was not supposed to happen );
  • The field accepts letters, and only after loses focus it gives the message that the format is wrong. I would like the field not to accept letters, just numbers (Can not RegExp?) Or even / which causes problems because the user sometimes tries to enter it.

I'm open to other solutions, even with plugins other than that I'm using to check the formatting, but I've already come a long way another solution and I did not find it. Either the plugin / script validates the formatting, or well worth the comparison of the dates, and I need both.

Follow the code:

    // VALIDAÇÃO DO FORMATO PELO FORM.VALIDATOR

// Chama o form.validator

    $.validate({
        modules: 'date'
    });

    // Cria uma classe que verifica se o form.validator foi true, e abre o botão.

    $('.checar')

            .on('validation', function (evt, valid) {
                var validou =  document.getElementById('validou').value = valid ? "true" : "false";

                /* Verifica SE a data está OK */

                if (validou === "true") {
                    verificar(); // chama o script abaixo antes de abrir o botão se o formato está correto
                }
            });


    //VALIDA DATAS EM COMPARAÇÕES 

    var primeiradata = document.getElementById('Cinsem');
    var segundadata = document.getElementById('Cdesl22');
    var terceiradata = document.getElementById('Cinsem2');
    var quartadata = document.getElementById ('Cdesl223');
    var quintadata = document.getElementById('Cdatapgtos');

    function gerarData(str) {
        var partes = str.split("/");
        return new Date(partes[2], partes[1] - 1, partes[0]);
    }

    function verificar() {
        var primeira = primeiradata.value;
        var segunda = segundadata.value;
        var terceira = terceiradata.value;
        var quarta = quartadata.value;
        var quinta = quintadata.value;

        // PRIMEIRA DATA X SEGUNDA DATA

        if (primeira.length != 10 || segunda.length != 10) {
            return;
        }
        if (gerarData(segunda) >= gerarData(primeira)) {
            $('#startBtnseg').removeAttr('disabled', 'disabled');
            $('#message1').hide();
        }
        else {
            $('#startBtnseg').attr('disabled', 'disabled');
            $('#message1').fadeIn('slow');
        }
        // TERCEIRA DATA X QUARTA DATA

        if (terceira.length != 10 || quarta.length != 10) {
            return;
        }
        if (gerarData(quarta) >= gerarData(terceira)) {
            $('#startBtnseg2').removeAttr('disabled', 'disabled');
            $('#message2').hide();
        }
        else {
            $('#startBtnseg2').attr('disabled', 'disabled');
            $('#message2').fadeIn('slow');
        }

        //QUINTA DATA X SEGUNDA DATA

        if (quinta.length != 10 || segunda.length != 10){
            return;
        }
        if (gerarData(quinta) < gerarData(segunda)){
            $('#startBtnseg3').attr('disabled', 'disabled');
            $('#message3').fadeIn('slow');
        }
        else {
            $('#startBtnseg3').removeAttr('disabled', 'disabled');
            $('#message3').hide();
        }
    }

  
    <style>
        .message1 {

            font-size: 10pt;
            color: red;
        }
    </style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><scriptsrc="http://cdnjs.cloudflare.com/ajax/libs/jquery-form-validator/2.1.47/jquery.form-validator.min.js"></script>
<form>
    <div class="container textWord_about"  data-link="first">
    <label class="btn" for="Cinsem">
    <i class="glyphicon glyphicon-calendar"></i>Primeira data
    <input class="form-control checar" type="text" maxlength="10" placeholder="dd/mm/aaaa"
           onkeyup="formatar('##/##/####', this, event)" name="Tinsem3" id="Cinsem"
           data-validation="birthdate" data-validation-error-msg="Insira uma data válida"
           data-validation-format="dd/mm/yyyy"></label>
<br><br>
<label class="btn" for="Cdesl22">
    <i class="glyphicon glyphicon-calendar"></i>Segunda data
    <input type="text" class="form-control checar" name="Tdesl"  maxlength="10" data-validation="date"
           data-validation-format="dd/mm/yyyy" data-validation-error-msg="Insira uma data válida" placeholder="dd/mm/aaaa"
           onkeyup="formatar('##/##/####', this, event)" id="Cdesl22"></label>

<!-- Espelho de #aniv1,porém do tipo "date" -->
<label for="Cdesl222"></label>
<input type="date" id="Cdesl222" name="Cdesl22" class="checar" hidden="hidden" />

<!-- Auxilia na validação. Pode ser um DIV também mas precisará alterar o código -->
<label for="validou"></label>
<input type="text" id="validou" name="validou" hidden="hidden" class ="checar" value="false" />

<div class="message1 " id="message1" style="display:none;"><br><br>A segunda data deve ser igual ou posterior à primeira data.</div>
    <br><br>

<button type="button" class="btn btn-primary btn-sm link" id="startBtnseg"  name="TstartBtnseg"
        data-link="dois" onkeyup="verificar()" disabled="disabled">
    <i class="glyphicon glyphicon-ok"> Ir para próximas datas</i></button>
       <br><br>
        A segunda data deve ser <b>igual ou maior</b> que a primeira, e ambas devem estar
        no formato correto (ou seja, não pode aceitar letras, nem mês acima de 13 etc) para abrir o botão.
        Caso o usuário, antes de submeter o formulário (ou depois, se ele voltar) faça qualquer alteração
        que torne o formato inválido, ou torne a data final menor que a inicial, o botão deve ser desabilitado.
        O ideal é que a habilitação/desabilitação do botão seja feita com onkeyup (assim que o usuário
        tirar a pressão da tecla), mas se não tiver jeito pode ser só quando perder o foco mesmo (e eu criaria uma botão
        "falso" para "Checar data", onde o usuário clicaria apenas para o campo perder o foco e realziar a validação).
    <br><br>
</div>
    <div class="container textWord_about"  data-link="dois">
        <label class="btn" for="Cinsem2">
            <i class="glyphicon glyphicon-calendar"></i>Terceira data
            <input class="form-control checar" type="text" maxlength="10" placeholder="dd/mm/aaaa"
                   onkeyup="formatar('##/##/####', this, event)" name="Tinsem3" id="Cinsem2"
                   data-validation="birthdate" data-validation-error-msg="Insira uma data válida"
                   data-validation-format="dd/mm/yyyy"></label>
        <br><br>
        <label class="btn" for="Cdesl223">
            <i class="glyphicon glyphicon-calendar"></i>Quarta data
            <input type="text" class="form-control checar" name="Tdesl"  maxlength="10" data-validation="date"
                   data-validation-format="dd/mm/yyyy" data-validation-error-msg="Insira uma data válida" placeholder="dd/mm/aaaa"
                   onkeyup="formatar('##/##/####', this, event)" id="Cdesl223"></label>

        <!-- Espelho de #aniv1,porém do tipo "date" -->
        <label for="Cdesl222"></label>
        <input type="date" id="Cdesl2223" name="Cdesl223" class="checar" hidden="hidden" />

        <!-- Auxilia na validação. Pode ser um DIV também mas precisará alterar o código -->
        <label for="validou"></label>
        <input type="text" id="validou3" name="validou" hidden="hidden" class ="checar" value="false" />

        <div class="message1" id="message2" style="display:none;"><br><br>A data quarta data deve ser posterior à terceira data.</div>
        <br><br>

        <button type="button" class="btn btn-primary btn-sm link" id="startBtnseg2"
                data-link="tres" onkeyup="verificar()" disabled="disabled">
            <i class="glyphicon glyphicon-ok"> Próximas!</i></button>
        <br><br>
        Igual a primeira tela, considerando entre a terceira e a quarta datas.
    </div>

    <div class="container textWord_about" id="menu_about" data-link="tres">
<label class="btn" for="Cdatapgtos">
    <i class="glyphicon glyphicon-calendar"></i> Quinta data
    <input type="text"  id="Cdatapgtos" name="Tdatapagtos" class="form-control checar" maxlength="10"
           placeholder="dd/mm/aaaa" onkeyup="formatar('##/##/####', this, event)"></label>
<div class="message1 " id="message3" style="display:none;">A quinta data deve ser igual ou posterior à segunda data.</div>
    <br><br>
<button type="submit" id="startBtnseg3" class="btn btn-primary btn-sm" onkeyup="verificar()">
    <i class="glyphicon glyphicon-ok">Submeter formulário</i></button>
        <br><br>
        A quinta data deve ser <b>IGUAL OU POSTERIOR</b> à <b>SEGUNDA DATA</b>, e ambas devem
        estar no formato correto para que o formulário seja submetido. O botão de submeter
        o formulário precisa estar habilitado, e será desabilitado caso as validações não ocorram (formato de data e comparação
        com segunda data). Da mesma forma seria interessante com onkeyup, mas pode ser quando clicar no botão.
        O campo não é obrigatório, mas caso seja preenchido é feita a validação, e habilitado/desabilitado.
        </div>
</form>
        
        <script>      // ALTERNA AS DIV's

  $('.textWord_about').not(':first').hide();
    $('.link').click(function() {
        $('.textWord_about').hide();
        $('.textWord_about[data-link=' + $(this).data('link') + ']').fadeIn('slow');
    });</script>
        
        <script>
            
// MÁSCARA DOS CAMPOS

function formatar(mascara, documento, e) {
        var code = e.keyCode || e.code;
        if (code == 8 || code == 46 || code == 37 || code == 39) return;
        var i = documento.value.length;
        var saida = mascara.substring(0, 1);
        var texto = mascara.substring(i);
        if (texto.substring(0, 1) != saida) {
            documento.value += texto.substring(0, 1);
        }
    }

            
        </script>
  

Several users here from SOpt helped me to implement this script. See the series of questions:

asked by anonymous 25.06.2015 / 05:42

1 answer

6

I ended up removing some parts of your code that I did not find necessary and added some <p> to get better displayed, as well as remove HTML5 validation.

.message1 {
    font-size: 10pt;
    color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><scripttype="text/javascript" src="http://pastebin.com/raw.php?i=gE1SbXKA"></script><scripttype="text/javascript" src="http://pastebin.com/raw.php?i=8xvHJBJf"></script><scripttype="text/javascript" src="http://pastebin.com/raw.php?i=YRhQfUJs"></script><formonsubmit="return verifica('data2', 'data5', false, 3);">
    <div class="container textWord_about"  data-link="first">
	
        <p>
            <label class="btn" for="Cinsem">
                <i class="glyphicon glyphicon-calendar"></i>Primeira data
                <input class="form-control checar" id="data1" type="text" maxlength="10"
				       data-funcao="verifica('data1', 'data2', true, 1);">
            </label>
        </p>
        <p>
            <label class="btn" for="Cinsem">
                <i class="glyphicon glyphicon-calendar"></i>Segunda data
                <input class="form-control checar" id="data2" type="text" maxlength="10"
				       data-funcao="verifica('data1', 'data2', false, 1);">
            </label>
        </p>

        <button type="button" class="btn btn-primary btn-sm link" id="botao1" 
		        data-link="dois" disabled="disabled">
            <i class="glyphicon glyphicon-ok"> OK, vamos continuar!</i>
        </button>
		   
        <p>
            A segunda data deve ser <b>igual ou maior</b> que a primeira, e ambas devem estar
            no formato correto (ou seja, não pode aceitar letras, nem mês acima de 13 etc) para abrir o botão.
            Caso o usuário, antes de submeter o formulário (ou depois, se ele voltar) faça qualquer alteração
            que torne o formato inválido, ou torne a data final menor que a inicial, o botão deve ser desabilitado.
            O ideal é que a habilitação/desabilitação do botão seja feita com onkeyup (assim que o usuário
            tirar a pressão da tecla), mas se não tiver jeito pode ser só quando perder o foco mesmo (e eu criaria uma botão
            "falso" para "Checar data", onde o usuário clicaria apenas para o campo perder o foco e realziar a validação).
        </p>
    </div>
	
    <div class="container textWord_about"  data-link="dois">
	
        <p>
            <label class="btn" for="Cinsem">
                <i class="glyphicon glyphicon-calendar"></i>Terceira data
                <input class="form-control checar" id="data3" type="text" maxlength="10"
				       data-funcao="verifica('data3', 'data4', true, 2);">
            </label>
        </p>
        <p>
            <label class="btn" for="Cinsem">
                <i class="glyphicon glyphicon-calendar"></i>Quarta data
                <input class="form-control checar" id="data4" type="text" maxlength="10"
				       data-funcao="verifica('data3', 'data4', false, 2);">
            </label>
        </p>

        <button type="button" class="btn btn-primary btn-sm link" id="botao2" 
		        data-link="tres" disabled="disabled">
            <i class="glyphicon glyphicon-ok"> OK, vamos continuar!</i>
        </button>
		   
        <p>
            Igual a primeira tela, considerando entre a terceira e a quarta datas.
        </p>
    </div>
	
    <div class="container textWord_about"  data-link="tres">
	
        <p>
            <label class="btn" for="Cinsem">
                <i class="glyphicon glyphicon-calendar"></i>Quinta data
                <input class="form-control checar" id="data5" type="text" maxlength="10"
				       data-funcao="verifica('data2', 'data5', false, 3);">
            </label>
        </p>

        <button type="submit" id="botao3" class="btn btn-primary btn-sm"
		        onclick="return verifica('data2', 'data5', false, 3);">
            Submeter formulário
        </button>
		   
        <p>
            A quinta data deve ser <b>IGUAL OU POSTERIOR</b> à <b>SEGUNDA DATA</b>, e ambas devem
            estar no formato correto para que o formulário seja submetido. O botão de submeter
            o formulário precisa estar habilitado, e será desabilitado caso as validações não ocorram (formato de data e comparação
            com segunda data). Da mesma forma seria interessante com onkeyup, mas pode ser quando clicar no botão.
            O campo não é obrigatório, mas caso seja preenchido é feita a validação, e habilitado/desabilitado.
        </p>
    </div>
	        
    <script>      // ALTERNA AS DIV
        $('.textWord_about').not(':first').hide();
        $('.link').click(function() {
            $('.textWord_about').hide();
            $('.textWord_about[data-link=' + $(this).data('link') + ']').fadeIn('slow');
        });
    </script>
        
    <script>    // MÁSCARA DOS CAMPOS
        $(document).ready(function(){
            $('.checar').inputmask("dd/mm/yyyy",
                                    {
                                        "oncomplete": function () {
                                            eval($(this).data("funcao"));
                                    }
            });
        });
		
        function gerarData(str) {
            var partes = str.split("/");
            return new Date(partes[2], partes[1] - 1, partes[0]);
        }
		
        function verifica(idMenor, idMaior, primeiro, botao) {
            $('.message1').remove();
		
            $campoMenor = $('#' + idMenor);
            $campoMaior = $('#' + idMaior);
            $campoAviso = primeiro ? $campoMenor : $campoMaior;
            $botao = $('#botao' + botao);
			
            if (!$campoMaior.val() || !$campoMenor.val())
                return;
			
            if (gerarData($campoMenor.val()) <= gerarData($campoMaior.val())) {
                $botao.removeAttr("disabled");
            } else {
                $campoAviso.after($('<span/>').html("Insira uma data válida").addClass('message1'));
                $botao.attr("disabled", "disabled");
            }
        }
    </script>
</form>

I used that same plugin from

28.06.2015 / 19:52