Wednesday, November 12, 2008

Ritornare valore da popup con JQuery

. Wednesday, November 12, 2008

Nello sviluppo di web application, può capitare di dover ritornare uno o più valori selezionati in una pagina di popup ad una pagina parent.  Per questo scopo userò lo strafamoso framework jQuery.
Tra gli strumenti di lavoro, oltre alla libreria, troverete Visual Studio 2008 SP1 con supporto per l'intellisense.
jQuery 1.2.6 (Visual Studio Autocomplete Documentation)
è il primo risultato visibile dell'accordo che Microsoft ha recentemente stretto con il team di jQuery per integrare completamente questa magnifica libreria nella versione 2010 di Visual Studio.
Per maggiori dettagli vi rimando al post di Rick Strahl.
Ma passiamo a dare uno sguardo ad un pò di codice.
Per il tutorial servono due web form:
Default.aspx
Popup.aspx
composte rispettivamente, dal punto di vista del markup, nel seguente modo:

   1: <body>
   2:   <form id="form1" runat="server">
   3:     <div>
   4:       <asp:TextBox ID="txtValue" runat="server" Text="Pagina 1"></asp:TextBox>
   5:       <input type="button" id="btnOpen" value="Open" onclick="Open()"/>
   6:     </div>
   7:   </form>
   8: </body>

   1: <body>
   2:   <form id="form1" runat="server">
   3:     <div>
   4:       <asp:TextBox ID="txtReturnValue" runat="server" Text=""></asp:TextBox>
   5:       <input type="button" id="btnReturn" value="Ritorno" onclick="SetValue()" />
   6:     </div>
   7:   </form>
   8: </body>

Entrambe le pagine presentano un controllo textbox e un input di tipo button.
Nello specifico, l'input con id btnOpen richiama una funzione javascript che si occupa di aprire la pagina Popup.aspx allo scatenarsi dell'evento onclick:


   1: <script type="text/javascript">
   2:   function Open() {
   3:     $(open("Popup.aspx", "external", "width=300;height=300;resizable=0"));
   4:   }
</script>

Non ci resta che inviare il valore del textbox con id txtReturnValue della pagina di Popup.aspx alla pagina chiamante, settando il valore del textbox con id txtValue:


   1: <script type="text/javascript">
   2:   function SetValue() {
   3:     window.parent.opener.$("#txtValue").val($("#txtReturnValue").val());
   4:     $(close());
   5:   }
</script>


Il linea di massima con tre linee di codice si è raggiunto l'obiettivo.
Vediamo di rendere l'esempio un pò più "appetitoso".
Supponiamo di avere una griglia con una lista di dati e supponiamo che dalla pagina di popup vogliamo indicare un valore su cui eseguire un filtro.
I passi per raggiungere lo scopo possono essere:


  • Dalla pagina Popup.aspx richiamare una funzione javascript nella pagina Default.aspx passando come parametro il valore di filtro.
  • La funzione sopra indicata invia tramite JQuery Ajax API il dato ad un Web Service.
  • Parsing dell'xml (che contiene i dati filtrati) ritornato dal Web Service.

Partiamo dal creare un Web Service: WSTest.asmx.
Per semplicità il metodo GetDati ritorna un DataSet:

   1: using System;
   2: using System.Data;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Web;
   6: using System.Web.Services;
   7:  
   8: namespace WebApplication2
   9: {
  10:   /// <summary>
  11:   /// Summary description for WSTest

  12:   /// </summary>
  13:   [WebService(Namespace = "http://tempuri.org/")]
  14:   [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  15:   [System.ComponentModel.ToolboxItem(false)]
  16:   // To allow this Web Service to be called from script, using ASP.NET AJAX,   
uncomment the following line.
  17:   // [System.Web.Script.Services.ScriptService]
  18:   public class WSTest : System.Web.Services.WebService
  19:   {
  20:     [WebMethod]
  21:     public DataSet GetDati( string filter)
  22:     {
  23:       //Eseguo le operazioni di filtro e ritorno un DataSet
  24:     }
  25:   }
  26: }

Invece la funzione ajax che si occupa di richiamare il web service e di parserizzare l'xml è la seguente:

   1: function Filter( filterValue) {
   2:     $.ajax({
   3:         type: "POST",
   4:         url: "WSTest.asmx/GetDati",
   5:         data: "filter=" + filterValue,
   6:         dataType: "xml",
   7:         success: function(response) {
   8:             var table = "<table border=\"1\">";
   9:             $("DTDati", response).each(function() {
  10:             var tr = "<tr><td>" + $("Id", this).text() + "</td><td>" + 
$("Desc", this).text() + "</td></tr>";
  11:             table = table + tr;
  12:                 })
  13:             $("#dv").append( table);
  14:             },
  15:             error: function(resp) {
  16:                 alert(resp);
  17:                 }
  18:         });
  19: }

In parole molto semplici la funzione Filter riceve il valore su cui effettuare il filtro. Viene richiamato il metodo GetDati indicato come valore del parametro url. In caso di successo viene lanciata la funzione che accetta un argomento restituito dal server, formattato in base al paramento dataType.
Itero sugli elementi di DTTati (name del DataTable) per generare l'html della tabella da renderizzare.
Dalla pagina Popup.aspx per lanciare la funzione Filter inserisco il codice della riga 4):

   1: <script type="text/javascript">
   2: function SetValue() {
   3:   window.parent.opener.$("#txtValue").val($("#txtReturnValue").val());
   4:   window.parent.opener.Filter($("#txtReturnValue").val());
   5:   $(close());
   6: }
   7: </script>


Come sempre questa soluzione non è certo da considerarsi quella definitiva ma solo come uno spunto.
Infatti si potrebbero apportare delle significative modifiche per migliorare di molto l'esempio come l'uso di JSON in sostituzione dell'xml, l'uso di AJAX Data Controls invece di generare il markup della griglia oppure l'uso di WCF (Windows Communication Foundation) al posto del Web Services.

0 commenti:

Post a Comment