Zanořený repeater a viditelnost podřízených záznamů   otázka

ASP.NET WebForms

Zdravím všechny ASP.NET odborníky a obracím se na Vás s dotazem. S ASP.NET začínám a po přečtení několika základních tutoriálů jsem si začal psát jednoduchou evidenci své knihovny. V databázi mám dvě tabulky - autori a knihy. Má představa je taková, že na obrazovce vlevo budu mít přehled autorů a když na některého z autorů kliknu, zobrazí se mi pod ním přehled jeho děl, když kliknu na název knihy, vpravo se zobrazí nějaká anotace. Řeším tu "navigační" část vlevo pomocí dvou zanořených repeaterů, takže se mi zobrazí všichni autoři a pod nimi všechny jejich díla, což je dost nepřehledné a především tento seznam je poměrně dlouhý. Můj kód nyní vypadá takto:

<asp:SqlDataSource ID="sqlAutori" runat="server"
    ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
    SelectCommand="SELECT * FROM [autori] ORDER BY [jmeno]">
</asp:SqlDataSource>

<asp:Repeater ID="repAutori" runat="server" DataSourceID="sqlAutori">
    <HeaderTemplate><ul></HeaderTemplate>
    <ItemTemplate>
        <li>
            <asp:HyperLink ID="hlAutor" runat="server" 
                navigateurl='~/Default.aspx?autor=<%# Eval("id").ToString()) %>'
                Text='<%# Eval("jmeno") %>' />

            <asp:Label ID="lblAutor" runat="server"
                Visible="False" Text='<%# Eval("id") %>' />

            <asp:SqlDataSource ID="sqlKnihy" runat="server" 
                ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
                SelectCommand="SELECT * FROM knihy WHERE autor = @autor) ORDER BY nazev">
                <SelectParameters>
                    <asp:ControlParameter ControlID="lblAutor" Name="autor" PropertyName="Text" Type="Int32" />
                </SelectParameters>
            </asp:SqlDataSource>

            <asp:Repeater ID="repKnihy" runat="server" DataSourceID="sqlKnihy">
                <HeaderTemplate><ul></HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="hlNabidka" runat="server"
                            NavigateUrl='~/Default.aspx?kniha=<%# Eval("id").ToString()) %>'
                            Text='<%# Eval("nazev") %>' />
                    </li>
                </ItemTemplate>
                <FooterTemplate></ul></FooterTemplate>
            </asp:Repeater>

        </li>
    </ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

Nyní se konečně dostávám k problému - jak to udělat, aby se mi nejprve zobrazil jen seznam autorů a až po kliknutí na autora (otevřu tutéž stránku s parametrem autor = id) a podle hodnoty vyzvednutou z QueryStringu říci repeateru repKnihy, jestli se má zobrazit nebo ne. Původně jsem to chtěl udělat pomocí vlastnosti Visible toho repeateru, kde bych zavolal jednoduchou třídu s parametrem hodnoty aktuálního id autora z nadřazeného repateru a v této třídě ji porovnal s hodntou id autora získanou z QueryStringu a na základě toho vrátil true/false. Ovšem nevím jak tu hodnotu id autora z nadřazeného repateru tam dostat, pokud použiju Eval("id") háže mi to chybu:

Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

Poradíte někdo jak na to?

Díky

Dave

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravim,

Bud vyrendrujete vsechny autory a vsechny knihy jak to mate a zobrazeni vyresite javascriptem. Po kliknuti se javascriptem bude rozbalovat prislusne knihy autora.

Nebo pokud chcete zobrazit knihy podle autora s parametrem (QueryString). Odeberte DataSourceID z repKnihy, protoze neni potreba vybirat vsechny knihy pro vsechny autory.

Vytvorte udalost OnItemDatabound na repAutori, do ktere date podminku, jeslti je hodnota z QueryString stejna jako jako vybrana hodnota z tabulky autori. Pak uz jen najdete pres e.Item.FindControl vas SqlDataSource sqlKnihy a Repeater repKnihy a nabindujete data.

Melo by to vypadat priblizne takto:

    
    DataRowView drw = e.Item.DataItem as DataRowView;

    if (Request.QueryString["IdAutor"] == drw["IdAutor"])
    {
        SqlDataSource sqlDS = e.Item.FindControl("sqlKnihy") as SqlDataSource 
        Repeater rp = e.Item.FindControl("repKnihy") as Repeater 

        rp.DataSource = sqlDS.Select(DataSourceSelectArguments.Empty);
        rp.DataBind();

    }

Snad vam to pomuze

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je potřeba si rozmyslet, jestli není autorů a knih moc a jestli je možné je stáhnout všechny najednou. Pokud těch dat není tolik (řádově jednotky kB), doporučoval bych nechat kód tak, jak je, a k zobrazení / schování sekcí použít jQuery.

Před odkaz dejte něco jako

<a href="#" onclick="$(this).parents('li:first').find('ul').slideToggle(200);">+</a>

A ve vnitřním repeateru nastavte do headertemplate tohle:

<ul style="display: none">

Ten jednoduchý kousek jQuery najde rodičovský element li ve stránce relativně k sobě samotnému, uvnitř něj najde element ul a slideToggle ten element zobrazí/schová s jednoduchou animací.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback