locked
expandable/collapsible grid using CollapsiblePanelExtender and DynamicPopulateExtender RRS feed

  • Question

  • User706013099 posted

    Like many before me I have been trying to implement a tidy expandable/collapsible gridview where, for example, the grid initially shows a list of writers and on clicking on a suitable 'expand' button in a row the writer's works are dynamically retrieved from the database and displayed. Actually I have managed to get a reasonably tidy version to work using the Ajax Toolkit CollapsiblePanelExtender and DynamicPopulateExtender in combination with minimal additional Javascript. In case it is of any use to anyone, the key elements are as follows:

    <asp:GridView runat="server" ID="Writers" DataSourceID="WritersDS" DataKeyNames="PersonID" PageSize='<%$ AppSettings: GridPageSize %>' >
      <Columns>
        <asp:TemplateField ShowHeader="False" ItemStyle-VerticalAlign="Top">
          <ItemTemplate>
    	<asp:Image ID="ShowWorksButton" runat="server" />
            <ajaxToolkit:DynamicPopulateExtender ID="DPE" runat="server" PopulateTriggerControlID="ShowWorksButton" CacheDynamicResults="false" ClearContentsDuringUpdate="true" EnableViewState="False"
                ServiceMethod="GetWorks" ContextKey='<%# Eval("PersonID") %>' TargetControlID="WorksPanel" />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="writer" SortExpression="Surname" ItemStyle-Width="200" ItemStyle-VerticalAlign="Top">
          <ItemTemplate>
            <asp:Label ID="hName" runat="server" Text='<%# Eval("Name")%>' />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ItemStyle-Width="750">
          <ItemTemplate>
            <asp:Panel ID="WorksPanel" runat="server" EnableViewState="false" style="height:auto;min-height:36px;max-height:124px;overflow:auto"/>
            <ajaxToolkit:CollapsiblePanelExtender ID="CPE" ClientIDMode="Static" runat="server" TargetControlID="WorksPanel" ExpandControlID="ShowWorksButton" CollapseControlID="ShowWorksButton"
                ImageControlID="ShowWorksButton" CollapsedImage="~/images/expand.png" ExpandedImage="~/images/collapse.png"
                Collapsed="True" CollapsedSize="0" ExpandedSize="124" ScrollContents="True" AutoCollapse="False" AutoExpand="False" />
          </ItemTemplate>
        </asp:TemplateField>
      </Columns>

    And in code behind:

        <WebMethod()> _
        <ScriptMethod()> _
        Public Shared Function GetWorks(ByVal contextKey As String) As String
            Dim dal As New DAL
            Dim personid As Integer = CInt(contextKey)
            Dim html As StringBuilder = New StringBuilder
            html.Append("<table><col width='480px'</col><col width='70px'</col><col width='110px'</col><col width='35px'</col><col width='50px'</col>")
            html.Append("<tr><th style='text-align:left;'>title</th><th style='text-align:left;'>form</th><th style='text-align:left;'>genre</th><th>written</th><th>owned</th></tr>")
            Dim works As List(Of LiteraryWorkInfo) = dal.GetSelectedWorksByWriter(personid)
            Dim owned As String = ""
            For Each work As LiteraryWorkInfo In works
                html.Append("<tr><td><a href='workform.aspx?id=" & work.WorkID.ToString() & "'>" & work.Title & "</a></td><td>" & work.Form & "</td><td>" & work.Genre & "</td><td style='text-align:center'>" & work.Written & "</td><td style='text-align:center'>" & work.Owned & "</td></tr>")
            Next
            html.Append("</table>")
            Return html.ToString()
        End Function
    

    It is also necessary to make the CPE IDs unique (it is probably possible to do this declaratively):

        Protected Sub WireUpWorks(ByVal s As Object, ByVal e As GridViewRowEventArgs) Handles Writers.RowCreated
            If e.Row.RowType = DataControlRowType.DataRow Then
                Dim cpe As CollapsiblePanelExtender = CType(e.Row.FindControl("CPE"), CollapsiblePanelExtender)
                Dim id As String = String.Concat("CPE", e.Row.RowIndex)
                cpe.BehaviorID = id
            End If
        End Sub
    

    And like others I have found it necessary to add some Javascript to smooth the animation (why this could not have been the default or at least easily changeable I do not know) and to provide an accordion-like effect:

    function pageLoad(sender, args) {
        for (num = 0; num < 20; num++) {
            var cpe = $find("CPE" + num);
            if (cpe) {
                cpe.add_expanding(accordion);
                cpe._animation._fps = 45;
                cpe._animation._duration = 0.4;
            }
        }
    }
    function accordion(sender, arg) {
        for (num = 0; num < 20; num++) {
            var cpe = $find("CPE" + num);
            if (cpe) {
                if (sender._expandControlID != cpe._expandControlID)
                    cpe.collapsePanel(cpe._expandControlID);
            }
        }
    }

    All of this works surprisingly well, but there are some irritating aspects which I have not been able to fix. I have limited the maximum height of the works panel in order to prevent the overall height of the grid causing vertical scrolling of the page. But what I would really like is for the CPE ExpandedSize to reflect the actual height of the panel (i.e. equivalent to 'auto'). But this does not appear possible and I have had to set ExpandedSize to the same value as the panel's maximum height (not setting ExpandSize at all has the surprising effect of causing the panel to pop out to the full size of the actual content with no animation, completely ignoring the CSS on the panel itself). As a result, the panel always expands to this height even if there is less actual content. And what is even more irritating is that there is a 'disabled' vertical scrollbar in the panel even if no scrolling is required (and if I remove ScrollContents="True" from the extender then, perhaps less surprisingly, there is no scrolling, despite the panel CSS). What I do not know is whether this is a CSS issue or something to do with the extender. Either way, I would be grateful for any suggestions how to fix this.

    Jon

    Thursday, January 30, 2014 6:08 AM

All replies

  • User2075212911 posted

    Hi jstranger,

    From your description and code, I see there is a issue with Panel control and CollapsiblePanelExtender.

    The page developer can specify whether the panel should scroll when it does not expand to the full size of its contents,

    and can also specify whether the panel expands in the height or width dimensions.

    Note: CollapsiblePanel assumes that the standard CSS box model is being used.

    Early versions of Internet Explorer didn't support that model completely, so please use the !DOCTYPE declaration

    (as found at the top of this page and enabled by default for new ASP.NET pages) to specify that the page should be rendered in IE's standards-compliant mode.

    Tuesday, February 4, 2014 2:41 AM
  • User706013099 posted

    I am using HTML5 on IE10 or later (this is a non-public web app) - i.e. <!DOCTYE html>

    Tuesday, February 4, 2014 3:25 AM