Problema com JavaScript e Eventos

10 respostas
danieldestro

Caros,

Estou com um "grave" problema com Javascript e eventos relacionados ao formulário HTML. Fiz umas funções para, automaticamente, formatar campos e evitar digitação de caracteres não numéricos. Porém estou tendo um problema com relação a isto. Olhem o código que eu explico o que é.

HTML:
<input type="text" name="cnpj" maxlength="14" size="18" 
  onkeypress="avoidNotNumber(this,event);" onblur="maskCnpj(this);" 
  onfocus="unmask(this);" onchange="doSomething();">
Javascript:
function maskCnpj(e) {
 // mascara o CNPJ no campo
}

function unmask(e) {
 // tira a máscara do texto do campo
}

function doSomething() {
  // faz algo
}

var v_elem_obj = null;

function avoidNotNumber( elem, evt ) {
    // se a tecla tab foi pressionada, ignora (corrige problema com Firefox)
    if( isTabKeyPressed(evt) ) {
        return;
    }
    v_elem_obj = elem;
    setTimeout("execAvoidNotNumber()",1);
    // a execução do timeout acima causa problema no navegador Firefox, pois
    // a formatação fica comprometida quando o foco do campo é perdido pelo 
    // pressionamento da tecla TAB (28/11/2007)
    
    //TODO: a execução deste método acima por timeout ocasiona o seguinte erro:
    // o evento "onchange" não é executado no campo, pois ele acaba sendo 
    // ofuscado pela alteração do valor do campo via javascript. SOLUCIONAR!
}

function execAvoidNotNumber() {
    v_elem_obj.value = removeNonDigits(v_elem_obj.value);
}

function removeNonDigits(e) {
  // remove do campo os caracteres que não são dígitos
}

Quando o campo perde o foco, o evento onChange não é executado quando deveria, pois o método de não permitir não-numéricos (avoidNotNumber) durante a digitação é executado via timeout, causando problemas com isso.

Parece que, por algum motivo, pelo Javascript alterar o conteúdo do campo, ele ignora o evento onchange.

Alguém vê alguma solução?

10 Respostas

Feijao

Destro, meu caro.

Parar de usar timeout não resolveria seu problema??

function avoidNotNumber( elem, evt ) {  

	if (window.event) {
		keynum = evt.keyCode;
	} else if(evt.which) {
		keynum = evt.which;
	}

	keychar = String.fromCharCode(keynum);
	numcheck = /\d/;

	return numcheck.test(keychar);
} 

onkeypress="return avoidNotNumber(this,event);"

Se isso não ajudar me fale que eu penso em alguma outra coisa aqui.

Abrax.
Feijão.

danieldestro

Muito bom. Isso parece me resolver o problema, porém me gera outro problema.
Se, por alguma razão, eu quiser chamar outro método no onkeypress, ele não funciona.
Exemplo:

onkeypress="return avoidNotNumber(this,event);outroMetodo();"

O outroMetodo() não será invocado.

Y

danieldestro:
Muito bom. Isso parece me resolver o problema, porém me gera outro problema.
Se, por alguma razão, eu quiser chamar outro método no onkeypress, ele não funciona.
Exemplo:

onkeypress="return avoidNotNumber(this,event);outroMetodo();"

O outroMetodo() não será invocado.

A não ser que você chame o outroMétodo() antes de chamar o avoidNotNumber().

danieldestro

Eu poderia, mas não deveria fazer isto.

Tendo em visto que este campo é gerado por uma taglib que criei.

Eu quero dar liberdade para o programador adicionar funcionalidade (via eventos e javascript), porém não quero tirar a funcionalidade do meu componente. Então pretendo adicionar o javascript do programador após as chamadas aos javascript da minha biblioteca apenas.

Ou então terei de restringir o uso de certos eventos, o que pode engessar demais o uso do componente.

Feijao

O que deve ser feito é impossibilitar que o campo digitado seja colocado no textbox caso não seja número e não usar o return na chamada do método no evento.

Veja se isso resolve o seu problema:

function avoidNotNumber( elem, evt ) {  

	if (window.event) {
		keynum = evt.keyCode;
	} else if(evt.which) {
		keynum = evt.which;
	}

	keychar = String.fromCharCode(keynum);
	numcheck = /\d/;

	if (!numcheck.test(keychar)) {
		evt.preventDefault();
	}
} 

onkeypress="avoidNotNumber(this,event);alert('olele');"

Abrax.

danieldestro

Não funcionou como esperado.

Quando digito números ele executa o método javascript seguinte. Porém se digito não-numéricos, ele não faz nada e ainda mostra o caracter digitado.

Feijao

Substitua o trecho do if para:

if (!numcheck.test(keychar)) {
		if (evt.preventDefault) {
			evt.preventDefault();
		} else {
			evt.returnValue = false;
		}
	}

Aí irá funcionar no Firefox e no IE.

Se funcionar eu quero uma breja.

danieldestro

FUNCIONOU!
Se você fosse uma mulher bonita eu te daria um beijo.
Como você é homem e feio, pago até duas brejas.
Valeu!

Feijao

Homem, feio e barbudo!

danieldestro

Outro problema relacionado: http://www.guj.com.br/posts/preList/80072/425977.java#425977

Criado 17 de janeiro de 2008
Ultima resposta 24 de jan. de 2008
Respostas 10
Participantes 3