En este ejemplo:

<form name="someform" action="somepage.php" method="post">
    <input name="length" id="length" type="number" min="1" oninput="validate()"/>
    <input type="submit" id="submit" value="submit" />
</form>

Quiero deshabilitar el botón Enviar para cualquier valor de longitud que no sea mayor que 0. Tengo min = "1" en la entrada, que funciona bien cuando los usuarios confían en los botones arriba / abajo para ingresar un valor, pero lo hace no les impida ingresar un 0 con el teclado. Así que he agregado la siguiente función de validación js.

function validate() {
   var valid = true;
   length = document.getElementById("length").value;
   if(!length > 0) {
       valid = false;
   }    
   document.getElementById("submit").disabled = valid == false;
}

Esta función devuelve válido = verdadero si ingresa un 0 en el cuadro y no entiendo por qué. Si tiene un número en el cuadro y lo elimina para que el cuadro esté vacío, devolverá falso, pero 0 siempre es verdadero aquí.

Editar: puede ingresar un número negativo, como -5 y que también devuelve verdadero.

Tengo un ejemplo de jsbin aquí: http://jsbin.com/qatekupuzu/edit ? html, js, consola, salida

Cualquier ayuda para que esto funcione correctamente sería apreciada.

1
Anonymous Man 15 feb. 2017 a las 23:44

6 respuestas

La mejor respuesta

No necesita ningún if simplemente almacene la prueba dentro del booleano valid directamente. Me gusta esto:

function validate() {
   var length = document.getElementById("length").value; // get the value
   var valid = length > 0;                               // if length is > 0 then valid will be true, otherwise it will be false
   document.getElementById("submit").disabled = !valid;  // disable if only valid is false
}
2
ibrahim mahrir 15 feb. 2017 a las 20:47

Por qué no:

 document.getElementById("length").oninput=function (){
   this.value=Math.max(this.value,1);
 }

O:

 document.getElementById("length").oninput=function (){
   this.value=this.value>0?this.value:"";
 }

Más fácil de entender para el usuario, en lugar de deshabilitar ...

0
Jonas Wilms 15 feb. 2017 a las 21:14

validate() se activa en cada pulsación de tecla, por lo que es mejor inicializar los objetos lengthInput y submitButton una vez y usarlos en la función para un mejor rendimiento.

var lengthInput = document.getElementById("length"),
    submitButton = document.getElementById("submit");

function validate() {
   submitButton.disabled = !(lengthInput.value > 0);  
}

// initial validation
validate();
<form name="someform" action="somepage.php" method="post">
    <input name="length" id="length" type="number" min="1" oninput="validate()"/>
    <input type="submit" id="submit" value="submit" />
</form>
0
Ja9ad335h 15 feb. 2017 a las 21:00

Parece que nadie ha captado esto, así que arrojaré esta respuesta para arrojar algo de luz sobre lo que realmente está sucediendo aquí.

La razón por la cual su declaración se comporta así es porque no es la declaración que usted cree que es. Inspeccionemos y veamos.

if(!length > 0) es lo que escribiste. Esta declaración dentro de if es en realidad dos declaraciones. !length se evalúa primero, luego su valor se compara con > 0.

!length se evalúa como booleano, que es solo true si el número es 0. Cualquier otro número se evalúa como false. Entonces, debido a que el operador izquierdo de > es un booleano, > 0 se evalúa como boolean > boolean, que solo se evalúa como true si la declaración es true > false.

Entonces, el problema no es que la declaración regrese incorrectamente, simplemente no está usando la declaración que desea. Lo que pretendía escribir es if( !(length >0) ){ valid = false; } o más concisamente if(length <=0) { valid = false; }

EDITAR: Otro factor está en juego aquí que me engañó en base al nombre de la variable length. Llamar a typeof(length) revela que esta variable es una string a pesar de la aplicación number en el elemento. Lo anterior aplica lo mismo para el tipo string con la modificación de que !"" es la única cadena que se evalúa como true.

No tengo claro si está intentando validar o no que la longitud de esta cadena sea mayor que 0 (es decir, no está vacía), o si desea validar que el número que ingresó el usuario es mayor que 0. Si el primero es el caso, luego evaluar length.length es lo que quieres. Para este último, necesitaría analizar esto como un int primero usando parseInt().

1
RayfenWindspear 15 feb. 2017 a las 21:52

Los navegadores modernos no requieren JavaScript para deshabilitar la entrada.

input:invalid {
  /* background-color: #ffdddd; */
}

form:invalid [type="submit"] {
  opacity: .5;
  pointer-events: none;
}
<form name="someform" action="somepage.php" method="post">
    <input name="length" id="length" type="number" min="1" required/>
    <input type="submit" id="submit" value="submit"/>
</form>

El error con su código es el hecho de que en realidad es ((!length) > 0). Cambiarlo a !(length>0) o (length<=0) tendría más sentido. Y realmente está comparando una cadena con un número, por lo que debe ser Number(length) para no depender de la coerción de tipo.

0
epascarello 15 feb. 2017 a las 21:24

No deberías escribir !length > 0. En su lugar, use length != 0 o length <= 0

1
stackoverfloweth 15 feb. 2017 a las 20:47