Desabilitar option ou nem deixar aparecer(resolvido)

Pessoal boa noite,

Tem uma atividade onde tenho duas combos uma com os meses do ano(janeiro, fevereiro…) e outra com anos (2017, 2018, 2019, 2020) porem a atividade pede que se estivermos em Março/2018 os meses de janeiro /2018 e Fevereiro/2018 não podem ser selecionados ou nem aparecer para ser selecionado.
Então eu pensei em criar duas tabelas com mes e os anos solicitados e criar um javascript para validar isso. O problema é que eu até conseguir fazer um javascript que desabilitava os meses de janeiro e fevereiro mas somente depois de selecionar na combo e a ideia é que assim que abrir a tela ja esteja desabilitado ou nem apareça, segue o codigo:

function desabilitaMes(mesAtual){
	 
	   mes = document.getElementById('mesReajuste'); 
   
	   for(i=0;i<=mes.options.length;i++){ 

	      if(mes.options[i].value < 3){ 
	         mes.options[i].disabled = true; 
	      }else{ 

	         mes.options[i].disabled = false; 
	         		        	         
	      } 
	   }
	}

Esse é a combo na JSP:

<select class="form-control m-input" id="mesReajuste" name="mesReajuste" onchange="desabilitaMes(this.value)">
						<c:forEach var="parametrosSimulacaoResult" items="${colecaoMes}">
								<option value="${parametrosSimulacaoResult.codigo}">${parametrosSimulacaoResult.mesAbrev}</option>
							</c:forEach>
					</select>

eu poderia colocar na jsp os meses, mas podem ser mudados então é mais facil mudar no banco do que no codigo.

me ajudem…Desde ja agradeço!

Cara, não seria melhor você já carregá-los bloqueados, sem nem passar pela função?

Algo nesse sentido não ajuda?

...
<script>
var dataAtual = new Date();
var mes = document.getElementById('mesReajuste'); 
var ano = document.getElementById('anoReajuste');

for(i=0;i<=mes.options.length;i++){ 
    if(mes.options[i].value < dataAtual.getMonth() + 1) {
        mes.options[i].disabled = true; 
    }
}

for(i=0;i<=ano.options.length;i++){ 
    if(ano.options[i].value < dataAtual.getFullYear()) {
        ano.options[i].disabled = true; 
    }
}
</script>
</body>
</html>

getMonth() mes de 0-11 (0 = jan, 11 = dez)…
getFullYear() ano com 4 digitos…

Obviamente quebrei um pouco as boas práticas deixando tudo no escopo global, você pode encapsular cada lógica em sua função e chamá-las logo após, no escopo global ou no windo.onload… assim dessa forma o combo já terá seus options anteriores bloqueados apenas para o usuário visuá-los…

Usei o objeto Date do js apenas como exemplo, mas o ideal é trazer o ano e mes fixos do servidor, pois o usuário pode alterar o relógio/calendário local ai ja viu…

Espero ter ajudado…

A chamada no JSP permanece a mesma, certo?

A principio sim, você só removeria o onchange do select, pois da forma que lhe mostrei nem precisa dele…

Ficou assim:

function desabilitaMes(MesAtual) {

	var dataAtual = new Date();
	mesReajuste = document.getElementById('mesReajuste');
	anoReajuste = document.getElementById('anoReajuste');
	for (i = 0; i <= anoReajuste.options.length; i++) {
		if (anoReajuste.options[i].value == dataAtual.getFullYear()) {
			for (i = 0; i <= mesReajuste.options.length; i++) {
				if (mesReajuste.options[i].value < dataAtual.getMonth()) {
					mesReajuste.options[i].disabled = true;
				}
			}
		} else {
			mesReajuste.options[i].disabled = false;
		}

	}

}

Porque tem uma logica que não me atentei… se a pessoa escolher ano de 2019 ele pode escolher todos os meses do ano, mas se ele escolher o ano de 2018 ele só pode escolher a partir de março.

porem ao rodar na jsp da erro.

Uncaught TypeError: Cannot read property 'value' of undefined

no trecho: if (mesReajuste.options[i].value < dataAtual.getMonth())

Nesse caso fica melhor você manter do jeito que estava e acrescentar no if do mês…

... 
if(mes.options[i].value < dataAtual.getMonth() + 1 && 
    ano.options[ano.selectedIndex].value <= dataAtual.getFullYear()) {
    mes.options[i].disabled = true; 
}
...

Definitivamente você não precisa de um for dentro do outro, já que o que te importa é comparar os options com ano/mes atual separadamente correto?

Esse trecho…

ano.options[ano.selectedIndex].value

Usei apenas como exemplo formal/acadêmico, mas também funciona assim…

ano.value

Antigamente não devido incompatibilidade entre navegadores, mas hoje em dia isso já está resolvido.

Agora como você precisa da função por causa do onchange, pode encapsular tudo assim…

function desabilitaMes(){
    var dataAtual = new Date();
    var mes = document.getElementById('mesReajuste'); 
    var ano = document.getElementById('anoReajuste');

    for(i=0;i<=mes.options.length;i++){ 
        var bloqueia = (mes.options[i].value < dataAtual.getMonth() + 1 && 
            ano.options[ano.selectedIndex].value <= dataAtual.getFullYear());
        mes.options[i].disabled = bloqueia; 
    }

    for(i=0;i<=ano.options.length;i++){ 
        var bloqueia = (ano.options[i].value < dataAtual.getFullYear());
        ano.options[i].disabled = bloqueia;
    }
}

desabilitaMes();

Perceba que chamei a função logo após sua criação, isso já previne o bloqueio, o onchange você mantém para chamar a função novamente e assim por diante…

Perceba também que no dataAtual.getMonth() somei + 1, isso é necessário porque se o value de cada option no mês começar com 1-12 (como eu vi você usando 3 para Março) o if vai dar errado sem ele, e você o retirou, fique atento a isso caso o value de cada option começar com 0-11 (nesse caso Março vale 2) ai tudo bem retirar o + 1…

Obs: Editei um pouco a parte dos ifs, pois a lógica é if/else mesmo, do jeito que deixei antes irie sempre bloquear os options e nunca desbloquear, como o if já retorna um boolean (true/false) basta colocar seu resultado numa variável e depois usar no disabled do option…

Espero ter ajudado…

1 curtida

obrigado resolveu…!

1 curtida