Nuevo Formulario para ASP.net

Acabo de terminar un Extender Control que permite transformar cualquier table HTML en un formulario con todas las funcionalidades necesarias para actualizar nuestras tablas de SQL. Todo esto, por supuesto, sin realizar un solo Postback. Les dejo un ejemplo de uso y la librería para que se bajen.

Siempre es un problema hacer un control Formulario que sirva para todo, se adapte a todas las circunstancias y ademas sea fácil de programar. El principal desafío es sincronizar los datos con los controles que los muestran según la acción que se está ejecutando (alta, baja, modificacion …) y ademas hacerlo de una manera sencilla.
Nunca me gustó el asunto de los Templates que se usan en el FormView de ASP.net. Había que definir un montón de elementos nuevos (EditItemTemplate,InsertItemTemplate, etc.), con propiedades nuevas y definiciones complejas. Y si además el formulario se sale un poco de lo común, bueno … mejor ni hablar.

Quería que los usuarios de este control no tuvieran que lidiar con esos problemas, así que definí tres o cuatro reglas básicas y trabajé con los objetos mas conocidos de HTML.

Tendremos que contar mínimamente con un ProveedorDatosServidor , un table de HTML y nuestro Formulario, que es en realidad un Extender Control.
Para probar este control aproveché el ejemplo de la Grilla y le sume una table y un Formulario. Quedó así:

 <form id="form1" runat="server" style="background-color: #aaaaaa">
    <MM2:ScriptManager ID="ScriptManager" runat="server">
    </MM2:ScriptManager>
    <MM2:ProveedorDatosServidor ID="Employees" runat="server" WebMethod="ManejoEmployees">
        <Ordenes>
            <MM2:OrdenDatos Columna="LastName"></MM2:OrdenDatos>
            <MM2:OrdenDatos Columna="Title"></MM2:OrdenDatos>
        </Ordenes>
    </MM2:ProveedorDatosServidor>

   <center>
        <table style="background-color: #aaaaaa">
            <tr>
                <td>
                    <div style="width: 100%; height: 100%; padding: 30px; display: inline">
                        <table class="Employ">
                            <tr>
                                <td id="Employees_Orden_LastName" class="ColumnaOrdenada">
                                    Ordenar por Apellido
                                </td>
                                <td runat="server" id="Employees_Orden_Title" class="ColumnaOrdenada">
                                    Ordenar por Titulo
                                </td>
                                <td>
                                </td>
                            </tr>
                            <tr>
                                <td colspan="2">
                                    <table class="Employ" id="TablaEmployees">
                                        <tr>
                                            <td>
                                                <table style="height: 550px">
                                                    <tr runat="server" id="RegistroEmployees" class="FilaEmploy">
                                                        <td>
                                                            <table>
                                                                <tr>
                                                                    <td>
                                                                        <img id="Employees_PhotoPath" runat="server" height="50" width="50" src="" alt="Sin Imagen" />
                                                                    </td>
                                                                    <td>
                                                                        <table>
                                                                            <colgroup>
                                                                            </colgroup>
                                                                            <colgroup style="background-color: #757575">
                                                                            </colgroup>
                                                                            <colgroup>
                                                                            </colgroup>
                                                                            <colgroup style="background-color: #757575">
                                                                            </colgroup>
                                                                            <colgroup>
                                                                            </colgroup>
                                                                            <colgroup style="background-color: #757575">
                                                                            </colgroup>
                                                                            <tr>
                                                                                <td>
                                                                                    Apellido:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_LastName">
                                                                                </td>
                                                                                <td>
                                                                                    Pais:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_Country">
                                                                                </td>
                                                                                <td>
                                                                                    Teléfono:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_HomePhone">
                                                                                </td>
                                                                            </tr>
                                                                            <tr>
                                                                                <td>
                                                                                    Nombre:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_FirstName">
                                                                                </td>
                                                                                <td>
                                                                                    Ciudad:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_City">
                                                                                </td>
                                                                                <td>
                                                                                    Nacimiento:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_BirthDate">
                                                                                </td>
                                                                            </tr>
                                                                            <tr>
                                                                                <td>
                                                                                    Titulo:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_Title">
                                                                                </td>
                                                                                <td>
                                                                                    Dirección:
                                                                                </td>
                                                                                <td style="width: 200px" id="Employees_Address">
                                                                                </td>
                                                                                <td>
                                                                                    Mail:
                                                                                </td>
                                                                                <td style="width: 200px" id="Td1">
                                                                                    <a id="Employees_Mail">Enviar</a>
                                                                                </td>
                                                                            </tr>
                                                                        </table>
                                                                    </td>
                                                                </tr>
                                                                <tr>
                                                                    <td colspan="3">
                                                                        <table>
                                                                            <colgroup>
                                                                            </colgroup>
                                                                            <colgroup>
                                                                            </colgroup>
                                                                            <tr>
                                                                                <td style="width: 93px; text-align: center">
                                                                                    Notas:
                                                                                </td>
                                                                                <td colspan="3" id="Employees_Notes" style="width: 700px">
                                                                                </td>
                                                                            </tr>
                                                                        </table>
                                                                    </td>
                                                                </tr>
                                                            </table>
                                                        </td>
                                                    </tr>
                                                </table>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td id="Info" style="text-align: left" class="CeldaInfo">
                                            </td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </div>
                </td>
                <td style="vertical-align: top">
                    <center>
                        <div style="border: solid 2px black">
                            <table style="background-color: #666666; height: 300px">
                                <colgroup style="background-color: #ffffff">
                                </colgroup>
                                <tr>
                                    <td>
                                        <input type="image" src="App_Themes\Tema\img\Botones\Agrega.gif" onclick="$find('Employees$Formulario').Mostrar('Al');return false" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <input type="image" src="App_Themes\Tema\img\Botones\Eliminar.gif" onclick="$find('Employees$Formulario').Mostrar('Ba');return false" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <input type="image" src="App_Themes\Tema\img\Botones\Editar.gif" onclick="$find('Employees$Formulario').Mostrar('Mo');return false" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <input type="image" src="App_Themes\Tema\img\Botones\Info.gif" onclick="$find('Employees$Formulario').Mostrar('Co');return false" />
                                    </td>
                                </tr>
                            </table>
                            <table id="Empleado_Mdl" style="-webkit-filter: drop-shadow(15px 15px 20px black);
                                color: Black; border: solid 1px black; background-color: White">
                                <colgroup style="width: 150px; background-color: lightblue">
                                </colgroup>
                                <colgroup style="width: 300px">
                                </colgroup>
                                <tr id="Empleado_AlDR">
                                    <td colspan="3" style="text-align: center; cursor: pointer">
                                        Alta
                                    </td>
                                </tr>
                                <tr id="Empleado_BaDR" style="text-align: center; cursor: pointer">
                                    <td colspan="3">
                                        Baja
                                    </td>
                                </tr>
                                <tr id="Empleado_MoDR" style="text-align: center; cursor: pointer">
                                    <td colspan="3">
                                        Modificacion
                                    </td>
                                </tr>
                                <tr id="Empleado_CoDR" style="text-align: center; cursor: pointer">
                                    <td colspan="3">
                                        Consulta
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <img id="Empleado__PhotoPath" runat="server" height="50" width="50" src="" alt="Sin Imagen" />
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMoFMFA_PhotoPath" size="60" />
                                        <span id="Empleado_BaCo_PhotoPath" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Apellido :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_LastName" size="60" />
                                        <span id="Empleado_BaCo_LastName" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Nombre :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_FirstName" size="60" />
                                        <span id="Empleado_BaCo_FirstName" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Titulo :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_Title" size="60" />
                                        <span id="Empleado_BaCo_Title" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Pais :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_Country" size="60" />
                                        <span id="Empleado_BaCo_Country" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Ciudad :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_City" size="60" />
                                        <span id="Empleado_BaCo_City" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Dirección :
                                    </td>
                                    <td>
                                        <input type="text" id="Empleado_AlMo_Address" size="60" />
                                        <span id="Empleado_BaCo_Address" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        Notas :
                                    </td>
                                    <td>
                                        <textarea rows="4" cols="60" id="Empleado_AlMo_Notes"></textarea>
                                        <span id="Empleado_BaCo_Notes" />
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="3">
                                        <table style="border: solid 1px black; width: 100%">
                                            <tr>
                                                <td style="text-align: center">
                                                    <input type="button" value="Aceptar" id="Empleado_AcFC" />
                                                </td>
                                                <td style="text-align: center">
                                                    <input type="button" value="Cancelar" id="Empleado_AlMoBaCaFB" />
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </center>
                </td>
            </tr>
        </table>
    </center>
    <MM2:Formulario runat="server" ID="Empleado" TargetControlID="Employees" Mostrado=""
        Cancelado="" Aceptado="Aceptado"></MM2:Formulario>
    <MM2:Grilla runat="server" ID="GrillaEmployees" TargetControlID="RegistroEmployees"
        Filas="4" IDDatos="Employees" IdCeldaInfo="Info" Seleccionado="">
    </MM2:Grilla>
</form>

Lo agregado al ejemplo anterior va de las lineas 144 a 289.
Mirándolo de cerca veremos que los controles dentro de la table e incluso esta tienen ids algo raros. Pues bien, lo descubrieron… La funcionalidad de cada control esta dada por su id.

Las reglas son las siguientes.

1. Cada objeto en la pagina cuyo id comience con el id del Formulario, pasará a ser tenido en cuenta por este último. O sea: extenderá su comportamiento. En nuestro ejemplo el Formulario se llama Empleado, por lo tanto, si queremos que un control participe en el funcionamiento de este, deberá llevar Empleado como primera palabra de su id.

2. Seguido de un guión bajo se debe especificar la/s función/es que cumplirá este control. Esta función será designada por ciertas letras que paso detallar.

De visibilidad: (cualquier objeto que tenga la propiedad style.display)
Al: Será visible cuando el formulario se invoque en modo Alta.
Ba: Será visible cuando el formulario se invoque en modo Baja.
Co: Será visible cuando el formulario se invoque en modo Consulta.
Mo: Será visible cuando el formulario se invoque en modo Modificación.

Se pueden concatenar entre si y con otras opciones. Si no se especifica ninguno el control sera visible siempre.

De Foco: (solo objetos con capacidad de recibir foco)
FA: Obtendrá el foco cuando el formulario se invoque en modo Alta.
FB: Obtendrá el foco cuando el formulario se invoque en modo Baja.
FC: Obtendrá el foco cuando el formulario se invoque en modo Consulta.
FM: Obtendrá el foco cuando el formulario se invoque en modo Modificación.

Se pueden concatenar entre si y con otras opciones.

De Drag&Drop: (cualquier objeto que acepte el eventos de mouse)
DR: Control desde el cual el usuario puede tomar el Formulario y moverlo por la pantalla.

Se pueden concatenar con otras opciones y solo funciona cuando existe un control marcado con la opción Mdl.

De Modalidad: (cualquier objeto contenedor)
Mdl: control contenedor que se mostrará en forma Modal anulando de esta manera el click de todo lo que este por fuera de este.

Generalmente va solo y no es obligatorio.

De Accion: (cualquier objeto que acepte el evento click del mouse)

Ca: Cuando se hace click sobre este objeto se descartaran los cambios hechos en el formulario.
Ac: Cuando se hace click sobre este objeto se Aceptarán los cambios hechos en el formulario enviándolos al servidor.

Se pueden concatenar con otras opciones.

3. Seguido de otro guión bajo va el nombre del campo que deseamos mostrar en ese control. Los nombres de los campos vienen del ProveedorDatosServidor que esta relacionado con nuestro formulario a través de la propiedad TargetControlID. Si no especificamos esta parte, el control no mostrará ningún dato y solo se comportará de acuerdo a lo que hayamos escrito en la sección anterior.

Veamos unos ejemplos:

<input type=”text” id=”Empleado_AlMoFMFA_PhotoPath” size=”60″ />

Este input será visible cuando el formulario se invoque en modo Alta o Modificación. Y obtendrá el foco como en ambos casos, a la vez que estará enlazado al campo PhotoPath, permitiendo su modificación.

<input type=”button” value=”Cancelar” id=”Empleado_AlMoBaCaFB” />

Este botón será visible en modo Alta, Modificación y Baja. Servirá para cancelar las modificaciones hechas en el formulario y tendrá el foco cuando se invoque el formulario en modo Baja.

<table id="Empleado_Mdl" ……

Esta tabla sera hará visible en forma modal cuando se invoque cualquier acción del formulario.

<tr style=”text-align:center;cursor:pointer;”>

Este tr será visible solo en modo Modificación y permitirá la funcionalidad de drag&drop para el objeto marcado con Mdl.

Como vemos no es obligatorio que exista una tabla o contenedor que contenga todos los controles. Estos pueden estar dispersos en cualquier parte de la página, lo que nos da mucha libertad a la hora de diseñar nuestro formulario.
También podemos usar mas de un control para mostrar el mismo campo de diferentes maneras. Es el caso del PhotoPath de nuestro ejemplo.
El formulario posee además un función para asignar valores de campos a controles de acuerdo al tipo de control y tipo de campo. O sea, reconoce ambos valores y los asigna de manera inteligente. De todas maneras, si la forma en que el formulario asigna los valores no es la de tu preferencia, podrías capturar el evento Mostrando y asignar el valor que quieras a la propiedad del control que quieras.

Siguiendo con el ejemplo vemos cuatro botones con el evento click capturado:

