locked
Reduce the number of clicks to see product details on my website. Help required RRS feed

  • Question

  • User665067954 posted

    I have a website with Departments, Categories within Departments and then Products within Categories.

    Homepage http://www.lingerie-luxury.co.uk/Default.aspx

    From the home page, the user clicks on the Department, to show the Categories, and then from the list of Categories, the user clicks on a specific category to see a list of products. See link below to the Grayca category.

    http://www.lingerie-luxury.co.uk/Catalog2.aspx?DepartmentId=4&CategoryId=45

    From the list of products, the user then selects a product and this goes to a new page where the size, colour etc options are shown.

    I want to remove the Catalog2 page showing the list of products in each category. Instead when the user clicks on the cateogry to see the list of products, I want it to go to the Product page (showing the main product ie Bra) and then the remaining products shown underneath in a datalist.

    The link below is an example of the layout im trying to achieve.

    http://www.alterego-lingerie.com/product.php?id=2497&brand=19

     I don't want a middle page showing the list of products in a category, I want to show the main product in a category and then the remaining products underneath. The PRODUCT table contains a field called ProductOnCatalogPromotion which I can set to TRUE and use as the main product for a particualr category.

    Can anyone help me achive this layout? Any help would be greatly appreciated. I have based the website on the book "Beginning ASP.NET 2.0 E-Commerce in C# 2005" by Apres.

    I can provide the current code on my webpages.

     

    Thursday, February 2, 2012 3:42 PM

Answers

  • User3866881 posted

    Are you able to give me the code i need to loop round the data table? The stored procedure Im using is shown in my original post, it should be selecting the product id?

    foreach(DataRow row in dt.Rows)
    {
        //row["productId"]……

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 6, 2012 3:25 AM

All replies

  • User3866881 posted

    Hello:)

    As far as I see,suppose your tables are——

    1)Brand(Id,BrandName)。

    2)Category(Id,CategoryName,BrandId)。

    3)Products(Id,ProName,CategoryId,IsMain)。

    Then you can write your sql:

    select products.* from brand,category,products

    where products.IsMain=1 And brand.id=category.brandid And category.id=products.id and brand.id=@brandid

    4)Use SqlDataAdapter to fill the fetched data contents into DataTable,and then return it as a query value。

    Reguards!

    Friday, February 3, 2012 9:33 PM
  • User665067954 posted

    Decker Dong - thanks for your response.

    Since my original post I have created a stored procedure that selects a product from a category where the field OnCatalogPromotion is set to TRUE.  See stored procedure below.

    ALTER PROCEDURE GetProductsCatalogPromotion
    (@CategoryId int,
    @DescriptionLength int)
    AS
    DECLARE @Products TABLE
    (ProductId int,
    Title VARCHAR(50),
    Price MONEY,
    ImageUrl VARCHAR(50),
    ImageUrl2 VARCHAR(50),
    AlterEgoRef VARCHAR(50),
    OnDepartmentPromotion bit,
    OnCatalogPromotion bit)

    INSERT INTO @Products
    SELECT DISTINCT Product.ProductId, Title, Price, ImageUrl, ImageUrl2, AlterEgoRef, OnCatalogPromotion, OnDepartmentPromotion
    FROM Product
    INNER JOIN ProductCategory ON Product.ProductId = ProductCategory.ProductId
    INNER JOIN Category ON ProductCategory.CategoryId = Category.CategoryId WHERE ProductCategory.CategoryId = @CategoryId AND OnCatalogPromotion = 1
    SELECT ProductId, Title, Price, ImageUrl, ImageUrl2, AlterEgoRef, OnCatalogPromotion, OnDepartmentPromotion
    FROM @Products

    When the user is on this page http://www.lingerie-luxury.co.uk/Catalog3.aspx?DepartmentId=4, when they click on the category, it shows the products within the category ie http://www.lingerie-luxury.co.uk/Catalog2.aspx?DepartmentId=4&CategoryId=45. I want to remove this page (Catalog2.aspx) and instead the website goers straight to the product page, showing the product where the OncatalogPromotion field is TRUE, and then the remaining products are listed underneath in a datalist.

    The problem with the design I want is the ProductId is not included in the URL. At the moment the product.aspx http://www.lingerie-luxury.co.uk/Product.aspx?DepartmentId=4&CategoryId=45&ProductId=71 gets the productId from the URL and then returns the product.

    I have copied the code below from the current Product.aspx page that gets the ProductId using QueryString. The productId is also used to get the product attributes ie colour and size. Can I adapt the code below to run GetProductsCatalogPromotion and then use the ProductId to also get the Product attributes?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Data;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    public partial class Product : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            PopulateControls();
          

        }
        private void PopulateControls()
        {
            string productId = Request.QueryString["ProductId"];
            string categoryId = Request.QueryString["CategoryId"];
            string departmentId = Request.QueryString["DepartmentId"];
            string page = Request.QueryString["Page"];
            if (page == null) page = "1";
            int howManyPages = 1;
            string firstPageUrl = "";
            string pagerFormat = "";

            if (categoryId != null)
            {
               
                CategoryDetails cd = CatalogAccess.GetCategoryDetails(categoryId);
                //list10.DataSource = CatalogAccess.GetRemainingProductsInCategory(productId, categoryId);
                //list10.DataBind();
                //CategoryDetails ca = CatalogAccess.GetCategoryDetails(categoryId);
                //productTitle.Text = ca.CatName;
                firstPageUrl = Link.ToCategory(departmentId, categoryId, "1");
                pagerFormat = Link.ToCategory(departmentId, categoryId, "{0}");
            }

            ProductDetails pd;
            pd = CatalogAccess.GetProductDetails(productId);
            titleLabel.Text = pd.Title;
            descriptionLabel.Text = pd.Description;
            priceLabel.Text = String.Format("{0:c}", pd.Price);
            productImage.ImageUrl = "ProductImages/" + pd.ImageUrl2;
            this.Title = pd.Title +  " : " + LuxuryConfiguration.SiteName;
           

            DataTable attrTable = CatalogAccess.GetProductAttributes(productId);
            string prevAttributeName = "";
            string attributeName, attributeValue, attributeValueId;

            Label attributeNameLabel;
            DropDownList attributeValuesDropDown = new DropDownList();


            foreach (DataRow r in attrTable.Rows)
            {
                attributeName = r["AttributeName"].ToString();
                attributeValue = r["AttributeValue"].ToString();
                attributeValueId = r["AttributeValueId"].ToString();

                if (attributeName != prevAttributeName)
                {
                    prevAttributeName = attributeName;
                    attributeNameLabel = new Label();

                    attributeNameLabel.Text = attributeName + ": ";
                    attributeValuesDropDown = new DropDownList();
                    attrPlaceHolder.Controls.Add(attributeNameLabel);
                    attrPlaceHolder.Controls.Add(attributeValuesDropDown);
                    attributeValuesDropDown.Items.Add(new ListItem("Please Select", "0"));
                    attrPlaceHolder.Controls.Add(new HtmlGenericControl("br"));

                }

                attributeValuesDropDown.Items.Add(new ListItem(attributeValue, attributeValueId));
            }
        }
               
               
             
        protected void AddToCartButton_Click(object sender, EventArgs e)
        {
            string productId = Request.QueryString["ProductId"];
            ProductDetails pd = CatalogAccess.GetProductDetails(productId);

            string options = "";
            foreach (Control cnt in attrPlaceHolder.Controls)
            {
                if (cnt is Label)
                {
                    Label attrLabel = (Label)cnt;
                    options += attrLabel.Text;
                }

                if (cnt is DropDownList)
                {
                    DropDownList attrDropDown = (DropDownList)cnt;
                    options += attrDropDown.Items[attrDropDown.SelectedIndex] + "; ";
                }
            }
            string productUrl = Link.ToProduct(pd.productId.ToString());
            string destination = Link.ToPayPalAddItem(productUrl, pd.Title, pd.Price, options);
            Response.Redirect(destination);
        }

     

       
    }

     

    Saturday, February 4, 2012 9:29 AM
  • User3866881 posted

    Hello again:)

    Yes,I think what you can do is just use the codes I've referred to you,and you can just assign a certain brandId,it will go through the inner join and find out all the categories' products' OncatalogPromotion =True。

    Saturday, February 4, 2012 8:08 PM
  • User665067954 posted

    Ca you provide some more help?

    I already have two files set up to create a DataTable for the results of the stored procedure GetProductsCatalogPromotion. See code files below. Can you tell me where I use the SQLDataAdaptor?

    CATALOGACCESS.CS

    public static DataTable GetProductsCatalogPromotion(string categoryId)
        {
            DbCommand comm = GenericDataAccess.CreateCommand();
            comm.CommandText = "GetProductsCatalogPromotion";
            DbParameter param = comm.CreateParameter();
            param.ParameterName = "@CategoryId";
            param.Value = categoryId;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            param.ParameterName = "@DescriptionLength";
            param.Value = LuxuryConfiguration.ProductDescriptionLength;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
            return table;
        }

    GENERICDATAACCESS.CS

    public static class GenericDataAccess
    {
        static GenericDataAccess()
        {
            //TODO
        }
        public static DataTable ExecuteSelectCommand(DbCommand command)
            {

                DataTable table;
                try
                {
                    command.Connection.Open();
                    DbDataReader reader = command.ExecuteReader();
                    table = new DataTable();
                    table.Load(reader);
                    reader.Close();
                }
                ////catch (Exception ex)
                ////{
                ////    throw ex;
                ////}
                finally
                {
                    command.Connection.Close();
                }
                return table;
            }
            public static DbCommand CreateCommand()
            {
                string dataProviderName = LuxuryConfiguration.DbProviderName;
                string connectionString = LuxuryConfiguration.DbConnectionString;
                DbProviderFactory factory = DbProviderFactories.GetFactory(dataProviderName);
                DbConnection conn = factory.CreateConnection();
                conn.ConnectionString = connectionString;
                DbCommand comm = conn.CreateCommand();
                comm.CommandType = CommandType.StoredProcedure;
                return comm;

            }
            public static int ExecuteNonQuery(DbCommand command)
            {
                int affectedRows = -1;
                try
                {
                    command.Connection.Open();
                    affectedRows = command.ExecuteNonQuery();
                }
                finally
                {
                    command.Connection.Close();
                }
                return affectedRows;
            }
            public static string ExecuteScalar(DbCommand command)
            {
                string value = "";
                try
                {
                    command.Connection.Open();
                    value = command.ExecuteScalar().ToString();
                }
               
                finally
                {
                    command.Connection.Close();
                }
                return value;
            }
        }

    Sunday, February 5, 2012 6:18 AM
  • User665067954 posted

    I have had a thought. The stored procedure gets the product details including the productId. Can I add the productId as an OUTPUT as part of the DataTable below?

    public static DataTable GetProductsCatalogPromotion(string categoryId)
        {
            DbCommand comm = GenericDataAccess.CreateCommand();
            comm.CommandText = "GetProductsCatalogPromotion";
            DbParameter param = comm.CreateParameter();
            param.ParameterName = "@CategoryId";
            param.Value = categoryId;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            param.ParameterName = "@DescriptionLength";
            param.Value = LuxuryConfiguration.ProductDescriptionLength;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
            return table;
        }

     

    Sunday, February 5, 2012 9:32 AM
  • User665067954 posted

    I want to add the stored proceedure to this page below. However this page currently retrieves the ProductId from the URL, and it is also used to provide the product attributes.

    My new design will not have the productId in the URL, so I want the stored procedure GetProductsOnCatalogPromotion to run, output the productId, and then use the productId to get the product attributes further down.

    Can you provide some code that I can implement in CatalogAccess.cs file to output the productId (in the DataTable) and then in the product.aspx.cs to retrieve the productId.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Data;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    public partial class Product : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            PopulateControls();
          

        }
        private void PopulateControls()
        {
            string productId = Request.QueryString["ProductId"];
            string categoryId = Request.QueryString["CategoryId"];
            string departmentId = Request.QueryString["DepartmentId"];
            string page = Request.QueryString["Page"];
            if (page == null) page = "1";
            int howManyPages = 1;
            string firstPageUrl = "";
            string pagerFormat = "";

            if (categoryId != null)
            {
                CategoryDetails cd = CatalogAccess.GetCategoryDetails(categoryId);
                firstPageUrl = Link.ToCategory(departmentId, categoryId, "1");
                pagerFormat = Link.ToCategory(departmentId, categoryId, "{0}");
            }

            ProductDetails pd;
            pd = CatalogAccess.GetProductDetails(productId);
            titleLabel.Text = pd.Title;
            descriptionLabel.Text = pd.Description;
            priceLabel.Text = String.Format("{0:c}", pd.Price);
            productImage.ImageUrl = "ProductImages/" + pd.ImageUrl2;
            this.Title = pd.Title +  " : " + LuxuryConfiguration.SiteName;
           

            DataTable attrTable = CatalogAccess.GetProductAttributes(productId);
            string prevAttributeName = "";
            string attributeName, attributeValue, attributeValueId;

            Label attributeNameLabel;
            DropDownList attributeValuesDropDown = new DropDownList();


            foreach (DataRow r in attrTable.Rows)
            {
                attributeName = r["AttributeName"].ToString();
                attributeValue = r["AttributeValue"].ToString();
                attributeValueId = r["AttributeValueId"].ToString();

                if (attributeName != prevAttributeName)
                {
                    prevAttributeName = attributeName;
                    attributeNameLabel = new Label();

                    attributeNameLabel.Text = attributeName + ": ";
                    attributeValuesDropDown = new DropDownList();
                    attrPlaceHolder.Controls.Add(attributeNameLabel);
                    attrPlaceHolder.Controls.Add(attributeValuesDropDown);
                    attributeValuesDropDown.Items.Add(new ListItem("Please Select", "0"));
                    attrPlaceHolder.Controls.Add(new HtmlGenericControl("br"));

                }

                attributeValuesDropDown.Items.Add(new ListItem(attributeValue, attributeValueId));
            }
        }
               
               
             
        protected void AddToCartButton_Click(object sender, EventArgs e)
        {
            string productId = Request.QueryString["ProductId"];
            ProductDetails pd = CatalogAccess.GetProductDetails(productId);

            string options = "";
            foreach (Control cnt in attrPlaceHolder.Controls)
            {
                if (cnt is Label)
                {
                    Label attrLabel = (Label)cnt;
                    options += attrLabel.Text;
                }

                if (cnt is DropDownList)
                {
                    DropDownList attrDropDown = (DropDownList)cnt;
                    options += attrDropDown.Items[attrDropDown.SelectedIndex] + "; ";
                }
            }
            string productUrl = Link.ToProduct(pd.productId.ToString());
            string destination = Link.ToPayPalAddItem(productUrl, pd.Title, pd.Price, options);
            Response.Redirect(destination);
        }

     

       
    }

    Sunday, February 5, 2012 10:39 AM
  • User3866881 posted

    I have had a thought. The stored procedure gets the product details including the productId. Can I add the productId as an OUTPUT as part of the DataTable below?

    public static DataTable GetProductsCatalogPromotion(string categoryId)
        {
            DbCommand comm = GenericDataAccess.CreateCommand();
            comm.CommandText = "GetProductsCatalogPromotion";
            DbParameter param = comm.CreateParameter();
            param.ParameterName = "@CategoryId";
            param.Value = categoryId;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            param.ParameterName = "@DescriptionLength";
            param.Value = LuxuryConfiguration.ProductDescriptionLength;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
            return table;
        }

    Hello again:)

    Your logic codes look right,and please make sure that your stored procdure has the productId column,then you can use foreach to loop each DataRow inside and then get the productId。

    Reguards!

    Sunday, February 5, 2012 8:31 PM
  • User665067954 posted
    Are you able to give me the code i need to loop round the data table? The stored procedure Im using is shown in my original post, it should be selecting the product id?
    Monday, February 6, 2012 3:21 AM
  • User3866881 posted

    Are you able to give me the code i need to loop round the data table? The stored procedure Im using is shown in my original post, it should be selecting the product id?

    foreach(DataRow row in dt.Rows)
    {
        //row["productId"]……

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 6, 2012 3:25 AM
  • User665067954 posted

    Decker Dong - I need your help again.

    I have updated the CatalogAccess.cs file below with the code that you suggested to get the productId. I have stopped the code and can see that the productId is being assigned correctly.

    The final piece code below is calling the stored procedure GetProductsCatalogPromotion from Product.aspx.cs. This page displays the product details, along with size and colour options. I have created a new variable to assign the productId from GetProductsCatalogPromotion dataTable. However im get an error on the line highlighted in bold below. The error is "Cannot implicitly convert type 'System.Data.DataTable to CatalogProm"

    Can you tell me what is causing the error?

    CATALOGACCESS.CS file

    public struct CatalogProm
    {
        public string productId;
    }

    ------------------------------------------------------------------------------------

    public static DataTable GetProductsCatalogPromotion(string categoryId)
        {
            DbCommand comm = GenericDataAccess.CreateCommand();
            comm.CommandText = "GetProductsCatalogPromotion";
            DbParameter param = comm.CreateParameter();
            param.ParameterName = "@CategoryId";
            param.Value = categoryId;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
            param = comm.CreateParameter();
            param.ParameterName = "@DescriptionLength";
            param.Value = LuxuryConfiguration.ProductDescriptionLength;
            param.DbType = DbType.Int32;
            comm.Parameters.Add(param);
           
            DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
            CatalogProm details = new CatalogProm();
            foreach (DataRow row in table.Rows)
            {
                details.productId = table.Rows[0]["productId"].ToString();
            }

            return table;

    ------------------------------------------------------------------------------------------------------------------

    PRODUCT.ASPX.CS file

    private void PopulateControls()
        {
            string categoryId = Request.QueryString["CategoryId"];
            string departmentId = Request.QueryString["DepartmentId"];
            string page = Request.QueryString["Page"];
            if (page == null) page = "1";
            int howManyPages = 1;
            string firstPageUrl = "";
            string pagerFormat = "";

            if (categoryId != null)
            {
                CategoryDetails cd = CatalogAccess.GetCategoryDetails(categoryId);
                CatalogProm cp = CatalogAccess.GetProductsCatalogPromotion(categoryId);
                string productId = cp.productId;
                         

    Tuesday, February 7, 2012 3:26 PM
  • User3866881 posted

    The error is "Cannot implicitly convert type 'System.Data.DataTable to CatalogProm"

    This problem means that you cannot convert a DataTable to a model class……So plz use DataTable or use SqlDataReader to read values from the table or something like this,and create new instances of classes and assign them one by one。

    Tuesday, February 7, 2012 9:43 PM
  • User665067954 posted
    I think you need to spell it out to me. Could you rewrite the code above that needs changing? Thank you.
    Thursday, February 9, 2012 3:13 AM
  • User3866881 posted

    I think you need to spell it out to me. Could you rewrite the code above that needs changing? Thank you.

    Snippet of codes are:

    public List<Catelog> GetProductCatelogPromotionList(int cid)
    {
        DataTable dt = GetProductCatelogPromotion(id); //DataTable returned
        List<Catelog> catelogs = new List<Catelog>();
        foreach(DataRow row in dt.Rows)
        {
           Catelog c = new Catelog{new Catelog{Id=row["xx"],Name=row["xx"]};
           catelogs.Add(c);
        }
        return catelogs;
    }


    Thursday, February 9, 2012 3:24 AM
  • User665067954 posted

    Does your code replace my code below?

    DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);
            CatalogProm details = new CatalogProm();
            foreach (DataRow row in table.Rows)
            {
                details.productId = table.Rows[0]["productId"].ToString();
            }

            return table;

     

    Or does it go into the page that is reading the dataTable ie Product.aspx.cs?

    Thursday, February 9, 2012 7:37 AM
  • User665067954 posted

    Decker Dong - I have been trying to implement the code that you gave me but im just really confused. Im getting more confused because I don't know where I should be implementing the code.

    I think I would understand if your code better if you used the variables from my code.

    For example

    public List<Catelog> brings up the error 'the type or namespace does not exist.

    Sorry to be a pain, but I need things explaining in more detail sometimes.

    Thank youin advance.

    Thursday, February 9, 2012 3:48 PM
  • User3866881 posted

    where I should be implementing the code.

    Just put my codes in the BLL or DLL as a static method。

    public List<Catelog> brings up the error 'the type or namespace does not exist.

    This is only an example,so plz use your own class instead,don't copy codes directly;Supporting is offering your tips and ideas,it cannot help you to finish your work or homework。

    Reguards!

    Thursday, February 9, 2012 8:24 PM