Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Microsoft & jQuery


Ο Rick Strahl είνα εξαιρετικός programmer και διατηρεί ένα πραγματικά καλό blog με θέματα που αφορούν όλες τις πτυχές του asp.net.
Διαβάστε στο link που ακολουθεί για τον καινούριο έρωτα μεταξύ της Microsoft και του jQuery

Rick Strahl's Web Log: "Microsoft and jQuery"

Databinding AJAX Toolkit accordions

Υπόθεση:
Έχουμε έναν πίνακα που σχηματίζει δεντράκι με join στον εαυτό του στα πεδία Id & ParentId.  Οι γραμμές με ParentId 0 είναι στην κορυφή του δέντρου. Σε κάποιες περιπτώσεις φτάνουμε σε βάθος τριών επιπέδων και σε άλλες σε δύο.
Όταν φτάνουμε στα "φύλλα", δηλαδή εγγραφές που δεν έχουν παιδιά θέλουμε να παρουσιάσουμε τις πληροφορίες, αλλιώς πρέπει να αναπτύξουμε την ιεραρχία των "παιδιών". Υπάρχει στον πίνακα ένα flag που λέγεται HasChildren που μας δίνει την πληροφορία της ύπαρξης των παιδιών (δυναμικό).
Χρησημοποιώντας SQL Datasources & MS Ajax accordions δεν υπήρξε ανάγκη για server side κώδικα. Για την ενφάνιση ή όχι του τελευταίου επιπέδου γίνεται χρήση του jQuery.
Υλοποίηση:
Ακολουθεί ο κώδικας και επεξηγήσεις.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="BindAccordionDemo.aspx.vb"
    Inherits="demos_BindAccordionDemo" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolKit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Data Bind AJAX Control Toolkit Accordion Demo</title>
    <style type="text/css">
        /* Οι κλάσεις για το format του accordion */.accHeader
        {
            cursorpointer;
            padding5px;
            bordersolid 1px #000;
            background-color#ccc;
            font-weightbold;
            border-collapsecollapse;
        }
        .accHeaderSelected
        {
            cursorpointer;
            padding5px;
            bordersolid 1px #000;
            font-weightbold;
            background-color#000;
            color#fff;
            border-collapsecollapse;
        }
        .accContent
        {
            margin-left15px;
            border-collapsecollapse;
        }
    </style>

    <script type="text/javascript">

      
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!--Δίνουμε το jQuery στον script manager αντί για λινκ στο head της σελίδας
        Κάλή πρακτική για κεντρική διαζείριση των scripts που χρησημοποιούμε
        και έχουμε ένα επιπλέον event που μας λέει πως ο script manager φόρτωσε όλα τα scripts -->
        <asp:ScriptManager ID="theScriptManager" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/scripts/jQuery/jquery-1.3.2.min.js" />
                <asp:ScriptReference Path="~/scripts/jQuery/pulse.jquery.js" />
            </Scripts>
        </asp:ScriptManager>
        <!--Το εξωτερικό accordion, η datasource του είναι στο τέλος της σελίδας
            και δεν βρίσκεται μέσα σε accordion pane-->
        <!--απαραίτητα όταν γίνεται το accordion databound σε datasource δηλώνουμε άδεια
                συλλογή panew και μετά "δένουμε" το περιεχόμενο σε header & content templates-->
        <ajaxToolKit:Accordion ID="theAccordion" runat="server" DataSourceID="theSqlDataSource"
            ContentCssClass="accContent" HeaderCssClass="accHeader" HeaderSelectedCssClass="accHeaderSelected"
            RequireOpenedPane="false" FadeTransitions="true" SuppressHeaderPostbacks="true"
            Width="350" SelectedIndex="-1">
            <Panes>
            </Panes>
            <HeaderTemplate>
                <%#Eval("Omada")%></HeaderTemplate>
            <ContentTemplate>
                <!--φυλάμε τo Id σε κρυμένο πεδίο για να περάσουμε την παράμετρο
                στο datasource-->
                <asp:HiddenField ID="hflId" runat="server" Value='<%#EVAL("Id") %>' />
                <!--to datasource βρίσκεται μέσα στο content template και θα τροφοδοτήσει
                    το εσωτερικό accordion-->
                <asp:SqlDataSource ID="innerSqlDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ProtocolConnectionString %>"
                    SelectCommand="SELECT Id, ParentId, OmadaType, Omada, Depth, HasChildren FROM prt_OmadesParalipton WHERE (OmadaType = N'OMD') AND (ParentId = @parentId) ORDER BY Omada">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="hflId" Name="parentId" PropertyName="Value" />
                    </SelectParameters>
                </asp:SqlDataSource>
                <!--το παρακάτω div είναι ο container του τελευταίου επιπέδου και παίρνει css κλάση
                    δυναμικά που βάση αυτής της κλάσης θα εμφανιστεί ή όχι-->
                <div class='<%#EVAL("HasChildren") %>'>
                    Τελευταίο επίπεδο
                    <br />
                    Id:<%#EVAL("Id"%><br />
                    Όνομα:
                    <%#EVAL("Omada"%>
                </div>
                <!--μέσα στο εξωτερικό content template ξεκινάμε τα "παιδιά" accordions
                που τροφοδοτούνται από τα εσωτερικά datasources-->
                <ajaxToolKit:Accordion ID="innerAccordion" runat="server" DataSourceID="innerSqlDataSource"
                    ContentCssClass="accContent" HeaderCssClass="accHeader" HeaderSelectedCssClass="accHeaderSelected"
                    RequireOpenedPane="false" FadeTransitions="true" SuppressHeaderPostbacks="true"
                    Width="100%" SelectedIndex="-1">
                    <Panes>
                    </Panes>
                    <HeaderTemplate>
                        <%#Eval("Omada")%></HeaderTemplate>
                    <ContentTemplate>
                        <asp:HiddenField ID="hflId_2" runat="server" Value='<%#EVAL("Id") %>' />
                        <asp:SqlDataSource ID="moreInnerSqlDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ProtocolConnectionString %>"
                            SelectCommand="SELECT Id, ParentId, OmadaType, Omada, Depth, HasChildren FROM prt_OmadesParalipton WHERE (OmadaType = N'OMD') AND (ParentId = @parentId) ORDER BY Omada">
                            <SelectParameters>
                                <asp:ControlParameter ControlID="hflId_2" Name="parentId" PropertyName="Value" />
                            </SelectParameters>
                        </asp:SqlDataSource>
                        <div class='<%#EVAL("HasChildren") %>'>
                            Τελευταίο επίπεδο
                            <br />
                            Id:<%#EVAL("Id"%><br />
                            Όνομα:
                            <%#EVAL("Omada"%>
                        </div>
                        <ajaxToolKit:Accordion ID="moreInnerAccordion" runat="server"DataSourceID="moreInnerSqlDataSource"
                            ContentCssClass="accContent" HeaderCssClass="accHeader"HeaderSelectedCssClass="accHeaderSelected"
                            RequireOpenedPane="false" FadeTransitions="true" SuppressHeaderPostbacks="true"
                            Width="100%" SelectedIndex="-1">
                            <Panes>
                            </Panes>
                            <HeaderTemplate>
                                <%#Eval("Omada")%></HeaderTemplate>
                            <ContentTemplate>
                                <div class='<%#EVAL("HasChildren") %>'>
                                    Τελευταίο επίπεδο
                                    <br />
                                    Id:<%#EVAL("Id"%><br />
                                    Όνομα:
                                    <%#EVAL("Omada"%>
                                </div>
                            </ContentTemplate>
                        </ajaxToolKit:Accordion>
                    </ContentTemplate>
                </ajaxToolKit:Accordion>
            </ContentTemplate>
        </ajaxToolKit:Accordion>
    </div>
    <div style="clearboth;">
        <asp:SqlDataSource ID="theSqlDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ProtocolConnectionString %>"
            SelectCommand="SELECT Id, ParentId, OmadaType, Omada, Depth, HasChildren FROM prt_OmadesParalipton WHERE (OmadaType = N'OMD') AND (ParentId = 0) ORDER BY Omada">
        </asp:SqlDataSource>

        <script type="text/javascript">
            $(document).ready(function() {
                $('.True').hide();
                $('.False').css('color''Red').css("padding""5px");
                $('.False').pulse({

                    textColors: ['red''black''#ccc''purple''green''#ccc''black']
                });

            });
        </script>

    </div>
    </form>
