2010-03-10 7 views
29

Tengo un javascript que capta cambios en un formulario y luego llama a la función de envío regular del formulario. El formulario es un formulario GET (para una búsqueda) y tengo muchos atributos vacíos que aparecen en los parámetros. Lo que me gustaría hacer es eliminar todos los atributos vacíos antes de enviar, para obtener una URL más limpio: por ejemplo, si alguien cambia el 'sujeto' seleccionar a 'Inglés' i quieren que su URL búsqueda seaEliminar valores vacíos de los parámetros del formulario antes de enviarlo

http://localhost:3000/quizzes?subject=English 

en lugar de

http://localhost:3000/quizzes?term=&subject=English&topic=&age_group_id=&difficulty_id=&made_by=&order=&style= 

como lo está actualmente. Esto es solo con el propósito de tener una URL más limpia y más significativa para vincular y para los marcadores de las personas, etc. Por lo tanto, lo que necesito es algo en esta línea, pero esto no es correcto ya que no estoy editando la forma real sino un objeto JS hecha de parametros del formulario:

quizSearchForm = jQuery("#searchForm"); 
    formParams = quizSearchForm.serializeArray(); 
    //remove any empty fields from the form params before submitting, for a cleaner url 
    //this won't work as we're not changing the form, just an object made from it. 
    for (i in formParams) { 
    if (formParams[i] === null || formParams[i] === "") { 
     delete formParams[i]; 
    } 
    } 
    //submit the form 

creo que estoy cerca con esto, pero me falta el paso de la forma de editar los atributos de la forma real en lugar de hacer otro objeto y editar eso.

agradecido por cualquier consejo - max

EDITAR - SOLUCIONADO - gracias a las muchas personas que han publicado sobre este. Esto es lo que tengo, que parece funcionar perfectamente.

function submitSearchForm(){ 
    quizSearchForm = jQuery("#searchForm"); 
    //disable empty fields so they don't clutter up the url 
    quizSearchForm.find(':input[value=""]').attr('disabled', true); 
    quizSearchForm.submit(); 
} 
+5

¿Puedo decir, que está muy fresco su pensamiento de sus usuarios por el estilo. –

+0

Buena pregunta y buenas respuestas: Tengo un gran formulario de búsqueda y la mayoría de las veces solo se llena un campo. Ahora las URL son mucho más cortas. – guettli

Respuesta

29

Las entradas con el atributo disabled establecido en true no se enviarán con el formulario. Así, en una línea de jQuery:

$(':input[value=""]').attr('disabled', true); 
+2

Entonces, ¿por qué no simplemente: $ (': input [value = ""]'). Attr ('disabled', true); –

+0

@Marko Dumic - 'attr' solo actuará en el * primer * elemento de la colección resultante. – karim79

+0

@ karim79: Incorrecto. Pruebe: http://jsfiddle.net/EfwBC/ –

4

No puede hacerlo de esa manera si se llama el método de la forma submit; que enviará el formulario completo, no el conjunto que has creado jQuery para ti.

Lo que puede hacer es deshabilitar los campos de formulario que están vacíos antes de enviar el formulario; Los campos desactivados se omiten del envío de formularios. Así que recorra los elementos del formulario y, para cada uno que esté vacío, desactívelo y luego llame al método submit en el formulario. (Si su objetivo es otra ventana, entonces querrá volver y volver a habilitar los campos. Si su objetivo es la ventana actual, no importa, la página se reemplazará de todos modos)

3

Bien una cosa que podría hacer sería desactivar las entradas vacías antes de llamar "serializeArray"

$('#searchForm').find('input, textarea, select').each(function(_, inp) { 
    if ($(inp).val() === '' || $(inp).val() === null) 
    inp.disabled = true; 
    } 
}); 

La rutina "serializeArray()" no incluirá los de sus resultados. Ahora, es posible que deba volver atrás y volver a habilitarlos si la publicación del formulario no va a generar una página completamente actualizada.

+0

Si está llamando al propio método 'submit' del formulario, no necesita llamar' serializeArray'. –

+0

Sí, eso es cierto, pero la muestra del código se corta, y lo hizo después de todo llamar serializeArray en primer lugar. Funcionará para desactivar los campos en un envío normal también, como usted menciona. – Pointy

18
$('form#searchForm').submit(function() { 
    $(':input', this).each(function() { 
     this.disabled = !($(this).val()); 
    }); 
}); 
+0

Esto me funciona mejor, porque tiene en cuenta el nuevo valor editado en el campo de entrada enfocado cuando presiono Enter. – warvariuc

+0

Esta es la respuesta correcta. http://stackoverflow.com/a/2418022/431698 no tiene en cuenta el nuevo valor editado. –

1

Su problema me ayudó a entender mi situación, que es un poco diferente - así que tal vez alguien más puede beneficiarse de ella. En lugar de enviar directamente un formulario, necesitaba evitar que los elementos de formulario vacíos se recopilaran en un conjunto serializado que es y luego publicado a través de AJAX.

En mi caso, yo simplemente necesitaba para recorrer los elementos del formulario y desactivar todos los que estaban vacíos y, a continuación, recoger las sobras en una matriz de este modo:

// Loop through empty fields and disable them to prevent inclusion in array 
$('#OptionB input, select').each(function(){ 
    if($(this).val()==''){ 
     $(this).attr('disabled', true); 
    } 
}); 

// Collect active fields into array to submit 
var updateData = $('#OptionB input, select').serializeArray(); 
0

Otro enfoque siempre recomiendo es hacer que en el lado del servidor, por lo que son capaces de:

  1. Validar los datos de entrada correctamente
  2. valores predeterminados
  3. Set
  4. Cambiar los valores de entrada si n ecesarios
  5. tener una URL limpia o una URL amigable como "/ concursos/Inglés/nivel 1 /"

lo contrario, tendrá que lidiar con la entrada de texto, seleccionar, la radio, etc ...

+0

Hola Thomas. También uso la validación del lado del servidor, pero en este caso lo que quería lograr era una url donde los únicos parámetros en los parámetros de búsqueda eran los que no estaban vacíos. Esto no hace ninguna diferencia en el lado del servidor, pero da URLs más agradables. –

2

Tal vez algunas de las soluciones propuestas funcionaron en el momento en que se hizo la pregunta (marzo de 2010), pero hoy, agosto de 2014, la solución de inhabilitar las entradas vacías simplemente no está funcionando. Los campos desactivados también se envían en mi Google Chrome. Sin embargo, traté de eliminar el atributo "nombre" y funcionó bien.

$('form').submit(function(){ 
    $(this).find('input[name], select[name]').each(function(){ 
     if (!$(this).val()){ 
      $(this).removeAttr('name'); 
     } 
    }); 
}); 

Actualización: Ok, probablemente la razón porque la desactivación campos no trabajados a mí, no es que algo cambiado desde 2010. Pero aún no funciona en mi Google Chrome. No sé, tal vez solo esté en la versión de Linux. De todos modos, creo que eliminar el nombre attr es mejor ya que, a pesar de la política que adopta el navegador sobre los campos deshabilitados, no hay forma de enviar los parámetros si falta el nombre attr. Otra ventaja es que, por lo general, los campos que inhabilitan implican algunos cambios de estilo, y no es agradable ver un cambio de estilo en el formulario un segundo antes de que finalmente se envíe el formulario. También hay un inconveniente, como mencionó Max Williams en los comentarios, ya que la solución remove name attr no se puede alternar. Aquí es una manera de evitar este problema:

$('form').submit(function(){ 
    $(this).find('input[name], select[name]').each(function(){ 
     if (!$(this).val()){ 
      $(this).data('name', $(this).attr('name')); 
      $(this).removeAttr('name'); 
     } 
    }); 
}); 

function recoverNames(){ 
    $(this).find('input[name], select[name]').each(function(){ 
     if ($(this).data('name')){ 
      $(this).attr('name', $(this).data('name')); 
     } 
    }); 
} 

Sin embargo, creo que este no es un caso muy común, ya que estamos presentando la forma lo que se supone que no hay necesidad de recuperar los nombres de attrs que faltan.

+1

Uso Chrome y deshabilitar las entradas de una forma significa que no se envían. No creo que esto haya cambiado desde 2010. El problema al hacerlo mediante la eliminación del atributo de nombre es que no se puede alternar, es decir, una vez que has eliminado el nombre no puedes volver a agregarlo, a menos que lo hayas guardado en algún lugar . –

1

O serializar, clave vacío = pares de valores claros con expresiones regulares y llame window.location:

$("#form").submit(function(e){ 
    e.preventDefault(); 
    //convert form to query string, i.e. a=1&b=&c=, then cleanup with regex 
    var q = $(this).serialize().replace(/&?[\w\-\d_]+=&|&?[\w\-\d_]+=$/gi,""), 
    url = this.getAttribute('action')+ (q.length > 0 ? "?"+q : ""); 
    window.location.href = url; 
}); 
Cuestiones relacionadas