Category List Page with Links and Webpages

Store UI, layout, design, look and feel; Discussion on the customer facing pages of your online store. Cascading Style Sheets, Themes, Scriptlets, NVelocity and the components in the ConLib directory.
Post Reply
rmaweb
Commander (CMDR)
Commander (CMDR)
Posts: 118
Joined: Fri Sep 10, 2010 9:41 am

Category List Page with Links and Webpages

Post by rmaweb » Sat Mar 12, 2011 10:24 am

Hello All,

I am having a lot of difficulty for some reason when trying to customize the Category List Page conlib. I created the new ascx and ascx.cs files with the following in them. After a lot of work with it still not working, I tried to copy over the Category Details Page files and customize those to show the data I need, but it still does not function properly. To clarify, I need the products/links/webpages to display together in the sort order specified in the admin if possible. If it is not, then I guess I can settle for having them show up in their own repeaters.

If the category has no links or webpages in them, then the page loads and displays properly showing the products as intended.

If the category has links or webpages in them, then it goes to the general order page and shows the following on the frontend:

Code: Select all

We are sorry, but the page you are trying to access has experienced an error.

Please contact (*store email*) to report this problem.
And the following on the Error Log page in the backend:

Code: Select all

Exception of type 'System.Web.HttpUnhandledException' was thrown.; Object reference not set to an instance of an object.
CategoryListPagePennparts.ascx :

Code: Select all

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="CategoryListPagePennparts.ascx.cs" Inherits="ConLib_CategoryListPagePennparts" %>
    <%--
    <conlib>
    <summary>A category page that displays all contents of a category in a simple list format.  This page displays products, webpages, and links.</summary>
    <param name="DefaultCaption" default="Catalog">Caption text that will be shown as caption when root category will be browsed.</param>
    </conlib>
    --%>
    <%@ Register Src="~/ConLib/CategoryBreadCrumbs.ascx" TagName="CategoryBreadCrumbs" TagPrefix="uc" %>
    <%@ Register Src="~/ConLib/CategorySearchSidebar.ascx" TagName="CategorySearchSidebar" TagPrefix="uc" %>
    <%@ Register Src="~/ConLib/AddToCartLinkPenn.ascx" TagName="ProductDetailsLink" TagPrefix="uc" %>
    <ajax:UpdatePanel ID="ResultsAjaxPanel" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
        <asp:PlaceHolder ID="CategoryHeaderPanel" runat="server" EnableViewState="false">
            <uc:CategoryBreadCrumbs id="CategoryBreadCrumbs1" runat="server" HideLastNode="True" />
            <div class="pageHeader">
                <h1><asp:Literal ID="Caption" runat="server" EnableViewState="False"></asp:Literal></h1>
            </div>
            <asp:PlaceHolder ID="SubCategoryPanel" runat="server" EnableViewState="false">
                <div class="section">
                    <div class="content">
                        <asp:Repeater ID="SubCategoryRepeater" runat="server" EnableViewState="false">
                            <SeparatorTemplate><br /></SeparatorTemplate>
                            <ItemTemplate><asp:HyperLink ID="SubCategoryLink" runat="server" Text='<%#String.Format("{0}", Eval("Name"))%>' NavigateUrl='<%#Eval("NavigateUrl")%>'></asp:HyperLink></ItemTemplate>
                        </asp:Repeater><br /><br />
                    </div>
                </div>
            </asp:PlaceHolder>
            <div >
                <asp:Literal ID="CategoryDescription" runat="server" EnableViewState="false"></asp:Literal>
            </div>            
        </asp:PlaceHolder>
        <br />
            <asp:PlaceHolder ID="phCategoryContents" runat="server">           
                <!-- Top Bar -->
                <div class="catalogWrapper" style="padding:0px;">
                    <asp:Repeater ID="CatalogNodeList" runat="server" OnItemDataBound="CatalogNodeList_ItemDataBound" EnableViewState="false">                   
                        <HeaderTemplate>
                            <table  class="pagedList" style="width: 100%;" border="0" cellspacing="1">
                                <tr>
                                    <th scope="col" style="width:130px;">Availability</th><!-- Change: add availability calls the Thumbnail -->
                                    <th scope="col" align="left">SKU</th>
                                    <th scope="col">Description</th>
                                    <th scope="col" align="center">Price</th>
                                    <th scope="col">&nbsp;</th>
                                </tr>
                        </HeaderTemplate>
                        <ItemTemplate>                       
                            <asp:PlaceHolder ID="phItemTemplate1" runat="server"></asp:PlaceHolder>
                            <td runat="server">
                                <uc:ProductDetailsLink ID="ProductDetailsLink" runat="server" Product='<%#((CatalogNode)Container.DataItem).CatalogNodeType == CatalogNodeType.Product ? ((CatalogNode)Container.DataItem).ChildObject : null %>' />
                            </td>
                            <asp:PlaceHolder ID="phItemTemplate2" runat="server"></asp:PlaceHolder>
                        </ItemTemplate>
                        <FooterTemplate>
                            </table>
                        </FooterTemplate>
                    </asp:Repeater>               
                </div>
            </asp:PlaceHolder>
            <asp:PlaceHolder ID="phEmptyCategory" runat="server" Visible="false" EnableViewState="false">
                <div class="catalogWrapper"  align="center">
                    <asp:Localize ID="EmptyCategoryMessage" runat="server" Text="The category is empty." EnableViewState="false"></asp:Localize>
                </div>
            </asp:PlaceHolder>
        </ContentTemplate>
    </ajax:UpdatePanel>
    <asp:Panel ID="RequiredParameterMissingPanel" runat="server" Visible="false" EnableViewState="false">
        <asp:Label ID="RequiredParameterMessage" runat="server" Text="{0}: Parameter(s) {1} is/are required." EnableViewState="false" SkinID="ErrorCondition"></asp:Label>
    </asp:Panel>
CategoryListPagePennparts.ascx.cs :

Code: Select all

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CommerceBuilder.Common;
using CommerceBuilder.Catalog;
using CommerceBuilder.Products;
using CommerceBuilder.Utility;

public partial class ConLib_CategoryListPagePennparts : System.Web.UI.UserControl
{
    private Category _Category;
    private CatalogNodeCollection _CatalogNodes;
    private string _DefaultCaption = "Catalog";
    private string _DefaultCategorySummary = "Welcome to our store.";

    private string _PagingLinksLocation = "BOTTOM";

    /// <summary>
    /// Name that will be shown as caption when root category will be browsed
    /// </summary>
    [Personalizable(), WebBrowsable()]
    public string DefaultCaption
    {
        get { return _DefaultCaption; }
        set { _DefaultCaption = value; }
    }

    /// <summary>
    /// Summary that will be shown when root category will be browsed
    /// </summary>
    [Personalizable(), WebBrowsable()]
    public string DefaultCategorySummary
    {
        get { return _DefaultCategorySummary; }
        set { _DefaultCategorySummary = value; }
    }

    public int CategoryId
    {
        get
        {
            if (ViewState["CategoryId"] == null)
                ViewState["CategoryId"] = PageHelper.GetCategoryId();
            return (int)ViewState["CategoryId"];
        }
        set
        {
            ViewState["CategoryId"] = value;
        }
    }

    private void BindPage()
    {
        //BIND THE DISPLAY ELEMENTS
        if (IsValidCategory())
        {
            if (_Category != null)
            {
                Page.Title = _Category.Name;
                CategoryBreadCrumbs1.CategoryId = this.CategoryId;
                Caption.Text = _Category.Name;
                CategoryDescription.Text = (_Category.Summary != null) ? _Category.Summary : "&nbsp;";
            }
            else
            {
                // IT IS ROOT CATEGORY
                Page.Title = DefaultCaption;
                CategoryBreadCrumbs1.CategoryId = this.CategoryId;
                Caption.Text = DefaultCaption;
                CategoryDescription.Text = DefaultCategorySummary;
            }

            BindSubCategories();
        }
        else
        {
            CategoryHeaderPanel.Visible = false;
        }
        BindResultHeader();
    }

    protected void Page_Init(object sender, System.EventArgs e)
    {
        Trace.Write(this.GetType().ToString(), "Load Begin");
        //EXIT PROCESSING IF CATEGORY IS INVALID OR MARKED PRIVATE
        if (!IsValidCategory())
        {
            // SHOW ONLY THE MESSAGE THAT REQUIRED PARAMETER IS MISSING.
            ResultsAjaxPanel.Visible = false;
            RequiredParameterMissingPanel.Visible = true;
            RequiredParameterMessage.Text = String.Format(RequiredParameterMessage.Text, "CategoryDetailsPage", "CategoryId");
            return;
        }
        else
        {
            if (!Page.IsPostBack)
            {
                //REGISTER THE PAGEVIEW
                CommerceBuilder.Reporting.PageView.RegisterCatalogNode(this.CategoryId, CatalogNodeType.Category);
            }
        }

        Trace.Write(this.GetType().ToString(), "Load Complete");
    }

    protected void BindSubCategories()
    {
        CategoryCollection allCategories = CategoryDataSource.LoadForParent(this.CategoryId, true);
        List<SubCategoryData> populatedCategories = new List<SubCategoryData>();
        foreach (Category category in allCategories)
        {
            int totalItems = CatalogNodeDataSource.CountForCategory(category.CategoryId);
            if (totalItems > 0)
            {
                populatedCategories.Add(new SubCategoryData(category.CategoryId, category.Name, category.NavigateUrl, totalItems));
            }
        }
        if (populatedCategories.Count > 0)
        {
            SubCategoryPanel.Visible = true;
            SubCategoryRepeater.DataSource = populatedCategories;
            SubCategoryRepeater.DataBind();
        }
        else SubCategoryPanel.Visible = false;
    }

