Blog de sonicbyte

Opinión y tendencias sobre negocios, diseño y avances en Internet

Formulario por pasos usando Mootools

25 octubre, 2011
form

En nuestro último proyecto e-commerce para el proceso de finalización de compra optamos por utilizar un formulario por pasos. Esta decisión fue tomada para no cansar al visitante con extensos e interminables formularios con un sinfín de campos que no alientan a ser rellenados. Además la interfaz queda bonita y el efecto al ir rellenando los pasos también es agradable para el visitante.

Pero una de las mayores ventajas es que la validación del formulario se realiza en cada etapa, por lo que el visitante puede corregir algún campo mal ingresado sin tener que esperar a rellenar todos los pasos. Esto le da una agilidad al proceso y genera confianza en el visitante.

Ver demo

Para la validación del formulario, en realidad cada etapa es un formulario en si, utilizamos el FormCheck de la librería MooFloor. Éste validador se ha convertido en nuestro favorito a lo largo de los proyectos. Esta librería requiere el core de Mootools 1.2.4 y del more 1.2.4.4 sólo la clase Fx.Scroll. También incluímos un archivo con las frases del validador en castellano salvo que se quiera que aparezcan los avisos en inglés, el idioma default. Es necesario incluir un archivo CSS para mostrar correctamente los avisos del validador. Este archivo se descarga junto con el plugin javascript en la misma página. Por lo tanto la inclusión de archivos para que funcione nuestro formulario por pasos de momento queda de la siguiente manera:

<script src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.5/mootools-yui-compressed.js"></script>

<script type="text/javascript" src="js/mootools-1.2.5.1-more.js"></script>

<script type="text/javascript" src="js/formcheck/lang/es.js"></script>

<script type="text/javascript" src="js/formcheck/formcheck.js"></script>

Para el efecto de transición entre los pasos utilizamos el plugin SlideShow de Ryan Florence. Un plugin para hacer carruseles bastante fácil de implementar y muy extendible. La clase requiere del core de Mootools y la clase Fx.Elements del more, también la clase Loop que se descarga en el mismo sitio del SlideShow. Por lo tanto dos nuevas línea se agrega a la inclusión de archivos:

<script type="text/javascript" src="ruta-archivos-js/slideshow/Loop.js"></script>

<script type="text/javascript" src="ruta-archivos-js/slideshow/SlideShow.js"></script>

El siguiente paso es crear las estructura del formulario. Para ello creamos un DIV contenedor que va a contener a las distintas etapas. Cada etapa va a ser un FORM que a su vez va a estar contenido en un DIV. Quedando una estructura así:

<div id="contenedor">
  <div id="etapa_1">
    <form id="form_1" action="#">
    ....
    </form>
  </div>
  <div id="etapa_2">
    <form id="form_2" action="#">
    ....
    </form>
  </div>
  .
  .
  <div id="etapa_n">
    <form id="form_n" action="#">
    ....
    </form>
  </div>
</div>

En esta entrada no explicaremos como validar los distintos tipos de campos, para ello pueden visitar los documentos de la librería MooFloor.

El siguiente paso es instanciar un validador para cada paso, por lo que cada formulario tendrá su propia instancia del validador. Las opciones de la clase deberán ser cambiadas un poco a las de una validación tradicional ya que no queremos que se envíe el formulario, sino pasar al siguiente paso.

Por lo tanto las instancias del validador tendrán la siguiente forma:

new FormCheck('form_1', {
  submit: false
});

new FormCheck('form_2', {
  submit: false
});

Al instanciar de este modo cada validador el formulario no es enviado pero sí le realiza el chequeo para comprobar que cada campo es correcto.

El siguiente paso es el de darle el efecto de transición para pasar al siguiente formulario cuando el chequeo es válido. Para ello debemos primero instanciar la clase SlideShow y luego decirle que hacer a cada formulario cuando el chequeo es válido:

var slideshow = new SlideShow('contenedor');

new FormCheck('form_1', {
  submit: false,
  onValidateSuccess: function () {
    slideshow.show($('etapa_2'), {
    transition: 'pushLeft'
    });
  }
});

new FormCheck('form_2', {
  submit: false,
  onValidateSuccess: function () {
    slideshow.show($('etapa_3'), {
    transition: 'pushLeft'
    });
  }
});

Instanciamos todos los pasos del formulario hasta llegar al último, en nuestro ejemplo el formulario ‘n’. Al validar el formulario ‘n’ se deben enviar todos los datos de los distintos pasos/formularios, para nuestro ejemplo los enviaremos mediante una llamada ajax. Recogemos la información de los distintos pasos para enviarlo como parámetro DATA en la llamada:

var slideshow = new SlideShow('contenedor');

new FormCheck('form_1', {
  submit: false,
  onValidateSuccess: function () {
    slideshow.show($('etapa_2'), {
    transition: 'pushLeft'
    });
  }
});

new FormCheck('form_2', {
  submit: false,
  onValidateSuccess: function () {
    slideshow.show($('etapa_3'), {
    transition: 'pushLeft'
    });
  }
});

..

new FormCheck('form_n', {
  submit: false,
  onValidateSuccess: function () {
    var datos = $('form_1').toQueryString() + '&' + $('form_2').toQueryString() + '&'...'&' + $('form_n').toQueryString();
    new Request({
      url: 'url_de_la_accion',
      data: datos,
      onSuccess: function (result) {
// acción resultado de el envío
      }
    }).send();
  }
});

Ver demo

Puedes ver todo el código en github.

Espero que les guste el post. Hasta la próxima.

Comentarios: 5
Tags:
  • ajay

    can you tell me how to sen all forms simultaneously, I want a single form show in multi page not different forms, or a single complete section in multi page, I have study your code but in there are three different forms, please Provide a solution I need it urgently, thanks

  • Juan

    Hola, estoy intentando adaptar este formulario y me funciona perfectamente con radios, checkbox, etc. El resultado lo envío por email.

    Me encuentro con un problema ahora, estoy intentando adjuntar un archivo y este no se envía con el email (el código que uso es de otro formulario y me unciona sin problema).
    Teneis experiencia de haber adjuntado archivos con este formulario/libreria?
    Saludos!

    • Enric

      Hola Juan, gracias por interesarte en el post!

      Al ser enviado por ajax el formulario los archivos no pueden ser enviados de la forma tradicional con el “multipart/form-data”. Por lo que hay algunas soluciones dando vueltas por ahí. Algunas usan flash, otras un iframe oculto y otras HTML5… y varias combinan estos métodos según el caso.

      Específicamente, en este proyecto, utilizamos un uploader que va muy bien http://digitarald.de/project/fancyupload/ es fácil de implementar. Cualquier cosa consulta nuevamente ;)

      Suerte, saludos

      • Juan

        Gracias a vosotros por el código y las muy buenas explicaciones.
        En pocos días me pondré a probar lo que me comentas, tiene muy buena pinta.

        Ahora estoy inetntando añadir campos que dependen de la seleción del usuario, por ejemplo:
        ¿Cuantos gatos tienes? si pone en un select 3, le aparezcan 3 inputs para añadir sus nombres (obligatorios), si pone 5, que le aparezcan 5 inputs (si pone más de 20 le mandamos un aviso de que tiene un problema… : p).

        Ya os mantandré informados de los avances por si un futuro lector tiene las mismas inquietudes.

        Si conoceis algún código compatible con lo que os comento, será muy bienvenido.

        Gracias de nuevo por todo

      • Juan

        Hola Enric, Ya solventé el tema que te hablaba hace unos días de campos Select dependientes. Funciona correctamente en vuestro formulario y lo que es más importante en todos los navegadores/dispositivos.

        Usé unos div en display none/block. Si a alguien le interesa el código, lo puedo postear sin problema.

        Ahora estoy empezando con el apartado de adjuntar imágenes.

        He empezado pro aqui http://digitarald.de/project/fancyupload/3-0/showcase/attach-a-file/ como me recomendaste ya que con solo adjuntar una imagen, en mi proyecto es más que suficiente.

        Adjunto los .js necesarios, y los intento cargar en el formulario usando “” pero no logro que se adjunte ni que se envíe al email.

        He buscado algún código de ejemplo para tener una pauta, pero no logro ver nada.

        Si sabes donde puedo estar errando o conoces algún ejemplo en el que me pueda basar, sería de gran ayuda.

        De nuevo, de verdad, gracias por todo.