Subpanels

En el anterior post hice una preview (y breve introducción) de una funcionalidad que me ha resultado útil en una aplicación web y espero lo sea en otras. Se trata de subpaneles que permiten agregar elementos durante la carga de otros elementos, por ejemplo permiten agregar Categorías durante el alta de un Libro, o Tiendas durante la carga de una Compra, o Ciudades en Provincias en Países durante la carga de un Cliente, etc.

Algunas características

  • Carga de subforms asincrónica y solo cuando se abre el subpanel (ajax).
  • Eventos para poder enlazar el subpanel con la página contenedora (callbacks).
  • Permite anidar subpaneles (recursive).
  • Integramente escrito con jquery y jquery-ui (client-side).

Usabilidad

Consideremos la siguiente pantalla:
subpanels-6
Cuando configuramos un subpanel, lo único que vemos es que se agrega un botón [+] a la pantalla, como el siguiente:
subpanels-1
Si presionamos este botón [+] se abrirá un subpanel que si estuviese vacío tendría un aspecto similar a:
subpanels-2
pero en nuestro caso tiene el contenido de la url configurada y se ve como el siguiente:
subpanels-5
cuando hagamos el POST del form del subpanel este se procesará, luego se llamará a la función configurada como success (si es que hay una) y, a menos que esta devuelva false, cerrará el subpanel. La función configurada como success recibirá como parámetro la respuesta del POST al servidor y se puede utilizar para mostrar mensajes de validación, actualizar otros controles enlazados al subpanel, etc.

Código

Veamos como logramos estos, considerando la primer imagen de este post, el html contendría algo parecido a lo siguiente:

<body>
  <div class='ui-widget ui-state-default ui-corner-all'>
    <div class='ui-widget-content ui-corner-all'>
      <h1>Compra de libros</h1>
      <form action='/compra' method='POST'>
        <p style="display: inline">Vendedor: 
        <select id="vendedor" name="vendedor" style="vertical-align: top;">
        </select>
        <div id="pnvendedor" style="display: inline"></div></p>
        <p>Fecha: <input id='fecha' name='fecha' type="text" /></p>
        <p style="display: inline">Libro: 
        <select id="libro" name="libro" style="vertical-align: top;">
        </select>
        <div id="pnlibro" style="display: inline"></div></p>
        <p>Cantidad: <input name='cantidad' type="text" /></p>
        <p><input type='submit' value='Guardar'/></p>
      </form>
    </div>
  </div>
</body>
como podemos observar, seguido al elemento select para el combo de vendedor (o de libro) tenemos un div donde se configurará nuestro subpanel. En estos divs se cargaran los botones [+] y [-] que abrirán y cerrarán el panel respectivamente.
para que un div se transforme en un subpanel debemos llamar a la función subpanel(…) como muestra el siguiente código:
$("#pnvendedor").subpanel({ 
  url: 'vendedor.html',
  success: function(data) { addToSelectElement($("#vendedor"), data); },
  imageLoding: '/css/loader.gif'
});
en este código estamos seleccionado el div cuyo id es pnvendedor y transformándolo en un subpanel, cuyo contenido está dado por vendedor.html y se invocará a la función addToSelectElement luego de que el POST del form del subpanel (es decir el subform) sea compleado.

Subpaneles anidados

También podemos anidar subpaneles, en el ejemplo, al abrir el subpanel de Libro tiene otro [+] para agregar Categoría:
subpanels-3
que cuando se presiona en este [+] se abre el otro subpanel  para agregar una Categoría.
subpanels-4

Descargas:

Archivos para usar los subpanels en cualquier sitio (solo js y css)
Archivos del entorno de desarrollo (incluye tests con qunit y servidor con node.js)
Código del ejemplo (incluye html y servidor en node.js)

Subpaneles – Preview

Sistema de subpaneles (o subformulario) que funcionan del lado del browser comunicándose mediante request asincrónicos al servidor (ajax). Originalmente fue desarrollado y usado en el sitio de la comunidad alt.net hispano. Luego generalizado en este ejemplo, testeado con qunit y con node.js del lado del servidor.
Unable to display content. Adobe Flash is required.
El código es algo como:
$("#pnvendedor").subpanel({
                    successful: function(data) { addToSelectElement(data, $("#vendedor")); },
                    imageLoding: "/css/loader.gif"
                    url: "vendedor.html" 
                });
donde pnvendedor es un contendor (div) donde se ubicarán los botones [+] y [–], por ejemplo:
<div id="pnvendedor" style="display: inline"></div>

Ir al post de subpanels