[Parte 2] Un progetto con "CrossWindow" in ASP.Net

Eccoci, pronti a continuare il discorso già iniziato ieri.

Qualche passo indietro

Facciamo un po' di ripasso su altre tecnologie che comunque ci servono per portare a termine il nostro compito, parliamo quindi di JavaScript (JS).
Innanzitutto occorre dire che ha senso utilizzare JS anche in un progetto ASP.Net (lo stesso ASP.Net utilizza proprio JS per implementare alcuni processi sul client) proprio perchè esso riesce a comunicare con tutti i componenti client della nostra pagina (e browser).

Quello che serve a noi per questo progetto sono essenzialmente due:

  • Poter comunicare alla pagina "chiamante" dei dati
  • Poter inserire in un tag input (eh si, ora si chiama così, siamo sul client...) un valore

Per la prima funzione esiste (nella gerarchia DOM assolutamente gestita da JS) l'utilissimo window.opener che altro non è che l'oggetto che ha aperto la window corrente (finestra browser).
Il window.opener non è altro che un oggetto di tipo window che permette di "navigare" tutta la struttura ad albero della finestra chiamante. Vale undefined se la finestra non è stata aperta da un altro link ma direttamente digitando l'URL dall'utente.

Detto questo, per chi già ha qualche esperienza con JS, si renderà facilmente conto che posso "rintracciare" tutti gli elementi della pagina tramite window.opener.document.getElementById('NomeElemento')

Per la seconda funzione invece è chiaro che tramite la document.getElementById('NomeElemento') ottengo l'oggetto (ad esempio un tag Input) e tramite la proprietà value assegno il valore che vorremo.

Facciamo il punto

Detto questo vediamo ora di capire come ci serviranno queste conoscenze.
Tornando al nostro progetto cominciamo dalla fine ;) ovvero dalla Default.aspx: è la pagina che richiede la compilazione del campo password che le verrà trasmessa dalla nostra KeyBoard.aspx.

Si implementa quindi una funzione (JS) per la compilazione del tag input con un valore a nostra scelta:

<script language="JavaScript"> 
function DoClick(Valore) 
    {
    document.getElementById('txtPassword').value=Valore;
    }
</script>

Molto semplice direi, ma il problema è: dove inserisco tutto questo in ASP.Net?

Fermo restando che la si può tranquillamente scrivere nella sezione Source del Designer (dove appunto troviamo il codice HTML), può anche capitare che in alcuni casi il codice JS debba per forza essere inserito nella parte di code behind (per esempio se vogliamo che risponda a eventi scatenati da web control) quindi vediamo subito come si fa (io, per mio ordine mentale il codice JS lo aggiungo sempre nella parte code behind, così divido la parte grafica, o HTML,  da quella logica).

Quindi si tratta di dover inserire codice JS a runtime nella nostra pagina. Quando? Beh nella Page.Load direi.

    Protected Sub Page_Load(ByVal sender As ObjectByVal As System.EventArgs) Handles Me.Load
        
'Form the script that is to be registered at client side.
        
Dim scriptString As String = "<script language=JavaScript> function DoClick(Valore) {"
        scriptString += "document.getElementById('txtPassword').value=Valore;"
        scriptString += "}<"
        scriptString += "/"
        scriptString += "script>"

        
If (Not ClientScript.IsClientScriptBlockRegistered("clientScript")) Then
            
ClientScript.RegisterClientScriptBlock(GetType(_Default), "clientScript", scriptString)
        
End If

    End Sub

Si nota che tutto il codice JS si presenta in una stringa, dopo di che, tramite la ClientScript.IsClientScriptBlockRegistered(NomeScript) si controlla se è già stato registrato uno script con quel nome, in caso contrario lo si registra passando il Type della pagina corrente, il nome con la quale registrare lo script o le script stesso.

La registrazione dello script è un'operazione importante, che evita il blocco dello stesso da parte del firewall (tipo quello di WinXP SP2) che eviterebbe l'esecuzione di codice ritenuto malizioso.
Tramite questa registrazione, niente avvisi e niente blocchi.

Ora la nostra pagina è pronta a riempire il nostro tag input richiamando in JS la funzione DoClick(valore) (si, non mi è venuto un nome migliore).

Cosa manca?
Beh il fatto che la nostra KeyBoard.aspx invii a Default.aspx la password.

Ormai tutti i trucchi sono svelati: sappiamo cosa ci permette di fare la window.opener, sappiamo come inserire del codice JS da ASP.Net, quindi?

Beh manca ancora una cosa: fare in modo che sull'evento di un Web Control venga eseguito codice JS.
Questo viene fatto con la collection Attributes del WebControl, se si vuole ad esempio che il Bottone btnOk esegua il codice della funzione Accetta() sul click basta aggiungere questo codice:

btnOk.Attributes.Add("onclick", "javascript:Accetta();")

Mettendo insieme tutti questi elementi, quindi, nel nostro User Control WebKeyBoard.ascx occorrerà aggiungere il codice seguente:

    Protected Sub Page_Load(ByVal sender As ObjectByVal As System.EventArgs) Handles Me.Load
        
Me.MyPWD = New Password(Me.txtPassword.Text)
        
Dim scriptString As String = "<script language=JavaScript> function Accetta() {"
        scriptString += "if (window.opener!=undefined)"
        scriptString += "{"
        scriptString += "window.opener.DoClick(document.getElementById('WebKeyBoard1_txtPassword').value); window.close();"
        scriptString += "}"
        scriptString += "}<"
        scriptString += "/"
        scriptString += "script>"


        
If (Not Me.Page.ClientScript.IsClientScriptBlockRegistered("clientScript")) Then
            Me
.Page.ClientScript.RegisterClientScriptBlock(GetType(WebKeyBoard), "clientScript", scriptString)
        
End If

        
btnOk.Attributes.Add("onclick", "javascript:Accetta();")
        btnAnnulla.Attributes.Add("onclick", "window.close();")

    
End Sub

Così, quando viene cliccato il Bottone btnOk viene richiamata l'Accetta() che non fa altro che richiamare la DoClick() della finestra chiamante (se esiste) passando la password.

Un'ulteriore occhio di riguardo va al nome (o meglio ID) che prende il tag input quando viene "creato" da ASP.Net al posto di una TextBox.

Per far questo io ho osservato il codice HTML generato e ho visto che come ID aveva WebKeyBoard1_txtPassword quindi presumo che sia il nome dello User Control nella sua prima istanza (come tutti gli oggetti di default: NomeTipo + 1) _ (underscore) NomeWebControl.

Ecco il motivo per il quale pur avendo una TextBox che si chiama txtPassword, in JS ho utilizzato la getElementById('WebKeyBoard1_txtPassword').

Conclusione

Questo è quanto, basta provare il tutto per rendersi conto che, dopo aver compilato (o costruito tramite la tastiera) la password nella nostra KeyBoard.aspx, cliccando Ok la stessa ce la ritroviamo nella Default.aspx, con un meccanismo che io ho chiamato CrossWindow Post (beh si, trattandosi di client certo non si parla di Post...)

Le considerazioni da fare sarebbero, come sempre, tantissime ma considerando il tempo che ho perso per tentare di capire come risolvere questo problema, ho preferito dare spazio alla soluzione più che ai dubbi in questa sede, in modo di poterli lasciare a vari commenti o e-mail...

Mi aspetto smentite, commenti, soluzioni migliori, consigli, critiche, di tutto...

powered by IMHO 1.3

Print | posted @ giovedì 23 febbraio 2006 17:49

Comments have been closed on this topic.