Manipulación de datos en AJAX mediante el control ModalPopupExtender (y II)
En la primera entrega de este artículo abordamos el desarrollo de un servicio WCF que permitía a los elementos de un control AJAX el acceso básico a la tabla Shippers de la base de datos Northwind, en esta segunda parte continuaremos con el resto de operaciones de edición necesarias para implementar un mantenimiento de datos sobre dicha tabla.
Métodos del servicio que reciben parámetros
La siguiente tarea a desarrollar consistirá en obtener el registro de la tabla Shippers relacionado con el elemento del DropDownList seleccionado por el usuario; para ello necesitamos añadir al servicio WSDatos un método que reciba como parámetro el valor del campo ShipperID a buscar, y que devuelva dicho registro como resultado.
[OperationContract]
public Shipper ObtenerShipper(int nShipperID)
{
SqlConnection cnConexion = new SqlConnection(
ConfigurationManager.ConnectionStrings["CadConexion"].ConnectionString);
SqlCommand cmdComando = new SqlCommand("SELECT * FROM Shippers WHERE ShipperID = @ShipperID",
cnConexion);
cmdComando.Parameters.AddWithValue("@ShipperID", nShipperID);
cnConexion.Open();
SqlDataReader drReader = cmdComando.ExecuteReader(CommandBehavior.SingleRow);
drReader.Read();
Shipper oShipper = new Shipper((int)drReader["ShipperID"],
drReader["CompanyName"].ToString(),
drReader["Phone"].ToString());
cnConexion.Close();
return oShipper;
}
Como hemos dicho, este método del servicio será llamado desde la página Web cada vez que se realice una nueva selección en el control ddlShippers, es decir, al producirse su evento cliente onchange. Puesto que se trata de un control de servidor, la manera más adecuada de asociar uno de sus eventos cliente con el nombre de la función Javascript que ejecutará, es desde el code-behind de la página -en el evento Load por ejemplo-, empleando su colección Attributes, como vemos a continuación.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.ddlShippers.Attributes.Add("onchange", "ddlShippers_onchange()");
}
}
Pasando al bloque Javascript del WebForm, en la función ddlShippers_onchange llamaremos a este nuevo método del servicio, pasándole como primer parámetro el valor del elemento seleccionado en la lista desplegable, y como segundo el nombre de la función que será llamada si la ejecución del método tiene éxito; en dicha función recibiremos como parámetro el objeto Shipper seleccionado, pasando los valores de sus propiedades a los controles TextBox del cuadro de diálogo.
<script type="text/javascript" language="javascript"> 1:
2: //....
3: function ddlShippers_onchange()
4: { 5: WSDatos.ObtenerShipper(document.getElementById("ddlShippers").value, 6: ObtenerShipperCompleted);
7: }
8:
9: function ObtenerShipperCompleted(oShipper)
10: { 11: document.getElementById("txtCompanyName").value = oShipper.CompanyName; 12: document.getElementById("txtPhone").value = oShipper.Phone; 13: }
</script>
En la siguiente figura podemos apreciar un ejemplo de este caso.

Al pulsar el botón btnAceptar del diálogo, traspasaremos los valores elegidos al formulario principal; para ello, tendremos que asignar a la propiedad OnOkScript del ModalPopupExtender, el nombre de la función Javascript que se encargará de dicha tarea.
<cc1:ModalPopupExtender ID="mpeShippers" runat="server"
….
OnOkScript="mpeShippers_OnOk()" />
//....
<script type="text/javascript" language="javascript">
//....
function mpeShippers_OnOk()
{
document.getElementById("txtTransportista").value = document.getElementById("txtCompanyName").value + '-' +
document.getElementById("txtPhone").value;
}
//....

Métodos del servicio para la edición de datos. Insertar, modificar y borrar
El resto de métodos que nos queda por escribir son aquellos relacionados con las operaciones de edición sobre la tabla Shippers. Al igual que en los anteriores casos, en primer lugar añadiremos estos métodos al servicio, como vemos en el siguiente código fuente.
[OperationContract]
public void InsertarShipper(string sCompanyName, string sPhone)
{
SqlConnection cnConexion = new SqlConnection(
ConfigurationManager.ConnectionStrings["CadConexion"].ConnectionString);
SqlCommand cmdComando = new SqlCommand("INSERT INTO Shippers VALUES (@CompanyName, @Phone)",
cnConexion);
cmdComando.Parameters.AddWithValue("@CompanyName", sCompanyName);
cmdComando.Parameters.AddWithValue("@Phone", sPhone);
cnConexion.Open();
cmdComando.ExecuteNonQuery();
cnConexion.Close();
}
[OperationContract]
public void ModificarShipper(int nShipperID, string sCompanyName, string sPhone)
{
SqlConnection cnConexion = new SqlConnection(
ConfigurationManager.ConnectionStrings["CadConexion"].ConnectionString);
string sSQL = "UPDATE Shippers ";
sSQL += "SET CompanyName = @CompanyName, ";
sSQL += "Phone = @Phone ";
sSQL += "WHERE ShipperID = @ShipperID";
SqlCommand cmdComando = new SqlCommand(sSQL, cnConexion);
cmdComando.Parameters.AddWithValue("@CompanyName", sCompanyName);
cmdComando.Parameters.AddWithValue("@Phone", sPhone);
cmdComando.Parameters.AddWithValue("@ShipperID", nShipperID);
cnConexion.Open();
cmdComando.ExecuteNonQuery();
cnConexion.Close();
}
[OperationContract]
public void BorrarShipper(int nShipperID)
{
SqlConnection cnConexion = new SqlConnection(
ConfigurationManager.ConnectionStrings["CadConexion"].ConnectionString);
string sSQL = "DELETE FROM Shippers ";
sSQL += "WHERE ShipperID = @ShipperID";
SqlCommand cmdComando = new SqlCommand(sSQL, cnConexion);
cmdComando.Parameters.AddWithValue("@ShipperID", nShipperID);
cnConexion.Open();
cmdComando.ExecuteNonQuery();
cnConexion.Close();
}
Como detalle aclarativo para el método InsertarShipper, recordemos que el campo ShipperID de la tabla Shippers es autonumérico, por lo que no es necesario calcular el valor para dicho campo al insertar un nuevo registro en la tabla.
A continuación pasaremos al código de marcado de la página Web, asignando al evento onclick de los botones correspondientes, el nombre de la función que realizará la operación de edición pertinente.
….
<input id="btnInsertar" type="button" value="Insertar" onclick="btnInsertar_onclick()" />
….
<input id="btnModificar" type="button" value="Modificar" onclick="btnModificar_onclick()" />
….
<input id="btnBorrar" type="button" value="Borrar" onclick="btnBorrar_onclick()" />
….
Solamente queda ya, escribir las funciones Javascript que realizarán las llamadas a los métodos de edición del servicio WCF, como se muestra en el siguiente bloque de código.
<script type="text/javascript" language="javascript"> 1:
2: //....
3: function btnInsertar_onclick()
4: { 5: WSDatos.InsertarShipper(document.getElementById("txtCompanyName").value, 6: document.getElementById("txtPhone").value, 7: InsertarShipperOnSuccess);
8:
9: LimpiarCargarCombo();
10: }
11:
12: function InsertarShipperOnSuccess()
13: { 14: alert("Registro añadido"); 15: }
16:
17: function btnModificar_onclick()
18: { 19: var ddlShippers = document.getElementById("ddlShippers"); 20:
21: WSDatos.ModificarShipper(ddlShippers.value,
22: document.getElementById("txtCompanyName").value, 23: document.getElementById("txtPhone").value); 24:
25: LimpiarCargarCombo();
26: }
27:
28: function btnBorrar_onclick()
29: { 30: var resultado = confirm("¿Seguro que quiere borrar?"); 31:
32: if (resultado == true)
33: { 34: var ddlShippers = document.getElementById("ddlShippers"); 35:
36: WSDatos.BorrarShipper(ddlShippers.value);
37:
38: LimpiarCargarCombo();
39: }
40: }
41:
42: function LimpiarCargarCombo()
43: { 44: document.getElementById("txtCompanyName").value = ""; 45: document.getElementById("txtPhone").value = ""; 46:
47: var ddlShippers = document.getElementById("ddlShippers"); 48:
49: while (true)
50: { 51: if (ddlShippers.length == 0)
52: { 53: break;
54: }
55: else
56: { 57: ddlShippers.remove(0);
58: }
59: }
60:
61: WSDatos.ObtenerShippers(ObtenerShippersCompleted);
62: }
</script>
Y tras este conjunto de operaciones podemos dar por concluida la segunda entrega del artículo, en el que hemos ilustrado una técnica que permite a un control AJAX acceder y manipular una tabla existente en una base de datos desde código Javascript.
Para poder realizar las pruebas necesarias, al igual que en la primera parte, el código fuente queda disponible en los siguientes enlaces: C# y VB. Espero que os resulte interesante
Un saludo.