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: