質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • ASP.NET

    481questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

表にアコーディオンの機能を持たせたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 351

teretail

score 14

前提・実現したいこと

ASP.NETにてDBから抽出したデータを以下のように表形式で表示することを考えています。

分類名 数値
大分類 中分類の合計
中分類1 小分類a~dの合計
小分類a 数値
小分類b 数値
小分類c 数値
小分類d 数値
中分類2 小分類a'~c'の合計
小分類a' 数値
小分類b' 数値
小分類c' 数値
中分類3 小分類の合計
小分類 数値
: :

単純な表でしたら、DataSetにデータを入れて、GridViewにbindすればいいのですが、
アコーディオンにしたいという要求があります。

例えば、中分類1の行をクリックしたら、小分類が隠れ、
もう一度クリックすると再び表示されると言った具合です。
また、大分類をクリックしたら、中分類が隠れることになります。
なお、アコーディオンを開く際は、他のアコーディオンは閉じないようにしたいです。

分類名 数値
大分類 中分類の合計
中分類1 小分類a~dの合計
中分類2 小分類a'~c'の合計
小分類a' 数値
小分類b' 数値
小分類c' 数値
中分類3 小分類の合計
小分類 数値
: :

試したこと

これを実現するために以下のようなイメージで動的に画面を作ることを考えています。

<ajaxToolkit:Accordion>
  <Panes>
    <ajaxToolkit:AccordionPane>
      <Header>
        <table>            中分類
      </Header>
      <Content>
        <asp:GridView>    小分類
      </Content>
    </ajaxToolkit:AccordionPane>
  </Panes>
</ajaxToolkit:Accordion>

上記のアコーディオンを大項目のアコーディオンに入れる

<ajaxToolkit:Accordion>
  <Panes>
    <ajaxToolkit:AccordionPane>
      <Header>
        <table>                        大分類
      </Header>
      <Content>
        <ajaxToolkit:Accordion>        中分類1
        <ajaxToolkit:Accordion>        中分類2
        <ajaxToolkit:Accordion>        中分類3
      </Content>
    </ajaxToolkit:AccordionPane>
  </Panes>
</ajaxToolkit:Accordion>

これを実現するために以下のようなプログラムを書きました。

    Private Sub SetContents(ByVal control As ControlCollection, ByVal header As DataRow, ByVal content As DataTable)

        Dim accordion As AjaxControlToolkit.Accordion
        Dim accordionPane As AjaxControlToolkit.AccordionPane

        Dim table As Table
        Dim tableRow As TableRow

        Try

            ' Accordion Header
            table = New Table
            tableRow = CreateRow(header)            ' TableRowを生成する関数(省略)
            table.Controls.Add(tableRow)

            contentRows = content.Select(pattern)    ' patternは抽出条件(省略)

            If (contentRows.Length = 0) Then
                ' コンテンツなし
                control.Add(table)

            Else
                ' コンテンツあり

                accordion = New AjaxControlToolkit.Accordion
                accordion.ID = "accordion_" + header("xxx")
                accordion.ContentCssClass = "accordionContent"
                accordion.HeaderCssClass = "accordionHeader"
                accordion.RequireOpenedPane = False
                accordionPane = New AjaxControlToolkit.AccordionPane
                accordionPane.ID = "accordionPane_" + header("xxx")

                ' ヘッダー追加
                accordionPane.HeaderContainer.Controls.Add(table)

                ' コンテンツの追加は、再帰呼出しによって行う
                For Each row As DataRow In contentRows

                    SetContents(accordionPane.ContentContainer.Controls, row, content)

                Next

                ' ペインの追加
                accordion.Panes.Add(accordionPane)

                ' 作成したアコーディオンを追加する
                control.Add(accordion)

            End If

        Catch ex As Exception
            Throw
        End Try

    End Sub

より良い方法がございましたらご教授いただければ幸いです。
よろしくお願いいたします。

補足情報(言語/FW/ツール等のバージョンなど)

Visual Studio 2015
.NET Framework 4.6.2
jQuery 3.1.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2018/01/18 09:51 編集

    質問者さんの案の通り実装してみたのでしょうか? であれば、その結果はどうなりましたか? まずはそれを書いていただけませんか? 期待した結果と異なるならどこがどのように異なるのか書いてください。

    キャンセル

  • teretail

    2018/01/19 16:31

    返信が遅くなり申し訳ありません。 上記の案で実装したところ、想定通りの動きをするものはできました。 ただし、実際には分類は5段階あるため、 データが多くなると表示に時間がかかります。 より良い方法がありましたらご教授頂けたら幸いです。

    キャンセル

  • SurferOnWww

    2018/01/19 18:15

    質問者さんは解答欄に書かないで、追加情報などを書く場合は最初の質問欄に追記する形で 書いていただけませんか 。ここはそれが流儀のようですので、そうしていただけないと、スレッドが意味不明になってきます。

    キャンセル

回答 1

check解決した方法

0

関数にControlを渡してコンテンツを追加する方法から、
コンテンツを追加したControlを返す方法に変えました。
これにより、葉の部分はテーブルにまとめられるようになりましたので、若干軽量化できたと思います。

Private Function CreateAccordion(ByVal header As DataRow, ByVal content As DataRow()) As Control

    CreateAccordion = Nothing

    Dim contentDT As DataTable = Nothing
    Dim accordion As AjaxControlToolkit.Accordion
    Dim accordionPane As AjaxControlToolkit.AccordionPane
    Dim table As Table = Nothing
    Dim headerRow As TableRow
    Dim children As DataRow() = Nothing
    Dim pattern As String

    Try

        ' Accordion Header
        headerRow = CreateRow(header)               ' TableRowを生成する関数(省略)

        If ((Not content Is Nothing) AndAlso (content.Length > 0)) Then
            ' Get Children
            contentDT = content.CopyToDataTable
            pattern = "xxxx"                        ' patternは抽出条件(省略)
            children = contentDT.Select(pattern)
        End If

        If ((Not children Is Nothing) AndAlso (children.Length > 0)) Then
            ' Have children

            accordion = New AjaxControlToolkit.Accordion
            accordion.ID = "accordion_" + header("xxx")
            accordion.ContentCssClass = "accordionContent"
            accordion.HeaderCssClass = "accordionHeader"
            accordion.RequireOpenedPane = False
            accordionPane = New AjaxControlToolkit.AccordionPane
            accordionPane.ID = "accordionPane_" + header("xxx")

            ' Add Header
            table = New Table
            table.ID = "table_" + header("xxx")
            table.Controls.Add(headerRow)
            accordionPane.HeaderContainer.Controls.Add(table)

            table = Nothing

            For Each row As DataRow In children

                pattern = "xxxx"                    ' patternは抽出条件(省略)
                Dim control As Control = CreateAccordion(row, contentDT.Select(pattern))

                If (TypeOf control Is TableRow) Then
                    ' Child-Node is TableRow

                    If (table Is Nothing) Then
                        ' Table is not created yet

                        table = New Table

                    End If

                    ' Add Child-Node
                    table.Controls.Add(control)

                Else
                    ' Child-Node is Accordion

                    If (Not table Is Nothing) Then
                        ' table is created -> add first

                        accordionPane.ContentContainer.Controls.Add(table)
                        table = Nothing

                    End If

                    ' Add Child-Node
                    accordionPane.ContentContainer.Controls.Add(control)

                End If

            Next

            If (Not table Is Nothing) Then
                ' table still remain
                accordionPane.ContentContainer.Controls.Add(table)

            End If

            accordion.Panes.Add(accordionPane)
            CreateAccordion = accordion

        Else
            ' Have no children

            CreateAccordion = headerRow

        End If

    Catch ex As Exception
        Throw
    End Try

End Function


これで締めさせていただきます。
ありがとうございました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • ASP.NET

    481questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。