Page 1 of 1

AllCategories.ascx Code Help for Navigation

Posted: Fri Oct 30, 2009 7:06 am
by dappy2
I'm trying to edit the code for how the categories are pulled/displayed in the AllCategories.ascx posted by mazhar around the forums. I'm trying to get 2 different options.

Option 1:
Load & display top level categories and for the current category, load child categories. This works for root categories, but if the user goes into a sub-category, the subcategories aren't displayed. It seems like I need to do something: If current category has a parent category, load those subcategories. I'm also not on the newest version of AC7 I don't think. If that matters.
What I have:

Code: Select all

    List<CategoryData> _CategoriesList = new List<CategoryData>();
    int _CurrentCategoryId;
    protected void Page_Load(object sender, EventArgs e)
    {
        _CurrentCategoryId = PageHelper.GetCategoryId();
        CategoryCollection rootCategories = CategoryDataSource.LoadForParent(0, true);
        _CategoriesList.Clear();
        foreach (Category category in rootCategories)
        {
            CategoryData categoryData = new CategoryData();
            categoryData.Category = category;
            if (category.CategoryId == _CurrentCategoryId)
            {
                categoryData.CssClass = "category-tab active-tab";
                _CategoriesList.Add(categoryData);
                LoadChildCategories(category.CategoryId, 1);
            }
            else
            {
                categoryData.CssClass = "category-tab";
                _CategoriesList.Add(categoryData);
            }
        }
        CategoryRepeater.DataSource = _CategoriesList;
        CategoryRepeater.DataBind();
    }
 
    protected void LoadChildCategories(int categoryId, int level)
    {
        CategoryCollection childCategories = CategoryDataSource.LoadForParent(categoryId, true);

        foreach (Category childCategory in childCategories)
        {
            CategoryData categoryData = new CategoryData();
            categoryData.Category = childCategory;
            if (childCategory.CategoryId == _CurrentCategoryId)
            {
                categoryData.CssClass = "sub-category-tab active-tab";
//                LoadChildCategories(childCategory.CategoryId, 1);
                _CategoriesList.Add(categoryData);
            }
            else
            {
                categoryData.CssClass = "sub-category-tab";
                _CategoriesList.Add(categoryData);
            }
                
            //LoadChildCategories(childCategory.CategoryId, (level + 1));
        }
    }

    public class CategoryData
    {
        private Category _category;

        public Category Category
        {
            get { return _category; }
            set { _category = value; }
        }
        private string _cssClass;

        public string CssClass
        {
            get { return _cssClass; }
            set { _cssClass = value; }
        }
    }
For my other option, I've been trying to figure out how to bind the subcategories of a root category to a nested repeater. Here's the display code that I've been trying to bind:

Code: Select all

       <asp:Repeater ID="CategoryRepeater" runat="server">
        <HeaderTemplate>
            <ul class="left-nav">
        </HeaderTemplate>
        <FooterTemplate>
            </ul>
        </FooterTemplate>
        <ItemTemplate>
            <li class='<%#Eval("CssClass") %>'>
                <asp:HyperLink ID="CategoryLink" runat="server" NavigateUrl='<%#Eval("Category.NavigateUrl") %>' ToolTip='<%#Eval("Category.Summary") %>'><%#Eval("Category.Name") %></asp:HyperLink>
                <asp:Repeater ID="ChildCategoryRepeater" runat="server">
                    <HeaderTemplate>
                        <ul>
                    </HeaderTemplate>
                    <FooterTemplate>
                        </ul>
                    </FooterTemplate>
                    <ItemTemplate>
                        <li class='<%#Eval("CssClass") %>'>
                            <asp:HyperLink ID="ChildCategoryLink" runat="server" NavigateUrl='<%#Eval("Category.NavigateUrl") %>' ToolTip='<%#Eval("Category.Summary") %>'><%#Eval("Category.Name") %></asp:HyperLink></li>
                    </ItemTemplate>
                </asp:Repeater>                
                </li>
        </ItemTemplate>
    </asp:Repeater>
Thanks for any help - I've been working on this for days with little luck.
Dappy

Re: AllCategories.ascx Code Help for Navigation

Posted: Thu Nov 05, 2009 3:08 pm
by ghghgh
You need to implement the OnItemDataBound event when using nested repeaters to get the inner repeaters the data they need.

Here is some markup using nested repeaters:

Code: Select all

asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound">
    <HeaderTemplate>
        <ul>        
    </HeaderTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
    <ItemTemplate>
        <li>
            <a href='<%#Eval("NavigateUrl")%>'><%#Eval("Name")%></a>
            <asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound"> 
                <HeaderTemplate> 
                    <ul>        
                </HeaderTemplate> 
                <FooterTemplate> 
                    </ul> 
                </FooterTemplate>
                <ItemTemplate> 
                    <li>
                        <a href='<%#Eval("NavigateUrl")%>'><%#Eval("Name")%></a>
                        <asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound"> 
                            <HeaderTemplate> 
                                <ul>        
                            </HeaderTemplate> 
                            <FooterTemplate> 
                                </ul> 
                            </FooterTemplate>
                            <ItemTemplate> 
                                <li><a href='<%#Eval("NavigateUrl")%>'><%#Eval("Name")%></a></li>                                    
                            </ItemTemplate>
                        </asp:Repeater>                    
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>
</asp:Repeater>
Here is the codebehind code that makes it work:

Code: Select all

    protected void Page_Load(object sender, EventArgs e)
    {
        CategoryRepeater.DataSource = GetChildCategories(PageHelper.GetCategoryId());
        CategoryRepeater.DataBind();
    }

    protected void CategoryRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        RepeaterItem item = e.Item;
        if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
        {
            Repeater ChildRepeater = (Repeater)item.FindControl("CategoryRepeater");
            if (ChildRepeater != null)
            {
                Category category = (Category)item.DataItem;
                ChildRepeater.DataSource = GetChildCategories(category.CategoryId);
                ChildRepeater.DataBind();
            }
        }
    }

    private CategoryCollection GetChildCategories(int parentCategoryId)
    {
        CategoryCollection subCategories = CategoryDataSource.LoadForParent(parentCategoryId, true);
        return subCategories;
    }
NOTE: I'm not sure if the above code will run as-is, but that should get you headed in the right direction.

Re: AllCategories.ascx Code Help for Navigation

Posted: Tue Nov 17, 2009 11:38 am
by jattwood@nubrand.ca
I have modified the code slightly so it always shows the root of the tree all the way through. However, I notice that the code will only traverse the children to a depth of 3 nodes. How can I extend that further?

Here is the modified code:

<%@ Control Language="C#" ClassName="AllCategories" %>
<script runat="server">


protected void Page_Load(object sender, EventArgs e)
{

CategoryRepeater.DataSource = GetChildCategories(0); //PageHelper.GetCategoryId()
CategoryRepeater.DataBind();

}

protected void CategoryRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
Repeater ChildRepeater = (Repeater)item.FindControl("CategoryRepeater");
if (ChildRepeater != null)
{
Category category = (Category)item.DataItem;
ChildRepeater.DataSource = GetChildCategories(category.CategoryId);
ChildRepeater.DataBind();
}
}
}

private CategoryCollection GetChildCategories(int parentCategoryId)
{
CategoryCollection subCategories = CategoryDataSource.LoadForParent(parentCategoryId, true);
return subCategories;
}


</script>

<asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound">
<HeaderTemplate>
<ul style="margin-left:0px;">
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
<ItemTemplate>
<li>
<a href='<%#Page.ResolveUrl(Eval("NavigateUrl").ToString())%>'><%#Eval("Name")%></a>
<asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound">
<HeaderTemplate>
<ul style="margin-left:10px;">
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
<ItemTemplate>
<li>
<a href='<%#Page.ResolveUrl(Eval("NavigateUrl").ToString())%>'><%#Eval("Name")%></a>
<asp:Repeater id="CategoryRepeater" runat="server" OnItemDataBound="CategoryRepeater_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
<ItemTemplate>
<li><a href='<%#Page.ResolveUrl(Eval("NavigateUrl").ToString())%>'><%#Eval("Name")%></a></li>
</ItemTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
</asp:Repeater>

Re: AllCategories.ascx Code Help for Navigation

Posted: Tue Nov 17, 2009 11:41 am
by jattwood@nubrand.ca
Forget it, I can't see the forest for the trees, I just need to add another nested repeater....

Thanks,

jamie

Re: AllCategories.ascx Code Help for Navigation

Posted: Thu Nov 19, 2009 7:27 am
by dappy2
I actually finally got this working also. The only problem I'm having is that the CSS classes (I was using category-tab, sub-category-tab, active-tab) are no longing binding. I realize why and where it isn't doing it anymore, I just don't know how to add it back in there...