Scour Design. Tutoriales de Flash, ActionScript, CSS, Photoshop, ImageReady...

\n"; } } } lecturas();

          


Ajax en asp.net (Visual C#)

      

Autor: Carlos Carmona

Para empezar, una pequeña explicación sobre qué es AJAX (con el permiso de la wikipedia).

AJAX
AJAX, acrónimo de Asynchronous JavaScript And XML (en inglés «JavaScript y XML asíncronos»). Técnica de desarrollo web para crear aplicaciones interactivas mediante la combinación de tres tecnologías ya existentes:

  • HTML (o XHTML) y Hojas de Estilo en Cascada (CSS) para presentar la información;
  • Document Object Model (DOM) y JavaScript, para interactuar dinámicamente con los datos, y
  • XML y XSLT, para intercambiar y manipular datos de manera desincronizada con un servidor web (aunque las aplicaciones AJAX pueden usar otro tipo de tecnologías, incluyendo texto plano, para realizar esta labor).

Como el DHTML o LAMP, AJAX no constituye una tecnología en sí, pero es un término que engloba a un grupo de éstas que trabajan conjuntamente.

En otras palabras, AJAX permite, mediante la suma de las citadas tecnologías, enviar y recibir datos entre cliente (navegador) y servidor sin provocar el refresco de la página, y sin tener que transferir aquel contenido estático (imágenes, maquetación de la web, menús, etc...) que consume ancho de banda innecesariamente.

En éste tutorial vamos a usar la librería libre de AJAX para Asp.NET para implementar un sistema de muestra de datos en una tabla (traidos de BD con un DataSet) con su correspondiente paginación y la capacidad de seleccionar filas y actualizarlas. Algo tal que así (lamento no poder mostrar activamente la aplicación aquí, pero este es un servidor Linux PHP - MySql) :

Sistema a implementar

Implementar AJAX en Asp.Net

Antes de entrar al tutorial en sí, vamos a ver cual es la forma genérica de utilizar ésta librería.

Teniendo en cuenta lo anterior, vamos con el ejercicio.

Si desea investigar más...

Nota
El código cuyo fondo es de color marrón es código CSharp (C#) de Servidor. El de fondo verde es código Cliente, ya sea JavaScript o Html.

1º Obtener la librería

La librería es libre, y podeis descargarosla o bajaros el proyecto de éste tutorial, que lógicamente ya trae la librería (implementada y funcional).

Volver al menú.

2º Crear la referencia a la librería

Agregar la referencia a la librería

Volver al menú.

3º Añadir una Cabecera a la declaración del Web.Config

Sencillamente, copiar y pegar el siguiente httpHandler:

  1. <configuration>
  2. <system.web>
  3. <httpHandlers>
  4. <add verb="POST,GET" path="ajax/*.ashx"
    type="Ajax.PageHandlerFactory, Ajax" />
  5. </httpHandlers>
  6. ...
  7. <system.web>
  8. </configuration>

Volver al menú.

4º Llamada a la Función

En el evento Page_Load hay que implementar la llamada a la función:

  1. private void Page_Load(object sender, EventArgs e)
  2. {
  3. Ajax.Utility.RegisterTypeForAjax(typeof(_Default));
  4. }

Como veis, se especifica como TypeOf la clase _Default, que es la clase del formulario por defecto que crear Visual Studio .NET. En cada formulario donde vayamos a utilizar AJAX deberemos poner por TypeOf la clase por defecto del formulario, que viene especificada al principio de cada página *.cs (página de código), es decir, si nuestra página es:

  1. public class Alta_Usuarios : System.Web.UI.Page

La llamada debería ser:

  1. private void Page_Load(object sender, EventArgs e)
  2. {
  3. Ajax.Utility.RegisterTypeForAjax(typeof(Alta_Usuarios));
  4. }

Ojo con esto si queremos evitarnos algún que otro dolor de cabeza. Además tendremos que usar el nombre de dicha clase para llamar a las funciones JavaScript que interactúen con el Servidor. Lo veremos más adelante.

Volver al menú.

5º Implementar las funciones en Servidor

Cada función que reciba peticiones por JavaScript desde cliente tiene la particularidad de que hay que añadirle el AjaxMethod(), por lo demás, es igual que cualquier otra función:

  1. [Ajax.AjaxMethod()]
  2. public tipo_dato_devuelto nombre_función(tipo_dato variable, tipo_dato_2 variable_2...)
  3. {
  4. //Operaciones
  5. return valor;
  6. }

Volver al menú.

6º Funciones en cliente (JavaScript)

Las funciones en JavaScript deben tener por nombre el mismo que la función de Servidor más "_CallBack" (Ojo con mayúsculas y minúsculas) . En lo que se refiere a los parámetros que recibirá, siempre será la variable "response", ya reciba un parametro o varios.

Por último, obtendremos el resultado de Servidor mediante "response.value" aun que hay otras formas, por ejemplo al trabajar con DataSet's, ya lo veremos.

  1. function nombre_funcion_en_servidor_CallBack(response){
  2. //Operaciones
  3. //Obtendremos los valores devueltos con
  4. //response.value, aaunque hay una forma
  5. //distinta si trabajamos con DataSet,
  6. //Más adelante lo veremos.
  7. }

Volver al menú.

7º Llamar a las funciones JavaScript en cliente

Una vez ya está todo implementado tanto en Cliente como en Servidor, necesitamos desencadenar el proceso, haciendo la llamada a la función JavaScript en el momento deseado, por ejemplo, en el click de un botón:

  1. <INPUT onclick="_Default.nombre_funcion_servidor(parámetro1, parámetro2, ...,
    parámetroN, nombre_funcion_servidor_CallBack);"

En el evento JavaScript deseado, por ejemplo, el evento onclick de un botón, (no confundir este evento onclick que es de JavaScript con un evento de Servidor, estamos en Cliente) ponemos, por este orden:

  1. La clase del formulario que pusimos en el TypeOf del evento Page_Load.
  2. Punto (por especificar que no quede...) .
  3. El nombre de la función de servidor que recibirá la petición, y entre paréntesis...
    1. Los parámetros que especificamos en la función de Servidor, en el mismo orden y...
    2. Por último, el nombre de la función JavaScript, escrita tal y como he especificado en el punto 6º.

Volver al menú.

Un ejemplo sencillo

Veamos un ejemplo muy básico de los puntos 5º a 7º... El usuario escribe 2 valores en 2 TextBox, los enviamos a servidor y devolvemos la suma de ambos. Suponiendo que los puntos 1º a 4º ya están cumplimentados (esos pasos son siempre igual...):

Creamos la función de servidor que recibirá y procesará las peticiones:

  1. [Ajax.AjaxMethod()]
  2. public string SumaValores(int firstNumber, int secondNumber)
  3. {
  4. return ("La suma de los valores " + firstNumber.ToString() + " y " +
    secondNumber.ToString() + " es igual a " + (firstNumber + secondNumber));
  5. }

La función de JavaScript:

  1. <script type="text/javascript">
  2. function SumaValores_CallBack(response){
  3. if (response.error != null){
  4. alert("Los valores introducidos no son válidos.");
  5. return;
  6. }
  7. target="contenido";
  8. document.getElementById(target).innerHTML = response.value;
  9. }
  10. </script>

Por último, necesitamos los 2 TextBox y el botón con la llamada a la función JavaScript:

  1. <STRONG>Valor 1º: </STRONG>
  2. <asp:textbox id="TextBox1" runat="server"></asp:textbox><BR>
  3. <STRONG>Valor 2º: </STRONG>
  4. <asp:textbox id="TextBox2" runat="server"></asp:textbox><BR>
  5. <INPUT onclick="_Default.SumaValores(TextBox1.value,TextBox2.value,
    SumaValores_CallBack);"
    type="button" value="Traer Datos">
  6. <!-- En el div 'contenido' insertaremos el resultado -->
  7. <div id="contenido"></div>

Y con esto ya tenemos operativo este sencillo sistema AJAX que comunicará con Servidor sin provocar el refresco de la página.

Volver al menú.

Funciones básicas de JavaScript para manejar AJAX.

Aunque esto no tiene nada que ver con Asp.Net ni con la librería de AJAX, si pretendemos trabajar con este sistema será imprescindible manejar algunas funciones de JavaScript para maquetar (CSS) los resultados que traigamos de Servidor.

getElementById()

Esta función sirve para localizar e interactuar con una etiqueta html o xhtml por su identificador (atributo id) , por ejemplo:

  1. //Dar estilos CSS
  2. document.getElementById("nombreCapa").style.visibility="visible";
  3. //Asignar un contenido
  4. document.getElementById("nombreCapa").innerHTML="Asignar contenido.";
  5. //Etc...
getElementsByTagName()

Funciona exáctamente igual que la anterior, con la excepción de que no afecta a un elemento concreto, sino a todas las etiquetas de un tipo. Por ejemplo:

  1. //Metemos todas las etiquetas "td" en un array
  2. var nodes = document.getElementsByTagName("td");
  3. //obtenemos el nº total de etiquetas "td" de la página
  4. var max = nodes.length;
  5. //Recorremos el array dándole estilos a las etiquetas
  6. for(var i = 0;i ) {
  7. var nodeObj = nodes.item(i);
  8. nodeObj.style.color = "#000000";
  9. nodeObj.style.background = "#FFFFFF";
  10. }