    public class SubCategoryData
    {
        private int _CategoryId;
        private string _Name;
        private int _ProductCount;
        private string _NavigateUrl;
        public int CategoryId { get { return _CategoryId; } }
        public string Name { get { return _Name; } }
        public int ProductCount { get { return _ProductCount; } }
        public string NavigateUrl { get { return _NavigateUrl; } }
        public SubCategoryData(int categoryId, string name, string navigateUrl, int productCount)
        {
            _CategoryId = categoryId;
            _Name = name;
            _NavigateUrl = navigateUrl;
            _ProductCount = productCount;
        }
    }

    protected void BindResultHeader()
    {
        //UPDATE THE RESULT INDEX MESSAGE       
        CatalogNodeList.DataSource = _CatalogNodes;
        CatalogNodeList.DataBind();
    }

    protected void CatalogNodeList_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
    {
        if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            //GENERATE TEMPLATE WITH HTML CONTROLS
            //TO OPTIMIZE OUTPUT SIZE
            PlaceHolder itemTemplate1 = (PlaceHolder)e.Item.FindControl("phItemTemplate1");
            PlaceHolder itemTemplate2 = (PlaceHolder)e.Item.FindControl("phItemTemplate2");

            if ((itemTemplate1 != null))
            {

                // CSS CLASS FOR THIS ROW
                String cssClass = "oddRow";
                if (e.Item.ItemIndex % 2 == 0) cssClass = "evenRow";

                itemTemplate1.Controls.Add(new LiteralControl("<tr class=\"" + cssClass + "\">"));

                CatalogNode catalogNode = (CatalogNode)e.Item.DataItem;

                string target = "_self";
                if (catalogNode.CatalogNodeType == CatalogNodeType.Link)
                    target = ((Link)catalogNode.ChildObject).TargetWindow;

                if (catalogNode.CatalogNodeType == CatalogNodeType.Product && catalogNode.ChildObject != null)
                {
                    Product product = ((Product)catalogNode.ChildObject);
                    string catalogNodeUrl = this.Page.ResolveUrl(catalogNode.NavigateUrl);

                    //OUTPUT LINKED THUMNAIL
                    string thumbnail = "&nbsp;";
                    itemTemplate1.Controls.Add(new LiteralControl("<td>"));
                    if (catalogNode.ThumbnailUrl != null) thumbnail = string.Format("<a href=\"{0}\" target=\"{3}\"><img src=\"{1}\" alt=\"{2}\" border=\"0\" class=\"Thumbnail\" width=\"100\" /></a><br />", catalogNodeUrl, ResolveUrl(catalogNode.ThumbnailUrl), catalogNode.ThumbnailAltText, target);
                    itemTemplate1.Controls.Add(new LiteralControl(thumbnail));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));

                    //OUTPUT SKU
                    String sku = "&nbsp;";
                    sku = product.Sku;
                    itemTemplate1.Controls.Add(new LiteralControl("<td>"));
                    itemTemplate1.Controls.Add(new LiteralControl(sku));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));

                    //OUTPUT LINKED NAME
                    itemTemplate1.Controls.Add(new LiteralControl("<td>"));
                    itemTemplate1.Controls.Add(new LiteralControl(string.Format("<a href=\"{0}\" class=\"highlight\" target=\"{2}\">{1}</a><br />", catalogNodeUrl, catalogNode.Name, target)));
                    itemTemplate1.Controls.Add(new LiteralControl(catalogNode.Summary));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));

                    //OUTPUT PRICE
                    itemTemplate1.Controls.Add(new LiteralControl("<td align='center'>"));
                    if (!product.UseVariablePrice && product.Price > 0)
                    {
                        string price = string.Format("<span class=\"price\">{0:ulc}</span> ", product.Price);
                        itemTemplate1.Controls.Add(new LiteralControl(price));
                    }
                    else itemTemplate1.Controls.Add(new LiteralControl("&nbsp;"));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));
                }

                if (catalogNode.CatalogNodeType == CatalogNodeType.Link || catalogNode.CatalogNodeType == CatalogNodeType.Webpage)
                {
                    //OUTPUT LINKED THUMNAIL
                    string thumbnail = "&nbsp;";
                    itemTemplate1.Controls.Add(new LiteralControl("<td>"));
                    if (catalogNode.ThumbnailUrl != null) thumbnail = string.Format("<a href=\"{0}\" target=\"{3}\"><img src=\"{1}\" alt=\"{2}\" border=\"0\" class=\"Thumbnail\" width=\"100\" /></a><br />", catalogNode.NavigateUrl, ResolveUrl(catalogNode.ThumbnailUrl), catalogNode.ThumbnailAltText, target);
                    itemTemplate1.Controls.Add(new LiteralControl(thumbnail));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));

                    itemTemplate1.Controls.Add(new LiteralControl("<td>&nbsp;</td>"));

                    //OUTPUT LINKED NAME
                    itemTemplate1.Controls.Add(new LiteralControl("<td>"));
                    itemTemplate1.Controls.Add(new LiteralControl(string.Format("<a href=\"{0}\" class=\"highlight\" target=\"{2}\">{1}</a><br />", catalogNode.NavigateUrl, catalogNode.Name, target)));
                    itemTemplate1.Controls.Add(new LiteralControl(catalogNode.Summary));
                    itemTemplate1.Controls.Add(new LiteralControl("</td>"));

                    itemTemplate1.Controls.Add(new LiteralControl("<td>&nbsp;</td>"));
                }
            }
        }
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        if (IsValidCategory())
        {
            //INITIALIZE THE CONTENT NODES
            _CatalogNodes = new CatalogNodeCollection();
            CatalogNodeCollection allNodes;
            if (_Category != null) allNodes = _Category.CatalogNodes;
            else allNodes = CatalogNodeDataSource.LoadForCategory(0);
            foreach (CatalogNode node in allNodes)
            {
                if (node.Visibility == CatalogVisibility.Public)
                {
                    bool addNode = true;
                    if (node.CatalogNodeType == CatalogNodeType.Category)
                    {
                        addNode = (CatalogDataSource.CountForCategory(node.CatalogNodeId, true) > 0);
                    }
                    if (addNode)
                    {
                        _CatalogNodes.Add(node);
                    }
                }
            }

            //BIND PAGE
            BindPage();
        }
    }

    private bool IsValidCategory()
    {

        // IF IT IS ROOT CATEGORY
        if (this.CategoryId == 0) return true;
        else
        {
            // TRY TO LOAD THE CATEGORY AGAIN
            if (_Category == null) _Category = CategoryDataSource.Load(this.CategoryId);
            if (_Category != null && _Category.Visibility != CatalogVisibility.Private) return true;
            else return false;
        }
    }
}
Last edited by rmaweb on Tue Mar 15, 2011 6:11 am, edited 1 time in total.
Ryan A.
Scott's Bait and Tackle
http://store.scottsbt.com
Work In Progress
Able Gold R10
Bootstrap 3.3

rmaweb
Commander (CMDR)
Commander (CMDR)
Posts: 118
Joined: Fri Sep 10, 2010 9:41 am

Re: Category List Page with Links and Webpages

Post by rmaweb » Sat Mar 12, 2011 10:24 am

I really appreciate any help you guys/gals can give.
Ryan A.
Scott's Bait and Tackle
http://store.scottsbt.com
Work In Progress
Able Gold R10
Bootstrap 3.3

plugables
Captain (CAPT)
Captain (CAPT)
Posts: 276
Joined: Sat Aug 15, 2009 4:04 am
Contact:

Re: Category List Page with Links and Webpages

Post by plugables » Mon Mar 14, 2011 4:26 am

Turn off custom errors in web.config and check again to see detailed error message. Alternatively you may check App_Data/Logs/app.log for the details of the error. It may help you figure out whats wrong.

rmaweb
Commander (CMDR)
Commander (CMDR)
Posts: 118
Joined: Fri Sep 10, 2010 9:41 am

Re: Category List Page with Links and Webpages

Post by rmaweb » Tue Mar 15, 2011 6:44 am

As a followup, after turning off the custom errors page and turning on the debug feature, I saw that the error came from the conlib/AddToCartLinkPenn.ascx.cs ( modeled after the AddToCartLink.ascx.cs file with changes made so it only displayed the More Details link so customers would be forced to read the product pages before buying an item ) file in the Page_PreRender method when it tried to load the product id into the product object. Since the id's being put in where link/webpage id's then it did not create the object, so when it tried to pull up the product.NavigateUrl variable, it returned the error.

I made the below changes and now it works fine:

Code: Select all

protected void Page_PreRender(object sender, EventArgs e)
    {
        Product product = ProductDataSource.Load(_ProductId);

        if (product != null) MoreDetailsLink.NavigateUrl = product.NavigateUrl;
        else MoreDetailsLink.Visible = false;
        SaveCustomViewState();
    }
Thanks plugables for mentioning the custom errors thing :)
Ryan A.
Scott's Bait and Tackle
http://store.scottsbt.com
Work In Progress
Able Gold R10
Bootstrap 3.3

Post Reply