ArtAZ

Το νέο artAZ είναι το πρώτο site που υλοποιήθηκε με τη νέα version του cms μου. Η πλατφόρμα είναι asp.net 4 και η επικοινωνία με την βάση δεδομένων γίνεται με Entity Framework 4.

Χρησημοποιήθηκαν δύο γλώσσες, το σύστημα υποστηρίζει πολλαπλές γλώσσες. Το πολυγλωσσικό σύστημα επεκτείνεται ακόμα και στις RSS τροφοδοσίες.

Η εφαρμογή απαρτίζεται από την βασική λειτουργία δυναμικής διαχείρισης σελίδων και περιοχών, φόρμας επικοινωνίας, και διαχείριση νέων.

Η διαχείριση νέων επεκτάθηκε ώστε να περιλαμβάνει διάφορες κατηγορίες και "ειδικό βάρος" των αναρτήσεων. Με αυτό τον τρόπο καθώς οι συντάκτες εισάγουν άρθρα, και χαρακτηρίζοντάς τα με διάφορες παραμέτρους αυτά παίρνουν την θέση τους και σε σελίδες και λίστες. Το σύστημα νέων εμπλουτίστηκε με μηχανισμό διαχείρισης σχολίων ώστε να υπάρχει και μια μηχανή blog. Στις σελίδες του blog χρησημοποίησα τον πλούτο του περιεχομένου ενφανίζοντας στο back ground τα έργα τέχνης.

Πρόσθεσα έναν banner manager που υποστηρίζει, εικόνες και flash. Επίσης η διαχειριστές έχουν μηχανισμό δημιουργίας και μαζικής αποστολής news letter, με αναφορές και διαφημιστικές καμπάνιες. Επίσης στο σύστημα υπάρχει μηχανισμός διαχείρισης επαφών.

Για το project δημιούργησα μηχανισμό διαχείρισης των καλιτεχνών και των έργων τους, όπου εκμεταλεύτηκα την μηχανισμό tags που έχα για τα νέα και δεν χρειάστηκε να δημιουργήσω κατηγορίες.

Επειδή το site έχει αρκετές εικόνες και γραφικά έδωσα βάρος στο πόσο "γρήγορα" πρέπει να φορτώνουν οι σελίδες. Πολύ χρήσιμο βρήκα το νέο μοντέλο View State που υπάρχει στο asp.net 4 αλλά και τα Master Pages.

Από πλευράς client script έχει λίγο jQuery σε συμπληρωματικό ρόλο όμως.
Τα αποτελέσματα του SEO, αν και νωρίς, είναι ιδιαίτερα ικανοποιητικά, και πιστεύω πως ο χρόνος θα μας δικαιώσει.

Πλοηγηθείτε στο http://artaz.gr/el/NEWS/2010/11/3/νεο-artaz-τι-ειναι-νεο.aspx για να διαβάσετε την περιγραφή των διαχειριστών για την λειτουργικότητα του site.

Όπως θα δείτε και στα banners το e shop είναι ακόμα στο laptop μου, αλλά σύντομα θα είναι επάνω και αυτό.

Ρίξτε του μια ματιά ή και δύο, τρεις...










Διαγραφή directory σε asp.net εφαρμογή

Υπάρχουν περιπτώσεις που μια εφαρμογή πρέπει να διαγράψει ένα ολόκληρο directory και τα αρχεία ή άλλα directories που μπορεί να περιέχει.
Καλώντας την IO.Directory.Delete(path, true) που θα έπρεπε να διαγράψει το directory και τα περιεχόμενά του, γυρνάει το error: "The directory is not empty."
Για να παρακάμψω το πρόβλημα βρήκα τις εξής πολύ χρήσιμες μεθόδους:
        ''' <summary>
        ''' A method to traverse down through child directories until
        ''' we have reached the lowest level and then clean (delete) all
        ''' files before deleting the directory itself.
        ''' </summary>
        ''' <param name="di">
        ''' <remarks>All files must be deleted in a directory prior to deleting the
        ''' directory itself to prevent the following exception:
        ''' "The directory is not empty."
        ''' </param>
        ''' </remarks>
        Public Shared Sub DirectoryDeepDelete(ByVal di As DirectoryInfo)

            'If the current directory has more child directories, then continure
            'to traverse down until we are at the lowest level.  At that point all of the
            'files will be deleted.
            For Each diChild As DirectoryInfo In di.GetDirectories()
                DirectoryDeepDelete(diChild)
            Next

            'Now that we have no more child directories to traverse, delete all of the files
            'in the current directory, and then delete the directory itself.
            CleanAllFilesInDirectory(di)


            'The containing directory can only be deleted if the directory
            'is now completely empty and all files previously within
            'were deleted.
            If di.GetFiles().Count = 0 Then
                di.Delete()
            End If

        End Sub

        ''' <summary>
        ''' Iterates through all files in the directory passed into
        ''' method and deletes them.
        ''' </summary>
        ''' <param name="DirectoryToClean"/>
        ''' <remarks>It may be necessary to wrap this call in impersonation or ensure parent directory
        ''' permissions prior, because delete permissions are not guaranteed.
        ''' </remarks>
        Public Shared Sub CleanAllFilesInDirectory(ByVal DirectoryToClean As DirectoryInfo)

            For Each fi As FileInfo In DirectoryToClean.GetFiles()
                'The following code is NOT required, but shows how some logic can be wrapped
                'around the deletion of files.  For example, only delete files with
                'a creation date older than 1 hour from the current time.  If you
                'always want to delete all of the files regardless, just remove
                'the next 'If' statement.
                If fi.CreationTime < Now.Subtract(New TimeSpan(0, 0, 1)) Then
                    'Read only files can not be deleted, so mark the attribute as 'IsReadOnly = False'
                    fi.IsReadOnly = False
                    fi.Delete()

                    'On a rare occasion, files being deleted might be slower than program execution, and upon returning
                    'from this call, attempting to delete the directory will throw an exception stating it is not yet
                    'empty, even though a fraction of a second later it actually is.  Therefore the 'Optional' code below
                    'can stall the process just long enough to ensure the file is deleted before proceeding. The value
                    'can be adjusted as needed from testing and running the process repeatedly.
                    System.Threading.Thread.Sleep(50)  '50 millisecond stall (0.05 Seconds)
                End If
            Next
        End Sub
Τώρα κάθε φορά που η εφαρμογή χρειάζεται να σβήσει ένα directory καλώ την DirectoryDeepDelete περώντας ένα αντικέιμενο DirectoryInfo.

iPhone vs Android vs Blackberry

Microsoft & jQuery


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

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

Οι 40 άνθρωποι που άλλαξαν το internet


Γνωρίστε τους στο παρακάτω άρθρο.

Το domain που "τρέχει" μια asp.net σελίδα

Request.Url.Scheme & Uri.SchemeDelimiter & Request.Url.Host

HTML 5 & asp.NET τώρα!


Πολλοί θα πουν πως είναι ακόμα νωρίς για HTML 5. Εγώ λέω πως ο καιρός να ασχοληθούμε με το HTML 5 είναι τώρα.
Όσοι αναπτύσουν εφαρμογές σε asp.NET ξέρουν πως δεν υπάρχει αυτή η δυνατότητα "out of the box" στο Visual Studio 2010.
Ένας τρόπος που βρήκα να αναπτύσω εφαρμογές σε  HTML 5 με το Visual Studio 2010, είναι ο ακόλουθος.
Καταρχήν χρειάζονται δύο αρχεία που μπορείτε να κατεβάσετε ελεύθερα, τουλάχιστον σε αυτή την υλοποίηση.
Πρώτα το Modernizr που βασικά εξασφαλίζει ότι οι browsers θα αναγνωρίσουν τα νέα tags αλλά και άλλες δυνατότητες για CSS compatiobility.
Επειδή "by default" αυτά τα νέα tags ρεντάρονται σαν inline elements, η λύση στο πρόβλημα έρχεται από το html5doctor.com Reset Stylesheet.
Γενικώς χρησημοποιώ nested master pages, και δεν θα κάνω εξαίρεση τώρα. Έτσι εφόσον έφτιαξα ένα νέο web site στο Visual Studio 2010 και συμπεριέλαβα το css και το script που ανέφερα παραπάνω, προσέθεσα ένα master page με το όνομα html5base.master που είναι το παρακάτω mark up.

<%@ Master Language="VB" CodeFile="html5base.master.vb" Inherits="masters_html5base" %>
 
<!doctype html>
<html lang="en">
<head runat="server">
    <meta charset="utf-8" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
    <meta name="author" content="mitsbits" />
    <meta name="viewport" content="width=device-width; initial-scale=1.0" />
    <!--scripts-->
    <script src='<%= Page.ResolveUrl("~/scripts/jquery-1.4.3.js") %>' type="text/javascript"></script>
    <script src='<%= Page.ResolveUrl("~/scripts/modernizr-1.5.min.js") %>'
        type="text/javascript"></script>
    <!--css-->
    <link href='<%= Page.ResolveUrl("~/Styles/html5reset.css")%>' rel="stylesheet"
        type="text/css" />
</head>
<body>
    <form id="baseform" runat="server">
    <div id="container">
        <asp:ContentPlaceHolder ID="contentwrapper" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>
Τα πράγματα όπως βλέπετε είναι πολύ απλά, δύο place holders, ο ένας στο head και ο άλλος για το περιεχόμενο της σελίδας. Καταρχήν, αυτό αρκεί για να φτιάξει κάποιος μια asp.NET φόρμα με HTML 5 mark up.
Για να δώσω μια βασική δομή και ομοιομορφία στην εφαρμογή προσέθεσα άλλο ένα master page, το html5content.master που είναι το mark up που ακολουθεί.

<%@ Master Language="VB" MasterPageFile="~/masters/html5base.master" AutoEventWireup="false"
    CodeFile="html5content.master.vb" Inherits="masters_html5content" %>
 
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
    <!--css-->
    <link href='<%= Page.ResolveUrl("~/styles/html5main.css")%>' rel="stylesheet"
        type="text/css" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="contentwrapper" runat="Server">
    <header>
    <asp:ContentPlaceHolder ID="header" runat="server">
    
    </asp:ContentPlaceHolder>
    </header>
    <nav>
    <asp:ContentPlaceHolder ID="navigation" runat="server">
    </asp:ContentPlaceHolder>   
    </nav>
    <section id="maincontent" role="main">
    <asp:ContentPlaceHolder ID="maincontent" runat="server">
    </asp:ContentPlaceHolder>   
    </section>
    <footer>
    <asp:ContentPlaceHolder ID="footer" runat="server">
    </asp:ContentPlaceHolder>
    </footer>
</asp:Content>
To Visual Studio θα παραπονεθεί για τα tags δεν υποστηρίζονται στο HTML 4, αλλά δεν υπάρχει σφάλμα. Προσέξτε ότι προσθέτω και άλλο ένα stylesheet για την βασική μορφοποίηση των σελίδων. Από εδώ και πέρα όποια σελίδα χρησημοποιεί σας master page το html5content.master υποστηρίζει τα νέα HTML 5 tags. Για την ιστορία ορίστε το html5main.css
nav{float:leftwidth:20%;}
section #maincontent  {float:rightwidth:79%;}
footer {clear:both;}

asp.net checkbox που κάνει updates μέσα σε gridview ή κάποιο άλλο databound list container

Συχνά όταν έχουμε ένα databound list container χρειάζεται να κάνουμε ένα γρήγορο update χωρίς να μπει το control σε edit mode.
Αυτό το επιτυγχάνουμε εύκολα με buttons ή link buttons που έχουν τις ιδιότητες CommandName & CommandArgument και γράφουμε κώδικα στο event ItemCommand του control.
Σπάνια αυτό το funcionality είναι αρκετό, και το συνηθέστερο control που χρησημιοποιύμε σε τέτοιες περιπτώσεις είναι το checkbox.
Το checkbox όμως δεν έχει ιδιότητες CommandName & CommandArgument. Άρα δεν υπάρχει το event ItemCommand και είναι πολύ δύσκολο να βρούμε σε ποια γραμμή είναι το checkbox που ξεκινάει το update.

Λύση
Όταν το checkbox ρεντάρεται σαν html δημιουργεί ένα <input type=checkbox /> και ένα <label/>. Μπορούμε να εκμεταλευτούμε αυτό το χαρακτηριστικό για να πετύχουμε το functionality που επιθυμούμε.
Πρώτα θα φτιάξουμε μια css κλάση που θα την ονομάσουμε για το παράδειγμα chkHidden   .chkHidden labeldisplay:none;}Αυτό σημαίνει πως αν ένα html element με αυτήν την κλάση εμπεριέχει ένα tag label, το label δεν θα εμφανιστεί.
Προσθέτουμε το checkbox στο gridview (ή σε κάποιο άλλο list container).
Του δίνουμε CssClass="chkHidden" Το πεδίο που είναι το κλειδί στην γραμμή το κάνουμε databind στο text property του checkbox.
Το πεδίο που θέλουμε να αλλάξουμε το κάνουνουμε databind στο checked property του checkbox.
Δίνουμε AutoPostBack=True στο checkbox.

Τώρα το marckup του control πρέπει να μοιάζει κάπως έτσι:

<asp:CheckBox ID="ActiveCheckBox" runat="server" AutoPostBack="True" Checked='<%#Eval("Active") %>'  CssClass="chkHidden" Text='<%# Eval("Id") %>' />


Στον event handler του CheckedChanged είναι που θα κάνουμε όλη την δουλειά.
Για το παράδειγμα θα θεωρήσουμε ότι το checkbox είναι σε ένα template filed ενός gridview που λέγεται lstUsers και η μέθοδος που κάνει το update λέγεται UpdateActive και δέχεται δύο παραμέτρους, το Id της γραμμής που είναι integer και το active status που είναι boolean.


    Protected Sub ActiveCheckBox_CheckedChanged(ByVal sender As Object, _
                                                ByVal e As System.EventArgs)
        'βρίσκουμε το Id από το text του checkbox που δεν είναι ορατό στο UI
        Dim i As Integer = CInt(DirectCast(sender, CheckBox).Text)
 
        'η boolean τιμή είναι το Checked του checkbox
        UpdateActive(i, DirectCast(sender, CheckBox).Checked)
 
        'καλούμε το databind του list control για να εμφανιστούν τα ενημερωμένα δεδομένα
        lstUsers.DataBind()
    End Sub

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 που βρίσκεται.