parseInt(), parseFloat() y parseText()

En JavaScript no se especifica el tipo de dato de las variables, y esto puede traer problemas, ya que muchas veces al escribir:

  1. var num1 = 2;
  2. var num2 = 4;
  3. midiv.innerHTML = "El resultado de sumar " + num1 + " más " + num2 + " es "
    + (num1 + num2);

Nos devuelve: "El resultado de sumar 2 más 4 es 24"... parece que algo ha sucedido mal. Evidentemente, JavaScript a interpretado que eran variables de texto y las ha concatenado.

Para esto y el caso contrario, tenemos estas 3 funciones, que fuerzan a JavaScript a interpretar la variable como un tipo u otro de dato.

Hay muchas más funciones que serían útiles, sin embargo este no pretende ser un tutorial de JavaScript, y con estas funciones podemos salir del paso.

Volver al menú.

El Tutorial. AJAX en Asp.Net

El ejercicio utiliza la Base de Datos NorthWind que es la que trae por defecto SQL Server 2000, así que solo tendreis que poner vuestro usuario y contraseña en las cadenas de conexión.

Me he permitido la libertad de añadir algunos ticks de DOM y CSS para ocultar filas de la tabla, colorearlas al pasar el ratón (y descolorearlas al salir) y dejar coloreada de un color distinto la fila que se está editando, de modo que aunque cambiemos de página, al regresar seguirá marcada. Algunos de estos ticks, en particular el de ocultar filas, no pretende hacer nada en concreto, simplemente es para aquellos que estén interesados y quieran ver como manipular CSS dinámicamente con DOM de JavaScript.

Realmente no hay mucho que explicar, las particularidades de la librería de AJAX ya están explicadas en los puntos anteriores, lo único que aún no hemos visto es como mostrar y maquetar los datos traidos de un DataSet.

Manipular y maquetar un DataSet en Cliente

El modo de trabajar con un DataSet mediante JavaScript una vez lo hemos traido de nuestra consulta a Servidor es practicamente identico a como se hace tradicionalmente:

  1. ds.Tables[numTabla].Rows[numFila].campoDB
  2. /* Donde:
  3. numTabla es la tabla que queremos manipular, ya que un DataSet puede llevar
    varias. Si solo hemos hecho una consulta, será 'cero' 0.
  4. numFila es el registro o tupla actual.
  5. campoDB es el nombre de la columna de la select que queremos mostrar. */

Evidentemente, si vamos a traer más de una fila, deberemos recorrer el DataSet con un bucle:

  1. //Obtenemos el DataSet con response.value
  2. //Y lo asignamos a una variable...
  3. var ds = response.value;
  4. //Recorremos el DataSet practicamente igual
  5. //que lo haríamos en Servidor.
  6. for(var i=0; i<ds.Tables[0].Rows.length; i++){
  7. alert(ds.Tables[0].Rows[i].Campo1);
  8. alert(ds.Tables[0].Rows[i].Campo2);
  9. alert(ds.Tables[0].Rows[i].Campo3);
  10. ...
  11. alert(ds.Tables[0].Rows[i].CampoN);
  12. }

