Blog di LucaB

audio, video, disco

November 2007 - Posts

Come cambiare il tab visibile nel controllo Tabs dell'AJAX Control Toolkit usando JavaScript

In un sito web a cui sto lavorando ho inserito in una pagina il controllo Tabs dell'AJAX Control Toolkit. In questa pagina avevo l'esigenza di permettere al visitatore di cambiare il tab visibile anche mediante un link nella pagina stessa.

All'inizio ho provato semplicemente con un LinkButton inserito in un UpdatePanel, modificando dal lato server la proprietà ActiveTabIndex del TabContainer. Questa soluzione, semplicissima da implementare (anche se probabilmente genera parecchio codice superfluo), creava problemi con il rendering di una mappa visualizzata in uno dei tab (problema di cui ho scritto in un precedente post).

Allora ho provato ad utilizzare JavaScript, ma un primo abbozzo che sembrava funzionare senza problemi, in realtà si è dimostrato compatibile solo con IE (ho provato IE7, non so su IE6) e non con Firefox.

Dopo qualche inutile tentativo per rendere il mio approccio compatibile anche con Firefox, in questo post ho trovato la spiegazione del metodo giusto per affrontare il problema.

Il trucco è nel riferirsi al Behavior corrispondente al controllo (come sempre per i controlli dell'AJAX Control Toolkit), per il quale si trovano esposti i metodi e le proprietà "pubblici"[1], accessibili lato client. Per accedere al Behavior, è sufficiente riferirsi in JavaScript alla proprietà control del TabContainer.

Riassumo qui come fare.

Dato un controllo Tabs, costituito da un TabContainer col nome MyTabs e dai TabPanel interni ad esso, ad esempio:

<ajaxToolKit:TabContainer ID="MyTabs" runat="server">
  	<ajaxToolKit:TabPanel runat="server" ID="tab1">
		<HeaderTemplate> Uno </HeaderTemplate>
		<ContentTemplate> 
			Primo pannello
		</ContentTemplate>
	</ajaxToolKit:TabPanel>
	<ajaxToolKit:TabPanel runat="server" ID="tab2">
		<HeaderTemplate> Due </HeaderTemplate>
		<ContentTemplate>
			Secondo pannello
		</ContentTemplate>
	</ajaxToolKit:TabPanel>
	<ajaxToolKit:TabPanel runat="server" ID="tab3">
<HeaderTemplate> Tre </HeaderTemplate> <ContentTemplate> Terzo pannello </ContentTemplate> </ajaxToolKit:TabPanel> </ajaxToolKit:TabContainer>

Basterà inserire nella pagina il seguente codice BLOCKED SCRIPT

function changeTab( tabIndex ){ 
    var tabBehavior = $get('<%=MyTabs.ClientID%>').control; 
    tabBehavior.set_activeTabIndex(tabIndex); 
}

A questo punto un semplice collegamento ipertestuale, inserito in un punto qualsiasi della pagina (e quindi anche in uno dei TabPanel) può essere sufficiente a richiamare la funzione.

Ad esempio:

<a href="BLOCKED SCRIPTchangeTab(1);">Vai al secondo tab</a>

 

View blog reactions


[1] Trattandosi di JavaScript, non ha molto senso parlare di metodi, proprietà, pubblico e privato, anche se sia nella libreria AJAX di Microsoft che in quelle dell'AJAX Control Toolkit sono state adottate convenzioni per i nomi che rendono la programmazione in JavaScript simile alla programmazione ad oggetti. Per approfondimenti sul tema si può partire da questo post di Andrea Boschin.
Posted: Nov 25 2007, 08:06 AM by lucab | with no comments
Filed under: , ,
PostBack con AJAX per le CheckBox di un controllo TreeView

La soluzione proposta nel post precedente presenta almeno un paio di inconvenienti significativi:

  • deve essere "aggiustata" per poter funzionare su diversi tipi di browser (probabilmente annegando tra gli if)
  • non funziona con AJAX, poiché anche inserendo il controllo TreeView in un UpdatePanel, il click su una CheckBox genera ovviamente un PostBack sincrono

Una soluzione migliore e, forse, anche più semplice, l'ho trovata su questo thread tra i forum di ASP.NET.

Si inserisce nella pagina un controllo Button, reso invisibile attraverso lo stile, e al'evento OnClick del TreeView si simula una Click del controllo Button. A questo punto il PostBack è garantito. Se, inoltre, il TreeView ed il Button sono entrambi in un UpdatePanel, sarà generato un PostBack asincrono.

In questo modo, in più, si ottiene anche una maggiore compatibilità crossbrowser, lasciando questo fastidioso compito al rendering di ASP.NET ed alla libreria AJAX di Microsoft.

Riepilogando, nella pagina si inserisce:

<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
  <ContentTemplate>
    <asp:TreeView ID="TV1" runat="server" ShowCheckBoxes="Leaf">
      <Nodes>
        <asp:TreeNode Text="Nodo 1" Value="1">
          <asp:TreeNode Text="Nodo 1.1" Value="1.1" />
          <asp:TreeNode Text="Nodo 1.2" Value="1.2" />
          <asp:TreeNode Text="Nodo 1.3" Value="1.3" />
        </asp:TreeNode>
        <asp:TreeNode Text="Nodo 2" Value="2">
          <asp:TreeNode Text="Nodo 2.1" Value="2.1" />
          <asp:TreeNode Text="Nodo 2.2" Value="2.2" />                    
        </asp:TreeNode>
        <asp:TreeNode Text="Nodo 3" Value="3">
          <asp:TreeNode Text="Nodo 3.1" Value="3.1" />
          <asp:TreeNode Text="Nodo 3.2" Value="3.2" /> 
          <asp:TreeNode Text="Nodo 3.3" Value="3.3" />
          <asp:TreeNode Text="Nodo 3.4" Value="3.4" />                    
        </asp:TreeNode>
      </Nodes>
    </asp:TreeView>
    <asp:Button Id="Btn" runat="server" />
  </ContentTemplate>
</asp:UpdatePanel>

Mentre il codice corrispondente, con riferimento all'esempio del post precedente (si intercetta l'evento CheckChanged per imporre solo una CheckBox spuntata) diventa:

    Protected Sub Page_Load(ByVal sender As Object, _
                ByVal e As System.EventArgs) Handles Me.Load
        If Me.IsPostBack = False Then
            TV1.Attributes.Add("onclick", _
String.Format("$get('{0}').click();", Btn.ClientID)) Btn.Attributes.Add("style", "visibility: hidden") End If End Sub Protected Sub TV1_TreeNodeCheckChanged(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _ Handles TV1.TreeNodeCheckChanged If e.Node.Checked Then For Each n As TreeNode In TV1.Nodes Me.UncheckOtherNodes(n, e.Node) Next End If End Sub Private Sub UncheckOtherNodes(ByVal n As TreeNode, _ ByVal nc As TreeNode) If n.ChildNodes.Count > 0 Then For Each cn As TreeNode In n.ChildNodes Me.UncheckOtherNodes(cn, nc) Next Else If n IsNot nc Then n.Checked = False End If End If End Sub

cambiando, quindi, solo la parte relativa al Page.Load

View blog reactions

Posted: Nov 18 2007, 11:21 PM by lucab | with no comments
Filed under: , ,
Forzare il PostBack per le CheckBox di un controllo TreeView

Navigation ControlsIl controllo web di ASP.NET TreeView consente, attraverso la proprietà ShowCheckBoxes, di mostrare accanto ad ogni nodo una CheckBox.

Precisamente, è possibile assegnare a ShowCheckBoxes i valori All, Leaf, None, Parent, Root a seconda del tipo di nodi per i quali si vogliono visualizzare le CheckBox.

Ad esempio con il seguente codice:

<asp:TreeView ID="TV1" runat="server" ShowCheckBoxes="Leaf">
    <Nodes>
        <asp:TreeNode Text="Nodo 1" Value="1">
            <asp:TreeNode Text="Nodo 1.1" Value="1.1" />
TreeView            <asp:TreeNode Text="Nodo 1.2" Value="1.2" />
            <asp:TreeNode Text="Nodo 1.3" Value="1.3" />
        </asp:TreeNode>
        <asp:TreeNode Text="Nodo 2" Value="2">
            <asp:TreeNode Text="Nodo 2.1" Value="2.1" />
            <asp:TreeNode Text="Nodo 2.2" Value="2.2" />                    
        </asp:TreeNode>
        <asp:TreeNode Text="Nodo 3" Value="3">
            <asp:TreeNode Text="Nodo 3.1" Value="3.1" />
            <asp:TreeNode Text="Nodo 3.2" Value="3.2" /> 
            <asp:TreeNode Text="Nodo 3.3" Value="3.3" />
            <asp:TreeNode Text="Nodo 3.4" Value="3.4" />                    
        </asp:TreeNode>
    </Nodes>
</asp:TreeView>

si avrebbe il risultato visualizzato nell'immagine a lato.

Il problema è che non c'è verso di impostare un PostBack automatico per l'evento click su una CheckBox.

Per esempio, supponiamo di voler imporre che nel TreeView indicato possa essere selezionata una sola CheckBox. Il codice potrebbe essere il seguente:

    Protected Sub TV1_TreeNodeCheckChanged(ByVal sender As Object, _
            ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _
            Handles TV1.TreeNodeCheckChanged
        If e.Node.Checked Then
            For Each n As TreeNode In TV1.Nodes
                Me.UncheckOtherNodes(n, e.Node)
            Next
        End If
    End Sub

    Private Sub UncheckOtherNodes(ByVal n As TreeNode, _
            ByVal nc As TreeNode)
        If n.ChildNodes.Count > 0 Then
            For Each cn As TreeNode In n.ChildNodes
                Me.UncheckOtherNodes(cn, nc)
            Next
        Else
            If n IsNot nc Then
                n.Checked = False
            End If
        End If
    End Sub

Per intercettare l'evento, però, è necessario un altro controllo che generi il PostBack, ad esempio un altro Button nella stessa pagina.

Cercando in rete ho trovato qui una soluzione al problema, che riporto. In pratica si aggiunge un po' di codice JavaScript nella pagina:

function postbackOnCheck() {
    var o = window.event.srcElement;
    if (o.tagName == 'INPUT' && o.type == 'checkbox' &&
    o.name != null && o.name.indexOf('CheckBox') > -1) {
        __doPostBack("","");
    }
}

Si imposta, quindi, l'attributo OnClick al controllo TreeView per richiamare questa funzione:

    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Load
        If Me.IsPostBack = False Then
            TV1.Attributes.Add("OnClick", "postbackOnCheck()")
        End If
    End Sub

ed il gioco è fatto, ogni volta che si seleziona o deseleziona una CheckBox viene generato un PostBack e quindi la funzione di gestione dell'evento.

Questa soluzione, però, soffre di alcuni difetti (compatibilità cross browser, utilizzo con AJAX) che saranno oggetto di un prossimo post.

View blog reactions

Quiz: LIFO, FIFO e poste italiane

FIFO LIFOSapendo che:

  1. LIFO sta per Last In First Out, un metodo per gestire le code in cui il primo arrivato è l'ultimo ad uscire
  2. FIFO sta per Fisrt In First Out, per cui il primo arrivato è il primo ad uscire
  3. sono abbonato ad una rivista mensile e le poste me ne hanno consegnato il numero di settembre qualche giorno dopo averne ricevuto il numero di ottobre (con notevole ritardo pure questo)

quale metodo usano alle poste per smaltire le consegne arretrate?

 

Technorati Tags: , ,

 

View blog reactions

Posted: Nov 05 2007, 02:46 PM by lucab | with 1 comment(s)
Filed under:
Congratulations. You won 15th Prize in the October 2007 Contest

Dilbert Board Game... ossia l'ambitissimo Dilbert Board Game Big Smile

Chissà se mi arriverà per Natale...

Technorati Tags: ,

 

View blog reactions

Posted: Nov 04 2007, 01:11 PM by lucab | with 1 comment(s)
Filed under:
Come installare i gadget per la sidebar in inglese su Vista in italiano

Qualche giorno fa ho scaricato Uptime Gadget, un semplice gadget per la sidebar di Vista che permette di visualizzare il tempo trascorso dall'ultimo riavvio.

Ho provato ad installarlo, ma senza alcun risultato: non avevo alcun messaggio e il gadget non era stato aggiunto a quelli già presenti.

Cercando un po' in rete, ho letto che questo problema capita spesso quando si prova ad installare un gadget in lingua inglese su Vista in italiano. Più in generale, può capitare quando le lingue del gadget e di Vista non coincidono[1].

Grazie ad una dritta suggerita qui ho scoperto come ovviare all'inconveniente:

  1. Scompattare il file di installazione del gadget, che termina appunto con l'estensione .gadget in una cartella con lo stesso nome, compresa l'estensione (nel mio caso si trattava di Uptime.gadget). Per farlo è sufficiente aprire il file utilizzando Winrar.
  2. Rinominare la sottocartella en-US, che si trova nella cartella creata, in it-IT
  3. Copiare la cartella Uptime.Gadget in C:\Program Files\Windows Sidebar\Gadgets, fornendo le necessarie autorizzazioni quando richieste dallo UAC

A questo punto si può tranquillamente aggiungere il gadget alla sidebar, poiché comparirà tra quelli disponibili. uptimegadget

Nell'immagine il gadget in funzione.
(Giacché c'ero l'ho tradotto, cambiando le stringhe nel file Uptime.Gadget\it-IT\core\core.framework.vbs)


[1] Forse è per questo che sul sito ufficiale i gadget per la sidebar di Vista mi appaiono di default filtrati per lingua = italiano

View blog reactions

Add-in per Microsoft Office per leggere i file ODF (OpenOffice)

Mi è capitato di dover aprire da Office 2007 (Word ed Excel) dei file creati con OpenOffice e salvati in formato ODF (OpenDocument File), rispettivamente con estensione .odt (OpenDocument Text) e .ods (OpenDocument Spreadsheet).

Per chi dovesse avere questo stesso problema, o magari quello di aprire file .odp (OpenDocument Presentation), o più in generale di ineroperabilità tra i formati ODF e Microsoft OpenXML, può tornare utile il progetto di OpenXML/ODF Translator Add-ins for Office (grazie a Roberto per la segnalazione).

Io ho scaricato, installato e provato solo gli ODF Add-in per Word 2007 e per Excel 2007, che sembrano funzionare egregiamente.

Una volta installati gli add-in, sia in Word 2007 che in Excel 2007 compaiono due nuove voci del menù, per aprire e salvare file ODF, come nella figura seguente.

opzione per odf nel menu di word 2007

View blog reactions

Posted: Nov 03 2007, 12:34 AM by lucab | with no comments
Filed under: