Important Notice from AspDotNetStorefront
It is with dismay that we report that we have been forced, through the action of hackers, to shut off write-access to this forum. We are keen to leave the wealth of material available to you for research. We have opened a new forum from which our community of users can seek help, support and advice from us and from each other. To post a new question to our community, please visit: http://forums.vortx.com
Results 1 to 18 of 18

Thread: Recently Viewed Products XmlPackage

  1. #1
    Rob is offline Senior Member
    Join Date
    Aug 2004
    Posts
    3,037

    Default Recently Viewed Products XmlPackage

    This is a placeholder for new thread.

    I'll write and post here an XmlPackage approach that can be used to add a "recently viewed products" list/capability to any ASPDNSF site. I've attached an example from amazon.com which shows this (I think you're familiar with this now).

    This is now a very common and useful feature on most commerce sites.

    It can be done 100% in XmlPackages (I think) with a couple DB mods/tables to add/track the data.

    I'll write it up in a few days and post it here.
    Attached Images Attached Images  
    Last edited by Rob; 03-30-2008 at 11:42 AM.
    AspDotNetStorefront
    Shopping Cart

  2. #2
    DanV's Avatar
    DanV is offline Ursus arctos horribilis
    Join Date
    Apr 2006
    Posts
    1,568

    Default

    I actually posted some of this a while back, but I am guessing that I'll get outdone on this one...

    http://forums.aspdotnetstorefront.co...ecently+Viewed

    Still, it is an interesting post as Jwolthuis came up with some other neat uses for the click tracking table.
    Last edited by ASPDNSF Staff - Jon; 04-01-2008 at 08:52 AM.

  3. #3
    Rob is offline Senior Member
    Join Date
    Aug 2004
    Posts
    3,037

    Default

    Let's see if what I come up with is any better/different LOL this will be interesting.
    AspDotNetStorefront
    Shopping Cart

  4. #4
    Rob is offline Senior Member
    Join Date
    Aug 2004
    Posts
    3,037

    Default

    Update...as soon as I get back from travel "stuff"...i'll work up a example. Sorry for the delays on this thread.
    AspDotNetStorefront
    Shopping Cart

  5. #5
    Fatgamer is offline Junior Member
    Join Date
    May 2008
    Posts
    7

    Default

    Any progress on this yet?

    (My boss is on my back to include this exact functionality! Especially one that can use cookies or session values rather than relying on the user being logged in.)

    Thanks in advance!

  6. #6
    jobta is offline Junior Member
    Join Date
    May 2008
    Posts
    7

    Default

    Quote Originally Posted by Fatgamer View Post
    Any progress on this yet?
    Thanks in advance!
    Would like to implement this. Please let us know at what stage are you now.
    ML 7.1

  7. #7
    Rob is offline Senior Member
    Join Date
    Aug 2004
    Posts
    3,037

    Default

    yeah yeah... I know...if everyone could leave me alone for 10 mins, i'd write this all up...let me try tomorrow.


    RE: "(My boss is on my back to include this exact functionality! Especially one that can use cookies or session values rather than relying on the user being logged in.)"

    we would not do it that way. those requirements are session based which we frown on. we'll use unregistered (anon) customer accounts to do this. Just clean them montly via the monthly maint action in the admin site, so they don't clutter the db over time.
    AspDotNetStorefront
    Shopping Cart

  8. #8
    jobta is offline Junior Member
    Join Date
    May 2008
    Posts
    7

    Cool

    Quote Originally Posted by AspDotNetStorefront View Post
    yeah yeah... I know...if everyone could leave me alone for 10 mins, i'd write this all up...let me try tomorrow.
    .
    Hey are ready yet???? Just let us know. We don't want to duplicate efforts here. So let us know ......
    ML 7.1

  9. #9
    MarquessaX is offline Junior Member
    Join Date
    Aug 2008
    Posts
    4

    Default Anything Happening?

    We purchased this storefront with the intention to use it as a catalog only for a customer, not realizing these "amazon style" features were not yet in place. Is there any progress on the inclusion of this xml package for recently veiwed items, commonly looked at items, etc, in the module?

    I am not sure if this will fit our customers needs without it...

    thanks

    MarquessaX

  10. #10
    Jesse is offline Banned
    Join Date
    May 2008
    Posts
    1,329

    Default

    I'm on it. I should have something set up shortly that we can roll out.

  11. #11
    seasonalsin is offline Senior Member
    Join Date
    Nov 2006
    Posts
    123

    Default

    Jesse,

    Have you done anything with this?
    Shawn

    http://www.FirstChoiceMarine.com

    Currently 7.1 moving to MS9.3

  12. #12
    toofast is offline Senior Member
    Join Date
    Dec 2005
    Location
    Cherry Hill, NJ, USA
    Posts
    239

    Default

    pretty sweet feature! as far as i can tell, we can only add this xmlpackage within a product page. is there anyway to call it from the main template.ascx?

  13. #13
    JasonCorns is offline Junior Member
    Join Date
    Jan 2009
    Posts
    13

    Default Sidebar Recently Viewed Items

    so, I bastardized one of the pre-existing XML packages, and came up with this (I named the file recentmini.xml.config and saved it to Skins/Skin_1/XmlPackages):

    Code:
    <?xml version="1.0" standalone="yes" ?>
    <package version="2.1" displayname="Recently Viewed Mini" debug="false" includeentityhelper="false">
    
      
    
      <query name="RecentlyViewedProductsMini" rowElementName="Item">
        <sql>
          <![CDATA[
    	        exec dbo.aspdnsf_GetRecentlyViewedProductsMini
    				  @customerID,
              @productID,
    				  @invFilter,
    				  @RecentlyViewedProductsNumToDisplay		   
                ]]>
        </sql>
        <queryparam paramname="@customerID" paramtype="system" requestparamname="CustomerID" sqlDataType="int" defvalue="0"  validationpattern="" />
        <queryparam paramname="@ProductID"  paramtype="request" requestparamname="ProductID" sqlDataType="int" defvalue="0"  validationpattern="^\d{1,10}$" />
        <queryparam paramname="@invFilter" paramtype="appconfig" requestparamname="HideProductsWithLessThanThisInventoryLevel" sqlDataType="int" defvalue="1"  validationpattern="" />
        <queryparam paramname="@RecentlyViewedProductsNumToDisplay"	paramtype="appconfig" requestparamname="RecentlyViewedProductsMini.NumberDisplayed" sqlDataType="int" defvalue="3" validationpattern="" />
      </query>
    
    
      <PackageTransform>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                            xmlns:aspdnsf="urn:aspdnsf" exclude-result-prefixes="aspdnsf">
          <xsl:output method="html" omit-xml-declaration="yes" />
    
          <xsl:param name="RecentlyViewedProducts.NumberDisplayed" select="aspdnsf:AppConfig('RecentlyViewedProducts.NumberDisplayed')"></xsl:param>
          <xsl:param name="RecentlyViewedProductsGridColWidth" select="aspdnsf:AppConfig('RecentlyViewedProductsGridColWidth')"></xsl:param>
    
    
          <xsl:template match="/">
            <xsl:param name="encloseInTab" select="aspdnsf:EvalBool(/root/Runtime/EncloseInTab)" />
            <xsl:param name="productID" select="/root/runtime/productid" />
    
            <xsl:choose>
              <xsl:when test="count(/root/RecentlyViewedProductsMini/Item) &gt; 0">
                <table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-style: solid; border-width: 0px; border-color: #{aspdnsf:AppConfig('HeaderBGColor')};" >
                  <tr>
                    <td align="left" valign="top">
                      <img src="{aspdnsf:LocateImageURL(concat('/skins/Skin_', /root/System/SkinID, '/images/site/recentlyViewed.gif'))}" border="0"/>
    
    
                      <table width="100%" cellpadding="0" cellspacing="0" border="0">
    
                        <xsl:if test="$encloseInTab = true()">
                          <xsl:attribute name="style">
                            <xsl:value-of select="aspdnsf:AppConfig('BoxFrameStyle')"/>
                          </xsl:attribute>
                        </xsl:if>
    
    
                        <tr>
                          <td align="left" valign="top" class="RelatedProductsBoxStyle">
                            <p>
                              <b>
                                <xsl:value-of select="/root/Runtime/teaser" />
                              </b>
                            </p>
                            <xsl:choose>
                              <xsl:when test="aspdnsf:StrToLower(aspdnsf:AppConfig('RecentlyViewedProducts.ProductsFormat')) = 'grid'">
                                <xsl:apply-templates select="/root/RecentlyViewedProductsMini/Item" />
                              </xsl:when>
                              <xsl:otherwise>
                                <table width="100%" cellpadding="0" cellspacing="0">
                                  <xsl:for-each select="/root/RecentlyViewedProductsMini/Item">
                                    <xsl:variable name="pName" select="aspdnsf:GetMLValue(Name)"></xsl:variable>
                                    <xsl:variable name="pSEAltText" select="aspdnsf:GetMLValue(SEAltText)"></xsl:variable>
                                    <xsl:variable name="AltText">
                                      <xsl:choose>
                                        <xsl:when test="$pSEAltText=''">
                                          <xsl:value-of select="$pName" />
                                        </xsl:when>
                                        <xsl:otherwise>
                                          <xsl:value-of select="$pSEAltText" />
                                        </xsl:otherwise>
                                      </xsl:choose>
                                    </xsl:variable>
                                    <tr>
                                      <td width="100%">
                                        <table width="100%" cellpadding="0" cellspacing="0">
                                          <tr>
                                            <td valign="center" style="padding-left:4px; text-align:center;">
                                              <a href="/{aspdnsf:ProductLink(ProductID, SEName, 0, '')}">
                                                <img src="/{aspdnsf:ProductImageUrl(ProductID, imageFilenameOverride, SKU, 'icon', 0)}" border="0"  width="125"></img>
                                              </a>*
                                            </td>
                                          </tr>
                                          <tr>
                                            <td width="100%" style="padding:4px;">
                                              <table width="100%" cellpadding="0" cellspacing="0">
                                                <tr>
                                                  <td style="text-align:center;">
                                                    <a href="/{aspdnsf:ProductLink(ProductID, SEName, 0, '')}">
                                                      <xsl:value-of select="aspdnsf:GetMLValue(Name)" disable-output-escaping="yes" />
                                                    </a>
                                                  </td>
                                                </tr>
                                                <tr>
                                                  <td>
                                                    <span class="a2">
                                                      <xsl:value-of select="aspdnsf:GetMLValue(Description)" disable-output-escaping="yes" />
                                                    </span>
                                                  </td>
                                                </tr>
                                                <tr>
                                                  <td>
                                                    <xsl:if test="aspdnsf:AppConfigBool('DisplayOutOfStockProducts') = 'true'">
                                                      <xsl:value-of select="aspdnsf:DisplayProductStockHint(ProductID,'Product')" disable-output-escaping="yes" />
                                                    </xsl:if>
                                                  </td>
                                                </tr>
                                              </table>
                                            </td>
                                          </tr>
                                        </table>
                                        <xsl:if test="position() != last()">
                                          <hr size="1" class="LightCellText"/>
                                        </xsl:if>
                                      </td>
                                    </tr>
                                  </xsl:for-each>
                                </table>
                              </xsl:otherwise>
                            </xsl:choose>
    
                          </td>
                        </tr>
                      </table>
                    </td>
                  </tr>
                </table>
              </xsl:when>
              <xsl:otherwise>
                <xsl:if test="$encloseInTab != true()">
                  <div style="height : 200px; padding-top: 20px; padding-left: 20px">
                    <xsl:value-of select="aspdnsf:StringResource('showproduct.aspx.42')" disable-output-escaping="yes" />
                  </div>
                </xsl:if>
              </xsl:otherwise>
            </xsl:choose>
    
          </xsl:template>
    
          <xsl:template match="Item">
            <xsl:variable name="delta">
              <xsl:choose>
                <xsl:when test="(count(/root/RecentlyViewedProductsMini/Item) mod number($RecentlyViewedProductsGridColWidth)) = 0">0</xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="number($RecentlyViewedProductsGridColWidth)-(count(/root/RecentlyViewedProductsMini/Item) mod number($RecentlyViewedProductsGridColWidth))"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>
            <xsl:variable name="rows" select="ceiling(count(/root/RecentlyViewedProductsMini/Item) div number($RecentlyViewedProductsGridColWidth))" />
    
            <xsl:if test="$RecentlyViewedProductsGridColWidth = 1">
              <tr>
                <xsl:call-template name="ProductCell"></xsl:call-template>
                <xsl:if test="ceiling(position() div  number($RecentlyViewedProductsGridColWidth)) = $rows and $delta &gt; 0">
                  <xsl:call-template name="FillerCells">
                    <xsl:with-param name="cellCount" select="$delta" />
                  </xsl:call-template>
                </xsl:if>
              </tr>
            </xsl:if>
    
            <xsl:if test="position() mod $RecentlyViewedProductsGridColWidth = 1 and $RecentlyViewedProductsGridColWidth &gt; 1">
              <tr>
                <xsl:for-each select=". | following-sibling::*[position() &lt; $RecentlyViewedProductsGridColWidth]">
                  <xsl:call-template name="ProductCell"></xsl:call-template>
                </xsl:for-each>
                <xsl:if test="ceiling(position() div  number($RecentlyViewedProductsGridColWidth)) = $rows and $delta &gt; 0">
                  <xsl:call-template name="FillerCells">
                    <xsl:with-param name="cellCount" select="$delta" />
                  </xsl:call-template>
                </xsl:if>
              </tr>
            </xsl:if>
    
          </xsl:template>
    
          <xsl:template name="ProductCell">
    
            <xsl:param name="pName" select="aspdnsf:GetMLValue(Name)"></xsl:param>
    
            <xsl:param name="AltText">
              <xsl:choose>
                <xsl:when test="aspdnsf:GetMLValue(SEAltText)=''">
                  <xsl:value-of select="aspdnsf:GetMLValue(Name)" />
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="aspdnsf:GetMLValue(SEAltText)" />
                </xsl:otherwise>
              </xsl:choose>
            </xsl:param>
    
            <td align="center" valign="top">
              <a href="/{aspdnsf:ProductLink(ProductID, SEName, 0, '')}">
                <xsl:value-of select="aspdnsf:LookupProductImage(ProductID, ImageFileNameOverride, SKU, 'icon', 0, $AltText)" disable-output-escaping="yes"/>
              </a>
              <br/>
              <a href="/{aspdnsf:ProductLink(ProductID, SEName, 0, '')}">
                <xsl:value-of select="$pName" disable-output-escaping="yes"/>
              </a>
              <xsl:if test="aspdnsf:AppConfigBool('DisplayOutOfStockProducts') = 'true'">
                <xsl:value-of select="aspdnsf:DisplayProductStockHint(ProductID,'Product')" disable-output-escaping="yes" />
              </xsl:if>
            </td>
          </xsl:template>
    
    
          <xsl:template name="FillerCells">
            <xsl:param name="cellCount"/>
            <xsl:param name="CellWidth" select="100 div $RecentlyViewedProductsGridColWidth" />
            <td width="{$CellWidth}%">*</td>
            <xsl:if test="$cellCount > 1">
              <xsl:call-template name="FillerCells">
                <xsl:with-param name="cellCount" select="$cellCount - 1"/>
              </xsl:call-template>
            </xsl:if>
          </xsl:template>
    
    
        </xsl:stylesheet>
      </PackageTransform>
    </package>
    When combined with this Stored Procedure:
    Code:
    USE [AspDotNetStorefront]
    GO
    /****** Object:  StoredProcedure [dbo].[aspdnsf_GetRecentlyViewedProductsMini]    Script Date: 01/27/2009 19:05:32 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    
    
    
    CREATE PROCEDURE [dbo].[aspdnsf_GetRecentlyViewedProductsMini]
    	@customerID		int,
    	@productID		int,
    	@invFilter		int,
    	@recentlyViewedProductsNumToDisplay int	
        
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
    	
    	DECLARE @HideProductsWithLessThanThisInventoryLevel int,
    			@RecentlyViewedProductsEnabled varchar(10),
    			@customerGUID uniqueidentifier
    	
        -- Insert statements for procedure here
    	-- Uncomment the following lines for testing purposes
    --	select @customerID=58640
    --	select @invFilter=1
    --	select @recentlyViewedProductsNumToDisplay=3
        SELECT @RecentlyViewedProductsEnabled = CASE ConfigValue WHEN 'true' THEN 1 ELSE 0 END FROM dbo.AppConfig WITH (NOLOCK) WHERE Name = 'RecentlyViewedProducts.Enabled'
        SELECT @HideProductsWithLessThanThisInventoryLevel = CONVERT(int, ConfigValue) FROM dbo.AppConfig WITH (NOLOCK) WHERE [Name] = 'HideProductsWithLessThanThisInventoryLevel' AND ISNUMERIC(ConfigValue) = 1
        
        IF (@HideProductsWithLessThanThisInventoryLevel > @invFilter or @HideProductsWithLessThanThisInventoryLevel = -1) and @invFilter <> -1
            SET @invFilter = @HideProductsWithLessThanThisInventoryLevel 
        
        IF(@RecentlyViewedProductsEnabled = 1) BEGIN
    		SELECT @customerGUID = customerGUID FROM dbo.Customer WHERE CustomerID=@customerID
    
            SELECT  TOP (@recentlyViewedProductsNumToDisplay) p.ProductID, p.Name, p.SEName, p.SEAltText, p.imageFilenameOverride
            FROM dbo.Product p 
                join (select ProductID, max(ViewDate) LastViewDate FROM dbo.Productview pv where pv.CustomerGUID = @customerGUID and pv.ProductID <> @productID GROUP BY ProductID) v on p.ProductID = v.ProductID
                join dbo.productvariant pv WITH (NOLOCK) ON pv.ProductID = p.ProductID and pv.IsDefault = 1
                left join (SELECT variantid, SUM(quan) inventory FROM dbo.inventory GROUP BY variantid) i ON pv.variantid = i.variantid 	
            WHERE p.Deleted = 0  AND 
    	          pv.Deleted = 0 AND 
    	          p.published = 1 AND 
    	          pv.published = 1 AND
                 GETDATE() BETWEEN ISNULL(p.AvailableStartDate, '1/1/1900') AND ISNULL(p.AvailableStopDate, '1/1/2999')AND  
                 (CASE p.TrackInventoryBySizeAndColor  WHEN 1 THEN isnull(i.inventory, 0) ELSE pv.Inventory END >= @InvFilter OR @InvFilter = -1)	
            ORDER BY v.LastViewDate DESC
    
    
    	END
    END
    I can pull the recently viewed products into a compartmentalized feature that I can drop on any page, like so:

    Code:
    <div>(!XmlPackage Name="recentmini.xml.config"!)</div>
    I have this in my home and sub templates, in a side bar area. This can be extended and improved by creating a new AppConfig record to store the number of MINI recently viewed items, then swapping the new AppConfig Key name in, in place of RecentlyViewedProductsMini.NumberDisplayed - I haven't had the need to do that, yet.


    I hope this helps some of you!

  14. #14
    lenrom is offline Junior Member
    Join Date
    May 2008
    Posts
    6

    Default

    On the sql query , how can you select distinct (unique) productID's?..If I view same product again I see it 2 times.

    i tried adding "select distinct top 5"..but I get an error "The ntext data type cannot be selected as DISTINCT because it is not comparable."

    tx..

  15. #15
    JasonCorns is offline Junior Member
    Join Date
    Jan 2009
    Posts
    13

    Default

    Quote Originally Posted by lenrom View Post
    On the sql query , how can you select distinct (unique) productID's?..If I view same product again I see it 2 times.

    i tried adding "select distinct top 5"..but I get an error "The ntext data type cannot be selected as DISTINCT because it is not comparable."

    tx..
    in both the out-of-the-box SP and my version, above, the query forces a verification against that kind of action:

    Code:
    join (select ProductID, max...and pv.ProductID <> @productID...
    @productID should be passed by the XML package, as part of the queryparam set (see the @ProductID queryparam). Maybe your parameters aren't being passed in?

  16. #16
    kernel64 is offline Member
    Join Date
    Mar 2009
    Posts
    45

    Default

    How to use this function also for unregistered customer ?
    An unregistered customer has a CustomerID which is 0, and thats why donĀ“t get any data:

    exec dbo.aspdnsf_GetRecentlyViewedProducts 0, 0, 0, 20

    Is there an option to activate this?

  17. #17
    lexmicro is offline Junior Member
    Join Date
    Jan 2009
    Posts
    14

    Default

    Can anyone tell me how and where to do this from please?

  18. #18
    fabstoro is offline Junior Member
    Join Date
    Oct 2011
    Posts
    1

    Default bestsellers

    I have a cleint that need, that throws bestsellers google analytics appear in a category from the homepage, as I can relate it to the file entity.grid.xml.config ?????
    thanks!