Para maquetar los datos, la mejor solución es ir asignando los resultados en un array que finalmente volcaremos a un div:

  1. //Obtenemos el DataSet con response.value
  2. //Y lo asignamos a una variable...
  3. var ds = response.value;
  4. //Declaramos el array
  5. //Para meter los datos solo tendremos que asignarlos
  6. //y JavaScript se encarga automáticamente de incrementar
  7. //el indice en cada asignación, del siguiente modo:
  8. //s[s.length] = "valor como texto";
  9. //s[s.length] = "valor como texto2";
  10. //La segunda asignación no machacará la anterior,
  11. //ya que el índice del array se autoincrementa
  12. var s = new Array();
  13.  
  14. s[s.length] = "<table>";
  15. s[s.length] = "<tr><th>Campo 1º</th><th>Campo 2º</th></tr>";
  16.  
  17. for(var i=0; i<ds.Tables[0].Rows.length; i++){
  18. s[s.length] = "<tr>";
  19. s[s.length] = "<td>" + ds.Tables[0].Rows[i].Campo1 + "</td>";
  20. s[s.length] = "<td>" + ds.Tables[0].Rows[i].Campo2 + "</td>";
  21. s[s.length] = "</tr>";
  22. }
  23.  
  24. s[s.length] = "</table>";
  25.  
  26. //Volcamos el array a un div de id 'resultado'
  27. resultado.innerHTML = s.join("");

Volver al menú.

Funciones del lado Servidor

Salvando la declaración del AjaxMethod(), no difiere de lo de siempre...

  1. //Obtenemos los datos que rellenarán la tabla.
  2. [Ajax.AjaxMethod()]
  3. public DataSet GetDataSet()
  4. {
  5. SqlConnection conn = new SqlConnection("Data Source=localhost;User id=sa;
    Password=;Initial Catalog=northwind;"
    );
  6. SqlCommand cmd = new SqlCommand("SELECT Top 95 OrderID, ShipName,
    ShipAddress, ShipCity, ShipCountry FROM Northwind.dbo.Orders ORDER BY 1"
    , conn);
  7. SqlDataAdapter da = new SqlDataAdapter(cmd);
  8. DataSet ds = new DataSet();
  9. try
  10. {
  11. conn.Open();
  12. try
  13. {
  14. da.Fill(ds);
  15. }
  16. catch
  17. {
  18. return null;
  19. }
  20. finally
  21. {
  22. conn.Close();
  23. conn.Dispose();
  24. }
  25. }
  26. catch(Exception)
  27. {
  28. return null;
  29. }
  30. return ds;
  31. }
  32.  
  33. //obtenemos la fila que se va a editar
  34. [Ajax.AjaxMethod()]
  35. public DataSet SacarFila(string id)
  36. {
  37. SqlConnection conn = new SqlConnection("Data Source=localhost;User id=sa;
    Password=;Initial Catalog=northwind;"
    );
  38. SqlCommand cmd = new SqlCommand("select OrderID, ShipName, ShipAddress,
    ShipCity, ShipCountry FROM Northwind.dbo.Orders where OrderId = @id"
    , conn);
  39. cmd.Parameters.Add("@id",SqlDbType.Decimal).Value = Decimal.Parse(id);
  40. SqlDataAdapter da = new SqlDataAdapter(cmd);
  41. DataSet ds = new DataSet();
  42. try
  43. {
  44. conn.Open();
  45. try
  46. {
  47. da.Fill(ds);
  48. }
  49. catch
  50. {
  51. return null;
  52. }
  53. finally
  54. {
  55. conn.Close();
  56. conn.Dispose();
  57. }
  58. }
  59. catch(Exception)
  60. {
  61. return null;
  62. }
  63. return ds;
  64. }
  65.  
  66. //Actualizamos el registro modificado
  67. [Ajax.AjaxMethod()]
  68. public string Actualiza_Fila(string OrderId, string ShipName, string ShipAddress,
    string
    ShipCity, string ShipCountry)
  69. {
  70. SqlConnection conn = new SqlConnection("Data Source=localhost;User id=sa;
    Password=;Initial Catalog=northwind;"
    );
  71. SqlCommand cmd = new SqlCommand("update Northwind.dbo.Orders set ShipName =
    @ShipName, ShipAddress = @ShipAddress, ShipCity = @ShipCity, ShipCountry =
    @ShipCountry where OrderId = @OrderId"
    , conn);
  72. cmd.Parameters.Add("@ShipName", SqlDbType.NVarChar, 40).Value = ShipName;
  73. cmd.Parameters.Add("@ShipAddress", SqlDbType.NVarChar, 60).Value =
    ShipAddress;
  74. cmd.Parameters.Add("@ShipCity", SqlDbType.NVarChar, 15).Value = ShipCity;
  75. cmd.Parameters.Add("@ShipCountry", SqlDbType.NVarChar, 15).Value =
    ShipCountry;
  76. cmd.Parameters.Add("@OrderId", SqlDbType.Int).Value = Int32.Parse(OrderId);
  77. try
  78. {
  79. cmd.Connection.Open();
  80. cmd.ExecuteNonQuery();
  81. }
  82. catch (Exception errorMens)
  83. {
  84. return "<h4>El Expedidor <u style=\"background-color:#FF8000;\">
    <span>"
    + ShipName + "</span></u> de Id <u style=\"background-color:#FF8000;
    \"><span>"
    + OrderId + "</span></u> no ha sido actualizado. Tubo lugar
    el siguiente error: <br><ul><li><em><u><span>"
    +
    errorMens.Message + ".</span></u></em></li></ul></h4>";
  85. }
  86. finally
  87. {
  88. cmd.Connection.Close();
  89. }
  90. return "<h4>El Expedidor <u><span>" + ShipName + "</span></u> de Id
    <u><span>"
    + OrderId + "</span></u> ha sido actualizado con éxito.</h4>";
  91. }

Volver al menú.

Funciones del lado Cliente

Recomiendo encarecidamente que mireis este código descargándoos el proyecto, por que leerlo de aquí es harto complicado.

  1. <!-- Función para sacarlos datos de la fila
  2. seleccionada de la tabla para su posterior
  3. modificación de datos (Update) -------- -->
  4. <script type="text/javascript">
  5. /* Se envía a servidor el id de la tupla
  6. seleccionada para obtener dicha fila de DB */
  7. function SacarFila_callback(response){
  8. var ds = response.value;
  9. contenido2b.innerHTML = "";
  10. /* Si la consulta trae datos, se crea
  11. dinámicamente una tabla con textbox para
  12. poder modificar los datos y reenviar (Update) */
  13. if(ds != null && typeof(ds) == "object" && ds.Tables != null){
  14. contenido2b.innerHTML += "<br><h4>Actualizar Datos:</h4><table
    style='display:block; margin:0 auto;' border=0><tr><th>Id:</th>
    <td><input class=noinput type=text id=ident value='"
    +
    ds.Tables[0].Rows[0].OrderID + "' readonly=true></td></tr><tr>
    <th>Expedidor:</th><td><input type=text id=user value='"
    +
    ds.Tables[0].Rows[0].ShipName + "'></td></tr><tr><th>Direcci&oacute;n</th><td>
    <input type=text id=nom value='"
    + ds.Tables[0].Rows[0].ShipAddress +
    "'></td></tr><tr><th>Ciudad:</th><td><input type=text id=ape1 value='"
    +
    ds.Tables[0].Rows[0].ShipCity + "'></td></tr><tr><th>Pais:</th><td><input
    type=text id=ape2 value='"
    + ds.Tables[0].Rows[0].ShipCountry + "'></td></tr>
    <tr><td colspan=2><input type=button class=deco style='width:100%'
    value=actualizar id=enviar onclick='changeElementsStylebyTag(\"tr\",\"#000000\",
    \"
    #FEFCFD\"); document.Form1.sel.value=\"-1\";
    _Default.Actualiza_Fila(ident.value, user.value, nom.value, ape1.value,
    ape2.value, Actualiza_Fila_callback);'><td></tr></table><br>"
    ;
  15. }
  16. else {
  17. alert("Error. [3001] " + response.request.responseText);
  18. }
  19. }
  20. </script>
  21. <!-- ---------------------------------- -->
  22.  
  23. <!-- Una vez modificados los datos se
  24. envían al servidor para concluir
  25. la actualización de datos (Update) -->
  26. <script type="text/javascript">
  27. function Actualiza_Fila_callback(response){
  28. contenido2b.innerHTML = response.value;
  29. _Default.GetDataSet(GetDataSet_callback);
  30. }
  31. </script>
  32. <!-- ----------------------------- -->
  33.  
  34. <!-- Creamos la tabla y la paginación -->
  35. <script type="text/javascript">
  36. /* Función para cambiar los estilos (css)
  37. por etiquetas. 'el' especifica el elemento,
  38. para el caso será los elementos 'tr', para
  39. colorear las filas de la tabla. 'clr' será
  40. el color del texto y 'bclr' el color de
  41. fondo (background) --------------------- */
  42. function changeElementsStylebyTag(el,clr,bclr){
  43. if(document.getElementsByTagName) {
  44. var nodes = document.getElementsByTagName(el);
  45. var max = nodes.length;
  46. for(var i = 0;i < max;i++) {
  47. var nodeObj = nodes.item(i);
  48. nodeObj.style.color = clr;
  49. nodeObj.style.background = bclr;
  50. }
  51. }
  52. }
  53. /* ------------------------------------- */
  54.  
  55. /* Igual que la anterior función, pero en
  56. puesto de seleccionar por etiqueta, lo hace
  57. por id --------------------------------- */
  58. function changeElementsStylebyId(el,clr,bclr){
  59. var nodeObj = document.getElementById(el);
  60. nodeObj.style.color = clr;
  61. nodeObj.style.background = bclr;
  62. }
  63. /* ------------------------------------- */
  64.  
  65. /* Funciones para colorear las filas al
  66. pasar el ratón --------------------- */
  67. function changeElementsStylebyId_tr(el,clr,bclr,id){
  68. var fila = document.Form1.sel.value;
  69. if (parseInt(id) != parseInt(fila))
  70. {
  71. var nodeObj = document.getElementById(el);
  72. nodeObj.style.color = clr;
  73. nodeObj.style.background = bclr;
  74. }
  75. }
  76.  
  77. function changeElementsStylebyId_tr_salida(el,clr,bclr,id){
  78. var fila = document.Form1.sel.value;
  79. if (parseInt(id) != parseInt(fila))
  80. {
  81. var nodeObj = document.getElementById(el);
  82. nodeObj.style.color = clr;
  83. nodeObj.style.background = bclr;
  84. }
  85. else
  86. {
  87. var nodeObj = document.getElementById(el);
  88. nodeObj.style.color = "#F7F7F7";
  89. nodeObj.style.background = "#494949";
  90. }
  91. }
  92. /* --------------------------------- */
  93.  
  94. /* Funciones para ocultar las filas */
  95. function oculta_capa (capa) {
  96. if (document.getElementById(capa).style.visibility == "visible") {
  97. document.getElementById(capa).style.visibility = "hidden";
  98. }
  99. else if (document.getElementById(capa).style.visibility == "hidden") {
  100. document.getElementById(capa).style.visibility = "visible";
  101. }
  102. else {
  103. document.getElementById(capa).style.visibility = "hidden";
  104. }
  105. }
  106.  
  107. function oculta_capa_display (capa) {
  108. if (document.getElementById(capa).style.display == "block") {
  109. document.getElementById(capa).style.display = "none";
  110. }
  111. else if (document.getElementById(capa).style.display == "none") {
  112. document.getElementById(capa).style.display = "block";
  113. }
  114. else {
  115. document.getElementById(capa).style.display = "none";
  116. }
  117. }
  118. /* -------------------------------- */
  119.  
  120. /* Con ésta función creamos la tabla y la
  121. paginación, que puede ser tanto con
  122. botones como con links. --------------- */
  123. function GetDataSet_callback(response){
  124. /* Obtenemos el DataSet */
  125. var ds = response.value;
  126. /* Comprobamos si trae datos, de ser así
  127. comenzamos a maquetar los datos ----- */
  128. if(ds != null && typeof(ds) == "object" && ds.Tables != null){
  129. /* Vamos metiendo los contenidos en un
  130. array que posteriormente volcaremos
  131. a un div -------------------------- */
  132. var s = new Array();
  133. s[s.length] = "<br>";
  134. /* Miramos el valor del input type=hidden
  135. de nombre 'num' para saber que resultados
  136. de paginación debemos mostrar -------- */
  137. var pag = document.Form1.num.value;
  138. var numpag = (parseInt(pag)/parseInt(10));
  139. numpag = (parseInt(numpag) + parseInt(1));
  140. var z = 1;
  141. s[s.length] = "<div id='paginacion'><div id='contenido'>";
  142. /* quitar si se usa paginación de botones */
  143. //s[s.length] = "|";
  144. /* ************************************** */
  145. /* formamos la paginación de la tabla */
  146. for (var a=0; a<ds.Tables[0].Rows.length; a++){
  147. /* Paginación con botones */
  148. if (a%10 == 0) {
  149. s[s.length] = "<INPUT";
  150. s[s.length] = " style='";
  151. if (z == numpag) {
  152. s[s.length] = "background-color:#494949;
    color:#F3F3F3; "
    ;
  153. }
  154. s[s.length] = "width:70px;'";
  155. s[s.length] = " class=deco
    OnClick='document.Form1.num.value="
    + a + ";
    _Default.GetDataSet(GetDataSet_callback);'
    type=button value=P&aacute;g."
    +
    z + "> ";
  156. z += 1;
  157. }
  158. /* ********************** */
  159. /* Paginación con links */
  160. /*
  161. if (a%10 == 0) {
  162. s[s.length] = "| <a style='";
  163. if (z == numpag) {
  164. s[s.length] = "width:90px; color:#1248A5;
    font-weight:bold;
    border:1px solid #5D5D5D; background-color:#EAEEEF; padding-left:10px;
    padding-right:10px;";
  165. }
  166. else {
  167. s[s.length] = "width:50px;";
  168. }
  169. s[s.length] = "' href='#'
    OnClick='document.Form1.num.value=" + a + ";
    _Default.GetDataSet(GetDataSet_callback);'>" + "P&aacute;g. " +
    z + "</a> |";
  170. z += 1;
  171. }
  172. */
  173. /* ******************** */
  174. }
  175. /* quitar si se usa paginación de botones */
  176. //s[s.length] = "|";
  177. /* ************************************** */
  178. s[s.length] = "</div></div>";
  179. s[s.length] = "<br><br>";
  180. /* Construimos la tabla con los contenidos
  181. del DataSet --------------------------- */
  182. s[s.length] = "<table border=1 style='display:block; margin:0 auto;'>";
  183. s[s.length] = "<tr><th>Actualizar/Ocultar</th><th>Id</th><th>Expedidor
    </th><th>Direcci&oacute;n</th><th>Ciudad</th><th>Pais</th></tr>"
    ;
  184. /* Número de filas que mostraremos por table */
  185. var oper = 9;
  186. var comparar = parseInt(pag) + parseInt(oper);
  187. /* Construimos la tabla mostrando solo la
  188. página seleccionada ------------------ */
  189. for(var i=0; i<ds.Tables[0].Rows.length; i++){
  190. if ((parseInt(i) >= parseInt(pag)) && (parseInt(i) <=
    parseInt(comparar))) {
  191. s[s.length] = "<tr";
  192. /* Si el registro actual estaba seleccionado
  193. lo coloreamos --------------------------- */
  194. if (document.Form1.sel.value ==
    ds.Tables[0].Rows[i].OrderID) {
  195. s[s.length] = " style='background-color:#494949;
    color:#F7F7F7'"
    ;
  196. /* Le damos un nombre al td del botón seleccionar
  197. para que al colorear la fila, tras seleccionarla
  198. podamos descolorear (al final de la función), el
  199. fondo del botón, simplemente por que queda feo */
  200. var identif = "td" + ds.Tables[0].Rows[i].OrderID;
  201. }
  202. else
  203. {
  204. s[s.length] = " onmouseover=\"
    changeElementsStylebyId_tr('tr"
    + ds.Tables[0].Rows[i].OrderID
    + "','#F7F7F7','#8FA6B0'," + ds.Tables[0].Rows[i].OrderID +
    "); changeElementsStylebyId_tr('td" +
    ds.Tables[0].Rows[i].OrderID + "','#000000','transparent'," +
    ds.Tables[0].Rows[i].OrderID + ");\" onmouseout=\"changeElementsStylebyId_tr(
    'tr"
    + ds.Tables[0].Rows[i].OrderID + "','#000000','#FEFCFD'," +
    ds.Tables[0].Rows[i].OrderID
    + ");\"";
  205. }
  206. s[s.length] = " id=tr" + ds.Tables[0].Rows[i].OrderID + ">";
  207. s[s.length] = "<td id=\"td" + ds.Tables[0].Rows[i].OrderID
    + "\"><input onmouseover=\"this.style.background='#BF0000';
    this.style.color='#F2F8FC';\"
    onmouseout=\"this.style.background='#EAF4FA'; this.style.color='#242424';\"
    class='deco2' style='width:100%' value='Seleccionar'
    onclick='document.Form1.sel.value="
    + ds.Tables[0].Rows[i].OrderID + ";
    changeElementsStylebyTag(\"tr\",\"#000000\",\"#FEFCFD\");
    changeElementsStylebyId_tr_salida(\"tr"
    + ds.Tables[0].Rows[i].OrderID +
    "\",\"#F7F7F7\",\"#494949\"," + ds.Tables[0].Rows[i].OrderID + ");
    changeElementsStylebyId(\"td"
    + ds.Tables[0].Rows[i].OrderID +
    "\",\"transparent\",\"transparent\"); _Default.SacarFila(\""
    +
    ds.Tables[0].Rows[i].OrderID + "\", SacarFila_callback);' type=button id=" +
    ds.Tables[0].Rows[i].OrderID + "><input style='visibility: visible;'
    value='Visibilidad' type='button' onmouseover=\"this.style.background='#FF7400';
    this.style.color='#F2F8FC';\" onmouseout=\"this.style.background='#EAF4FA';
    this.style.color='#242424';\" class='deco2' style='width:100%'
    onclick='oculta_capa(\"tr"
    + ds.Tables[0].Rows[i].OrderID +
    "\");'></td>";
  208. s[s.length] = "<td>" + ds.Tables[0].Rows[i].OrderID +
    "</td>";
  209. s[s.length] = "<td>" + ds.Tables[0].Rows[i].ShipName +
    "</td>";
  210. s[s.length] = "<td>" + ds.Tables[0].Rows[i].ShipAddress +
    "</td>"
    ;
  211. s[s.length] = "<td>" + ds.Tables[0].Rows[i].ShipCity +
    "</td>"
    ;
  212. s[s.length] = "<td>" + ds.Tables[0].Rows[i].ShipCountry +
    "</td>"
    ;
  213. s[s.length] = "</tr>";
  214. }
  215. }
  216. s[s.length] = "</table>";
  217. /* Volcamos el array con los
  218. contenidos en el div ---- */
  219. contenido2.innerHTML = s.join("");
  220. }
  221. else {
  222. /* Si el DataSet no traía datos, mostramos
  223. el mensaje de error del servidor ------ */
  224. alert("Error. [3001] " + response.request.responseText);
  225. }
  226. try
  227. {
  228. /* Descoloreamos el fondo del botón
  229. de la tuple seleccionada ------- */
  230. changeElementsStylebyId(identif,'transparent','transparent');
  231. }
  232. catch (e)
  233. {}
  234. }
  235. /* ------------------------------- */
  236. </script>
  237. <!-- ---------------------------- -->
  238. <!-- Aquí guardamos la fila seleccionada
  239. para que al movernos por la paginación
  240. de la tabla, al volver a la página donde
  241. se haya dicha fila, ésta permanezca resaltada.
  242. Si está a -1 es que no hay ninguna fila
  243. seleccionada ----------------------------- -->
  244. <input id="sel" type="hidden" value="-1">
  245. <!-- ------------------------------------- -->
  246. <!-- Aquí guardamos la página (Paginación)
  247. en la que nos encontramos, para poder resaltar
  248. el enlace o botón de paginación en el que nos
  249. encontramos ------------------------------ -->
  250. <input id="num" type="hidden" value="0">
  251. <!-- ------------------------------------- -->

La paginación esta implementada tanto con botones como con enlaces, ya va en el código comentado, solo teneis que comentar el código del que no querais usar, el resultado es:

Paginación con botones:

Paginación con botones

Paginación con enlaces:

Paginación con enlaces

Volver al menú.

Enlaces de interés

JavaScript y DOM

Volver al menú.

AJAX

Volver al menú.

Scour Design ™ Todos los Derechos Reservados © Carlos Carmona Xhtml 1.1 Strict Válido!CSS Nivel 2 Válido! Nivel Triple-A de Conformidad con las Directrices de Accesibilidad Web (WAI)