<input type=”image” src=”App_Themes\Tema\img\Botones\Agrega.gif” onclick=”$find(‘Employees$Formulario’).Mostrar(‘Al’);return false” />

Este es uno de ellos y nos sirve para invocar la aparición del formulario en modo Alta. Lo hacemos buscando nuestro formulario como component de Sys.Application con el comando $find(TargetControlID$Formulario), e invocando el método Mostrar con el parámetro “Al”. Luego retornamos false para que no se produzca el postback.

Los parámetros permitidos para este método son :
Al :Alta
Ba: Baja
Mo: Modificación
Co: Consulta

Hasta aquí la programación del formulario en si. Ahora veremos el funcionamiento de la página y la interacción de los controles.

Todo comienza con el ProveedorDatosServidor que alimenta simultaneamente nuestra Grilla y Formulario.
Al movernos en la Grilla estamos cambiando el registro actual del ProveedorDatosServidor. El Formulario siempre muestra el registro actual del ProveedorDatosServidor, así que nos quedan perfectamente sincronizado. Esta es la ventaja de usar un mismo ProveedorDatosServidor para ambos controles.Si usáramos uno diferente para cada uno deberíamos mover el registro “a mano” para que el Formulario muestre lo que queramos.

Por último deberemos programar en el servidor la actualización de la tabla SQL, usando el WebMethod de nuestro ProveedorDatosServidor, ya que el Formulario invoca las funciones de Agregar, Eliminar y Modificar de este último.

 <WebMethod()> _
 Public Shared Function ManejoEmployees(ByVal pContrato As MoniMisi2.ProveedorDatosServidor.Contrato) As MoniMisi2.ProveedorDatosServidor.Contrato
    Dim Contrato As MoniMisi2.ProveedorDatosServidor.Contrato = pContrato

    If Contrato.Operacion.Nombre = "Leer" Then
      Contrato = ProveedorDatosServidor.LeerFilas(Contrato, ReglaEmploy.ConsultaTodo(pContrato.Orden))
    End If
  
    If Contrato.Operacion.Nombre = "Modificar" Then
      'Asi obtenemos los valor anteriores a la modificación y los valores nuevos
      Dim Viejo As Dictionary(Of String, Object) = pContrato.Operacion.Valor("RegistroAnterior")
      Dim Nuevo As Dictionary(Of String, Object) = pContrato.Operacion.Valor("RegistroActual")

      'Asi obtenemos el valor de cada campo
      Dim Apellido As String = Nuevo("LastName")
      Dim ApellidoAnterior As String = Viejo("LastName")
      Dim Nombre As String = Nuevo("FirstName")
      '' Etc.

      ''Podríamos comparar si hubo algun cambio o validar los datos
      ''Si esta todo bien deberímos usar nuestra forma preferida de actualizar la tabla SQL.

    End If

    If Contrato.Operacion.Nombre = "Eliminar" Then
      ' La opcion de Eliminar solo envia los datos anteriores.
      Dim Viejo As Dictionary(Of String, Object) = pContrato.Operacion.Valor("RegistroAnterior")

      Dim Apellido As String = Viejo("LastName")
      '' Etc.

      ''Eliminar el registro en SQL despues de validar.
    End If

    If Contrato.Operacion.Nombre = "Agregar" Then
      ' La opcion de Agregar solo envia los datos Nuevos.
      Dim Nuevo As Dictionary(Of String, Object) = pContrato.Operacion.Valor("RegistroActual")

      Dim Apellido As String = Nuevo("LastName")
      '' Etc.

      ''Agregar el registro en SQL despues de validar.
    End If


    Return Contrato

  End Function

Para terminar, deberíamos refrescar nuestra grilla para que refleje los cambios hechos en nuestra tabla.
Para eso capturaremos el evento Aceptado del Formulario invocando la siguiente función.

 function Aceptado(sender, e) {
       $find("RegistroEmployees$Grilla").Refrescar();
 }

Aquí simplemente ganamos acceso a la Grilla con la función $find e invocamos el método Refrescar().

¿ El stylesheet del Formulario ?. No es más ni menos que el de una table, así que lo definimos de manera tradicional.

A mi me quedó así.

Bajate la Librería MoniMisi2 e incluila en tu proyecto.

Anuncios

3 Respuestas a “Nuevo Formulario para ASP.net

  1. Pingback: Nuevo control para edición de números enteros y decimales. | MoniMisi

  2. Pingback: Nuevo Combo enlazado a Datos | MoniMisi

  3. Pingback: Nuevo Combo con múltiples columnas para ASP.Net | MoniMisi

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s