</body>
</html>



Για να δέσουμε το accordion του δίνουμε το DataSourceId,  ορίζουμε controls στα δύο templates που διαθέτει, τα γεμίζουμε me databind expressions(<%... %> ) όπως κάθε άλλο list control. Η διαφορά είναι ότι ορίζουμε ένα άδειο accordion panes collection με το <Panes</Panes.
Στην περίπτωση αυτή υπάρχουν τρία επίπεδα accordions με τα επίπεδα 2 & 3 να βρίσκονται μέσα σε <ContentTemplate</ContentTemplate. Ένα Hiden Field κρατάει το Id για την παράμετρο των εσωτερικών data sources.Επίσης σε κάθε content template υπάρχει και ένα div που θα κρατάει τα δεδομένα σε περίπτωση η εγγραφή είναι "φύλλο", δηλαδή χωρίς παιδιά. Το attribute της css κλάσης δένεται στο πεδίο HasChildren που θα μας γυρίσει "True" ή "False". Τέλος υπάρχει και ένα accordion με το αντίστοιχο datasource.
Αν λοιπόν η εγγραφή έχει παιδία τότε θα γεμίσει το εσωτερικό accordion, να όχι τότε απλά δεν θα εμφανιστεί. Από την άλλη το div με τις πληροφορίες του επιπέδου θα εμφανιστεί έτσι κι αλλιώς. Εφόσον αυτή δεν έιναι η σημεριφορά που περιμένουμε, θα μπορούσαμε να χρησημοποιήσουμε server code για να κρύψουμε τα divs ελέγχοντας το πεδίο HasChildren.
Στην συγκεκριμένη περίπτωση όμως τα divs έχουν class 'True' ή 'False' ανάλογα με την περίπτωση και μπορούμε να τα κρύψουμε όταν φορτώνει η σελίδα γράφοντας στο πιο γνωστό event handler του jQuery, το $(document).ready. Επιλέγουμε με jQuery selectors τα elements με κλάση 'True' και τα κρύβουμε.
        <script type="text/javascript">
            $(document).ready(function() {
                $('.True').hide();
            });
        </script>

Ένα άλλο σημείο που αξίζει να σημειωθεί είναι οι τρεις css κλάσεις που ορίζουν την εμφάνιση των accordions, ανάλογα με το state που βρίσκεται.

jQuery $(document).ready & asp.net AJAX update panel

Συχνά στις asp.net σελίδες έχουμε update panel αλλά και javascript κώδικα που τρέχει όταν "φορτώνει" η σελίδα.
Το πρόβλημα είναι πως καθώς με το update panel έχουμε partial updates δεν τρέχει ο jQuery κώδικας που συνήθως περιέχεται στο $(document).ready.
Για να αντιμετωπίσουμε το πρόβλημα, τρέχουμε τον jQuery κώδικα στο client event που συμβαίνει όταν το update panel φορτώνει.
Πρώτα πρέπει να κάνουμε bind μια javascript μέθοδο που να τρέχει όταν κάνει refresh το update panel, και γίνεται με τον παρακάτω κώδικα:

    <script type="text/javascript">
        Sys.Application.add_init(application_init);
 
        function application_init() {
 
 
            var prm = Sys.WebForms.PageRequestManager.getInstance();
 
            prm.add_pageLoaded(prm_pageLoaded);
 
        }
    </script>
Σαν δεύτερο βήμα υλοποιούμε την μέθοδο prm_pageLoaded() που έχει γίνει registered για το load event του update panel

        function prm_pageLoaded() {
 
            // o javascript κώδικας που τρέχει με κάθε refresh 
            // του update panel
 
        }
To update panel έχει και άλλα events που τρέχουν στον client. Την επόμενη φορά...