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 60 of 60

Thread: Quick Order Page

  1. #1
    IronDonut is offline Member
    Join Date
    Dec 2006
    Posts
    57

    Default Quick Order Page

    Hi everyone. I have a client that would like to implement a quick order page. The page would allow the customers to enter a series of sku numbers and quantities and those products would be automatically added to their cart.

    They're store is flat one product to one variant no sizing etc information. Just simple widgets. So there won't be any problem using a SKU as the product identifier.

    Here is an example of what they are looking for:

    http://www.shoplet.com/order/quickorder


    Thank you.

  2. #2
    mick is offline Junior Member
    Join Date
    Mar 2010
    Posts
    14

    Default

    That with a smart search autocomplete would be excellent and would also help ordering multiple products for the phone order page.

  3. #3
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    I just wrote something like this and I'm working out the bugs on it. How far have you made it in your design?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  4. #4
    esedirect is offline Senior Member
    Join Date
    Feb 2010
    Location
    Norfolk, UK
    Posts
    343

    Default

    We have done the same here: Quick Order
    http://www.esedirect.co.uk
    --------------------------------------------------------------------------
    Using MS 9.2.0.0 with the following customisations:

    Lightbox/Fancybox enlarged images;
    Auto-suggest searchbox;
    Extra product information shown only to our IP Address (such as supplier info, costs, etc.);
    Failed transactions emailed via trigger;
    Custom app to show basket contents when customer online;
    Orders pushed through to accounting systems.

    All the above without source!

  5. #5
    BFG 9000 is offline Senior Member
    Join Date
    Oct 2006
    Location
    South UK
    Posts
    882

    Default

    Quote Originally Posted by esedirect View Post
    We have done the same here: Quick Order

    Very Very Nice !!!

  6. #6
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    How does that form handle product variants? The version I've built will automatically look up the variants if there is more than one and let you choose.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  7. #7
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Quote Originally Posted by esedirect View Post
    We have done the same here: Quick Order
    How did you get the option to add another line to work without causing a post-back?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  8. #8
    jsimacek is offline Senior Member
    Join Date
    Dec 2008
    Location
    Phoenix, AZ
    Posts
    373

    Default

    Hello IronDonut, I think you are looking for our http://www.ecommercecartmods.com/p-5...torefront.aspx

    It does exactly what you need and is AJAX powered ;-)

    If not, contact Jan at jsimacek@compunix.us to customize it etc.
    Jan Simacek - Compunix, LLC
    AspDotNetStorefront trusted Devnet Partner and Reseller since 2005

    AspDotNetStorefront Mods and Add-Ons at http://www.ecommercecartmods.com/
    - Searching, Filtering and Sorting (like cSearch, Dealer Locator, Price Ranges, Blog)
    - Reports (like Cart Abandonment and Net Sales)
    - Customer Experience (like Question/Answers)
    - Site and Data Management (like Entity Product Mapper, Bulk Updaters, Make/Model/Year filters)

  9. #9
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    In order to get this to work with AsyncPostBack you have to include the following code in the page:

    Code:
    Public Overrides ReadOnly Property RequireScriptManager() As Boolean
    	Get
    		Return True
    	End Get
    End Property
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  10. #10
    IronDonut is offline Member
    Join Date
    Dec 2006
    Posts
    57

    Default

    Hi everyone. Can someone send me a link of the AJAX order page up on a live site?

  11. #11
    jsimacek is offline Senior Member
    Join Date
    Dec 2008
    Location
    Phoenix, AZ
    Posts
    373

    Default

    Sure, please email me at jsimacek@compunix.us and I will send you some sample links.

    Jan
    Jan Simacek - Compunix, LLC
    AspDotNetStorefront trusted Devnet Partner and Reseller since 2005

    AspDotNetStorefront Mods and Add-Ons at http://www.ecommercecartmods.com/
    - Searching, Filtering and Sorting (like cSearch, Dealer Locator, Price Ranges, Blog)
    - Reports (like Cart Abandonment and Net Sales)
    - Customer Experience (like Question/Answers)
    - Site and Data Management (like Entity Product Mapper, Bulk Updaters, Make/Model/Year filters)

  12. #12
    esedirect is offline Senior Member
    Join Date
    Feb 2010
    Location
    Norfolk, UK
    Posts
    343

    Default

    For all those who have asked how we did it. This code is not supported by us, even though it is ours

    We have a topic page which calls an XML package, the content, of which, is:

    Code:
    <?xml version="1.0" standalone="yes" ?>
    <package version="2.1" displayname="QuickOrder" allowengine="true" debug="false">
    
    	<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="LocaleSetting" select="/root/Runtime/LocaleSetting" />
    			<xsl:param name="CurrentPage">
    				<xsl:value-of select="/root/System/RequestedPage" />
    			</xsl:param>
    
    			<xsl:template match="/">
    			<script LANGUAGE="JavaScript" src="/jscripts/CheckItems.min.js"></script>
    			
    			<div id="eseQuickOrderContainer">
    				<form method="POST" name="QuickOrder" id="QuickOrder" action="QuickOrder.aspx?returnurl={$CurrentPage}">
    					<input name="Rows" type="hidden" value="5"/>
    					<div id="eseQuickOrder">
    						<div id="input1" class="clonedInput">
    							Order Ref: <input name="SKU1" id="SKU1" type="text" size="20" maxlength="20" class="eseSKU"/>
    							Quantity: <input name="Qty1" id="Qty1" type="text" size="3" maxlength="3" class="eseQty"/>
    						</div>
    						<div id="input2" class="clonedInput">
    							Order Ref: <input name="SKU2" id="SKU2" type="text" size="20" maxlength="20" class="eseSKU"/>
    							Quantity: <input name="Qty2" id="Qty2" type="text" size="3" maxlength="3" class="eseQty"/>
    						</div>
    						<div id="input3" class="clonedInput">
    							Order Ref: <input name="SKU3" id="SKU3" type="text" size="20" maxlength="20" class="eseSKU"/>
    							Quantity: <input name="Qty3" id="Qty3" type="text" size="3" maxlength="3" class="eseQty"/>
    						</div>
    						<div id="input4" class="clonedInput">
    							Order Ref: <input name="SKU4" id="SKU4" type="text" size="20" maxlength="20" class="eseSKU"/>
    							Quantity: <input name="Qty4" id="Qty4" type="text" size="3" maxlength="3" class="eseQty"/>
    						</div>
    						<div id="input5" class="clonedInput">
    							Order Ref: <input name="SKU5" id="SKU5" type="text" size="20" maxlength="20" class="eseSKU"/>
    							Quantity: <input name="Qty5" id="Qty5" type="text" size="3" maxlength="3" class="eseQty"/>
    						</div>
    					</div>
    					<div id="eseCheckItemsResults">
    						<div id="result1" class="ResultWrapper"></div>
    						<div id="result2" class="ResultWrapper"></div>
    						<div id="result3" class="ResultWrapper"></div>
    						<div id="result4" class="ResultWrapper"></div>
    						<div id="result5" class="ResultWrapper"></div>
    					</div>
    					<div id="eseFormButtons">
    						<img id="btnAdd" src="skins/Skin_1/images/newbuttons/addanotherrow.jpg" alt="Add Another Row" title="Add Another Row"/>
    						<img id="btnCheck" src="skins/Skin_1/images/newbuttons/checkitems.jpg" alt="Check Items" title="Check Items" onclick="checkItems(QuickOrder)"/>
    						<br/>
    						<input id="btnSubmit" type="image" border="0" src="skins/Skin_1/images/newbuttons/addtobasketdisabled.jpg" alt="Add to Basket" title="Add to Basket" disabled="disabled"/>
    					</div>
    				</form>
    			</div>
    
    			</xsl:template>
    
    		</xsl:stylesheet>
    	</PackageTransform>
    </package>
    This uses a javascript file:
    Code:
    function checkItems(form){
    
    	var i=0;
    	var rows = form.Rows.value;
    	var str = new Array;
    		for (i=1;i<=rows;i++)
    		{
    			str[i] = form[2*i-1].value.toUpperCase();
    		}
    
    	var url="/CheckItems.asp"; // this should really be a .ashx file
    	url=url+"?sid="+Math.random();
    	for(i=1;i<=rows;i++){
    		if(str[i]){
    			url = url+"&q"+i+"="+str[i];
    		}
    	}
    
    	if (window.XMLHttpRequest){
    		xmlhttp=new XMLHttpRequest();
    	}
    	else{
    		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    	}
    
    	xmlhttp.onreadystatechange=function(){
    		if (xmlhttp.readyState==4&&xmlhttp.status==200){
    			xmlDoc=xmlhttp.responseXML;
    			for (i=1;i<=rows;i++)
    			{
    				if(xmlDoc.getElementsByTagName("Body"+i)[0]){
    					document.getElementById("result"+i).innerHTML = xmlDoc.getElementsByTagName("Body"+i)[0].childNodes[0].nodeValue;
    					$("a.thickbox").fancybox();
    					$('#btnSubmit').attr('src','skins/Skin_1/images/newbuttons/addtobasket.jpg').attr('disabled','').attr('style','cursor:hand;cursor:pointer');
    				}
    				else{
    					if(str[i]){
    						document.getElementById("result"+i).innerHTML = "<div class=\"Results\"><div class=\"ResultError\">Product Code \"" + str[i] + "\" could not be found.</div></div>";
    					}
    					else{
    						document.getElementById("result"+i).innerHTML = "";
    					}
    				}
    			}
    		}
    	}
    	xmlhttp.open("GET",url,true);xmlhttp.send();
    }
    Which calls an .asp file (which should really by a .ashx file:
    Code:
    <%
    response.expires=-1
    Response.ContentType="text/xml"
    DIM i, ColorArray, SizeArray
    i=1
    	
    SET conn=Server.CreateObject("ADODB.Connection")
    IF InStr(1,Request.ServerVariables("SERVER_NAME"),"esedirect",1) THEN
    	conn.Open "Provider=SQLOLEDB; Server=.\SQLEXPRESS; Initial Catalog=AspDotNetStorefront; User Id=xxxx; Password=****;" 'live environment - removed to protect the innocent!
    ELSE
    	conn.Open "Provider=SQLNCLI10; Server=SERVER2\SQLExpress; Database=ASPDotNetStoreFront; Trusted_Connection=yes;" 'test environment
    END IF
    SET rs=Server.CreateObject("ADODB.recordset")
    
    function LoopThroughArray (arrName)
    	dim sout, arrValue, arrPos
    	arrPos=0
    	for each arrValue in arrName ' loop through the array
    	sout = sout & "<option value=""" & arrPos & """>" & arrValue & "</option>" ' store each value in array
    	arrPos = arrPos + 1
    	next
    	LoopThroughArray = sout ' return the output
    end function
    
    %>
    <Results>
    <%
    DO WHILE i <=15
    sql="SELECT p.ProductID, pv.SKUSuffix, p.Name AS ProductName, pv.Name AS VariantName, p.SEName, pv.Price, pv.Colors, pv.Sizes, p.ColorOptionPrompt, p.SizeOptionPrompt " & _
    	"FROM ProductVariant pv " & _
    	"LEFT JOIN Product p WITH (NOLOCK) ON pv.ProductID = p.ProductID " & _
    	"WHERE pv.SKUSuffix = '"&request.querystring("q"&i)&"' " & _
    	"AND p.Published=1 AND pv.Published=1 AND pv.Deleted=0 AND p.Deleted=0"
    	
    rs.Open sql,conn
    
    IF NOT rs.EOF THEN 
    ColorArray = split(rs("Colors"),",")
    SizeArray  = split(rs("Sizes"),",")
    %>
    	<Result>
    		<Body<%= i %>><![CDATA[
    		<div class="Results">
    		<a class="thickbox" href="images/product/large/<%= rs("ProductID") %>.jpg" title="<%= rs("ProductName") %>">
    			<img src="images/product/icon/<%= rs("ProductID") %>.jpg" height="35px" width="35px" class="ResultImg"/>
    		</a>
    		<div class="ResultName"><%= rs("ProductName") %></div>
    		<% IF rs("Colors") <> "" THEN %>
    		<div class="ResultColors">
    			<% IF rs("ColorOptionPrompt") <> "" THEN %>
    			<%= rs("ColorOptionPrompt") %>:
    			<% ELSE %>
    				Colour: 
    			<% END IF %>
    			<select id="Color<%= i %>" onchange="" name="Color<%= i %>" size="1">
    				 <% response.write(LoopThroughArray(ColorArray)) %>
    			</select>
    		</div>
    		<% END IF %>
    		<% IF rs("Sizes") <> "" THEN %>
    		<div class="ResultSizes">
    			<% IF rs("SizeOptionPrompt") <> "" THEN %>
    			<%= rs("SizeOptionPrompt") %>:
    			<% ELSE %>
    				Size: 
    			<% END IF %>
    			<select id="Sizes<%= i %>" onchange="" name="Sizes<%= i %>" size="1">
    				 <% response.write(LoopThroughArray(SizeArray)) %>
    			</select>
    		</div>
    		<% END IF %>
    		</div>
    		]]></Body<%= i %>>
    	</Result>
    <% 
    END IF
    i=i+1
    sql=""
    rs.close
    LOOP
    %>
    </Results>
    <%
    conn.Close
    SET rs=NOTHING
    SET conn=NOTHING
    %>
    The XMLPackage also posts a form to QuickOrder.aspx, so you need:
    Code:
    <%@ Page language="c#" Inherits="AspDotNetStorefront.QuickOrder" CodeFile="QuickOrder.aspx.cs" %>
    And the code behind, in QuickOrder.aspx.cs:
    Code:
    using System;
    using System.Web;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;
    using AspDotNetStorefrontCore;
    
    namespace AspDotNetStorefront
    {
        /// <summary>
        /// Summary description for QuickOrder.
        /// </summary>
        public partial class QuickOrder : SkinBase
        {
            protected void Page_Load(object sender, System.EventArgs e)
            {
                Response.CacheControl = "private";
                Response.Expires = 0;
                Response.AddHeader("pragma", "no-cache");
    
                CartTypeEnum CartType = CartTypeEnum.ShoppingCart;
    
                ThisCustomer.RequireCustomerRecord();
                int CustomerID = ThisCustomer.CustomerID;
    
                ShoppingCart cart = new ShoppingCart(1, ThisCustomer, CartType, 0, false);
                for (int i = 0; i < Convert.ToInt32(Request.Form["Rows"]+1); i++)
                {
    				try 
    				{
    					decimal CustomerEnteredPrice = Decimal.Zero;
    					int Qty = Localization.ParseNativeInt(Request.Form["Qty"+i]);
    						if (Qty == 0)
    						{
    							Qty = 1;
    						}
    					int ProductID = 0;
    					int VariantID = 0;
    					int ColorIdx = 0;
    						if (Request.Form["Color"+i] != null)
    						{
    							ColorIdx = Localization.ParseNativeInt(Request.Form["Color"+i]);
    						}
    					int SizeIdx = 0;
    						if (Request.Form["Sizes"+i] != null)
    						{
    							SizeIdx = Localization.ParseNativeInt(Request.Form["Sizes"+i]);
    						}
    					int NewRecID = 0;
    					String SKUSuffix = Request.Form["SKU"+i];
    					String ChosenColor = String.Empty;
    					String ChosenSize = String.Empty;
    					String ChosenColorSKUModifier = String.Empty;
    					String ChosenSizeSKUModifier = String.Empty;
    					String TextOption = String.Empty;
    
    					using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
    					{
    						dbconn.Open();
    						using (IDataReader rs = DB.GetRS("select * from productvariant where SKUSuffix='"+SKUSuffix+"'", dbconn))
    						{
    							rs.Read();
    							ProductID = DB.RSFieldInt(rs, "ProductID");
    							VariantID = DB.RSFieldInt(rs, "VariantID");
    							ChosenColor = DB.RSFieldByLocale(rs, "Colors", Localization.GetWebConfigLocale()).Split(',')[ColorIdx].Trim();
    							if (DB.RSField(rs, "ColorSKUModifiers").Length != 0)
    							{
    								ChosenColorSKUModifier = DB.RSField(rs, "ColorSKUModifiers").Split(',')[ColorIdx].Trim();
    							}
    							ChosenSize = DB.RSFieldByLocale(rs, "Sizes", Localization.GetWebConfigLocale()).Split(',')[SizeIdx].Trim();
    							if (DB.RSField(rs, "SizeSKUModifiers").Length != 0)
    							{
    								ChosenSizeSKUModifier = DB.RSField(rs, "SizeSKUModifiers").Split(',')[SizeIdx].Trim();
    							}
    						}
    					}
    
    					NewRecID = DB.GetSqlN("select ShoppingCartRecID as N from ShoppingCart where ProductID=" + ProductID.ToString() + " and VariantID=" + VariantID.ToString() + " and CartType=" + ((int)CartType).ToString() + " and CustomerID=" + CustomerID.ToString() + " and ChosenColor='" + ChosenColor + "' and ChosenSize='" + ChosenSize + "'");
    					if (NewRecID != 0)
    					{
    						//Already in the ShoppingCart so just up the Quantity
    						DB.ExecuteSQL("update ShoppingCart set Quantity=Quantity + " + Qty.ToString() + " where ShoppingCartRecID=" + NewRecID + " and CartType=" + ((int)CartType).ToString() + " and CustomerID=" + CustomerID.ToString());
    					}
    					if (NewRecID == 0)
                        {
                            cart.AddItem(ThisCustomer, 0, ProductID, VariantID, Qty, ChosenColor, ChosenColorSKUModifier, ChosenSize, ChosenSizeSKUModifier, TextOption, CartType, false, false, 0, CustomerEnteredPrice);
                        }
    
    				}
    				catch { }
                }
                cart = null;
    
                String ReturnURL = CommonLogic.QueryStringCanBeDangerousContent("ReturnURL");
                if (AppLogic.AppConfig("AddToCartAction").Equals("STAY", StringComparison.InvariantCultureIgnoreCase) && ReturnURL.Length != 0)
                {
                    Response.Redirect(ReturnURL);
                }
                else
                {
                    String url = CommonLogic.IIF(CartType == CartTypeEnum.WishCart, "wishlist.aspx", "ShoppingCart.aspx?add=true");
                    Response.Redirect(url);
                }
            }
    
        }
    }
    I haven't bothered to include any CSS or images, because you can probably work them out for yourselves.

    Happy coding. Always happy to give back to the community!
    http://www.esedirect.co.uk
    --------------------------------------------------------------------------
    Using MS 9.2.0.0 with the following customisations:

    Lightbox/Fancybox enlarged images;
    Auto-suggest searchbox;
    Extra product information shown only to our IP Address (such as supplier info, costs, etc.);
    Failed transactions emailed via trigger;
    Custom app to show basket contents when customer online;
    Orders pushed through to accounting systems.

    All the above without source!

  13. #13
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    How do you keep <form name="aspnetForm" method="post" action="qie.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm"> from being put in your code for this page. I believe this is what is making my page not work right.

  14. #14
    Orangey is offline Junior Member
    Join Date
    Aug 2010
    Location
    UK
    Posts
    23

    Default

    Quote Originally Posted by chrismartz View Post
    How do you keep <form name="aspnetForm" method="post" action="qie.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm"> from being put in your code for this page. I believe this is what is making my page not work right.
    Are you referring to the code posted by esedirect? I don't see the code you're having trouble with anywhere in there so I'm not sure where that's coming from. Sorry if I'm missing something obvious...

  15. #15
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Quote Originally Posted by esedirect View Post
    For all those who have asked how we did it. This code is not supported by us, even though it is ours
    Can this version automatically lookup the product as the person is typing to get the description to show to the person?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  16. #16
    esedirect is offline Senior Member
    Join Date
    Feb 2010
    Location
    Norfolk, UK
    Posts
    343

    Default

    No. It is what it is!
    http://www.esedirect.co.uk
    --------------------------------------------------------------------------
    Using MS 9.2.0.0 with the following customisations:

    Lightbox/Fancybox enlarged images;
    Auto-suggest searchbox;
    Extra product information shown only to our IP Address (such as supplier info, costs, etc.);
    Failed transactions emailed via trigger;
    Custom app to show basket contents when customer online;
    Orders pushed through to accounting systems.

    All the above without source!

  17. #17
    Orangey is offline Junior Member
    Join Date
    Aug 2010
    Location
    UK
    Posts
    23

    Default

    Quote Originally Posted by cjbarth View Post
    Can this version automatically lookup the product as the person is typing to get the description to show to the person?
    I imagine you could remove this section of code in the "Check Items" button:
    Code:
    onclick="checkItems(QuickOrder)"
    and instead put this in the code for the input boxes:
    Code:
    onchange="checkItems(QuickOrder)"
    That should check the product codes as you type but I dont know what adverse consequences this might have elsewhere in the code or the rest of the quick order process.

    I imagine it would be quite data and traffic intensive which you might not want every time you pressed a key. A solution to this might be to try onBlur instead of onChange.

    Hope this helps, sorry if it breaks things.
    Last edited by Orangey; 09-17-2010 at 03:39 AM.

  18. #18
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    We are updating a site from

    AspDotNetStorefront ML 5.9.9.1/5.9.9
    DB Version: 5.9.9 (Yeah, old school)

    to the Multi-Store version and the way we used to handle the quick order doesn't look like it will work now.

    esedirect's approach looks great. Has anyone else tried getting it to work in a Multi-Store install?

    I think I have all the mappings correct and it appears in the browser fine but it doesn't want to work for me.

    Thanks

  19. #19
    jsimacek is offline Senior Member
    Join Date
    Dec 2008
    Location
    Phoenix, AZ
    Posts
    373

    Default

    Hmm, that could be a number of things like script conflicts etc, but the http://www.ecommercecartmods.com/p-5...torefront.aspx is made for MultiStore.
    Jan Simacek - Compunix, LLC
    AspDotNetStorefront trusted Devnet Partner and Reseller since 2005

    AspDotNetStorefront Mods and Add-Ons at http://www.ecommercecartmods.com/
    - Searching, Filtering and Sorting (like cSearch, Dealer Locator, Price Ranges, Blog)
    - Reports (like Cart Abandonment and Net Sales)
    - Customer Experience (like Question/Answers)
    - Site and Data Management (like Entity Product Mapper, Bulk Updaters, Make/Model/Year filters)

  20. #20
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Here is the solution I came up with that leverages standard ASPDNSF code:

    quickorderform.aspx
    Code:
    <%@ Page Language="vb" Inherits="AspDotNetStorefront.quickorderform" CodeFile="quickorderform.aspx.vb"
      EnableEventValidation="true" MasterPageFile="~/App_Templates/Skin_1/template.master"
      Async="true" %>
    
    <%@ Register TagPrefix="aspdnsf" TagName="Topic" Src="~/Controls/TopicControl.ascx" %>
    <asp:Content ID="Content1" runat="server" ContentPlaceHolderID="PageContent">
      <aspdnsf:Topic ID="topicWelcome" runat="server" EnforceDisclaimer="true" EnforcePassword="true"
        EnforceSubscription="true" AllowSEPropogation="true" TopicName="Welcome" Visible="False" />
      <asp:UpdatePanel ID="pnlUpdatePanel" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
          <asp:HiddenField ID="intNumOfRows" runat="server" Value="4" />
          <asp:HiddenField ID="inhControlWithFocus" runat="server" />
          <asp:Table ID="QuickOrderTable" runat="server">
            <asp:TableHeaderRow>
              <asp:TableHeaderCell>APN/Variant:
              </asp:TableHeaderCell>
              <asp:TableHeaderCell>
              </asp:TableHeaderCell>
              <asp:TableHeaderCell HorizontalAlign="Center">Quantity:
              </asp:TableHeaderCell>
              <asp:TableHeaderCell>
              </asp:TableHeaderCell>
            </asp:TableHeaderRow>
          </asp:Table>
          <style type="text/css">
            .buttonTable, .buttonTable tr, .buttonTable tr td
            {
              padding: 4px;
            }
          </style>
          <asp:Table ID="Table1" runat="server" CssClass="buttonTable">
            <asp:TableRow>
              <asp:TableCell>
                <asp:Button ID="btnVerifyAll" runat="server" Text="Verify All" OnClientClick="this.value='Verifying...'" />
              </asp:TableCell>
              <asp:TableCell>
                <asp:Button ID="btnAddToCart" runat="server" Text="Add To Cart" OnClientClick="this.value='Adding...'" />
              </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
              <asp:TableCell ColumnSpan="2" HorizontalAlign="Center">
                <asp:Button ID="btnAddMoreRows" runat="server" Text="Add 4 More Rows" />
              </asp:TableCell>
            </asp:TableRow>
          </asp:Table>
        </ContentTemplate>
      </asp:UpdatePanel>
    </asp:Content>
    quickorderform.aspx.vb
    Code:
    Imports System
    Imports System.Data
    Imports System.Data.SqlClient
    Imports AspDotNetStorefrontCore
    Imports System.Security.Permissions
    
    Namespace AspDotNetStorefront
    
        Public Class QuickOrderFormRow
            Inherits TableRow
    
            <AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal)> _
            Private NotInheritable Class CustomSKUBox
                Inherits System.Web.UI.WebControls.TextBox
    
                Public isDirty As Boolean = False
    
                Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
                    MyBase.OnTextChanged(e)
                    isDirty = True
                    RaiseBubbleEvent(Me, e)
                End Sub
            End Class
    
            <AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal)> _
            Private NotInheritable Class CustomQtyBox
                Inherits System.Web.UI.WebControls.TextBox
    
                Public isDirty As Boolean = False
    
                Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
                    MyBase.OnTextChanged(e)
                    Me.Text = Regex.Replace(Me.Text, "[^0-9]", "")
                    isDirty = True
                    RaiseBubbleEvent(Me, e)
                End Sub
            End Class
    
            <AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal)> _
            Private NotInheritable Class CustomDropDownList
                Inherits System.Web.UI.WebControls.DropDownList
    
                Public isDirty As Boolean = False
    
                Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs)
                    MyBase.OnSelectedIndexChanged(e)
                    isDirty = True
                    RaiseBubbleEvent(Me, e)
                End Sub
            End Class
    
            Private tcTxtSKU As TableCell
            Private tcLstSKU As TableCell
            Private tcTxtQty As TableCell
            Private tcLbl As TableCell
    
            Private upTxtSKU As UpdatePanel
            Private upLstSKU As UpdatePanel
            Private upTxtQty As UpdatePanel
            Private upLbl As UpdatePanel
    
            Private upLabels As UpdatePanel
            Private txtSKU As CustomSKUBox
            Private lstSKUSuffix As CustomDropDownList
            Private txtQty As CustomQtyBox
            Private lblStatus As Label
            Private lblProductID As Label
            Private lblVariantID As Label
    
            Private RowID As String
            Private _CurrentID As Integer = 0
    
            'make sure that the IDs are assigned the same every time for ViewState consistancy
            'the RowID is needed to make sure that IDs are different between rows
            Private ReadOnly Property NextID() As Integer
                Get
                    _CurrentID += 1
                    Return RowID & _CurrentID
                End Get
            End Property
    
            Public ReadOnly Property ReadyToAddToCart() As Boolean
                Get
                    Return txtQty.Enabled AndAlso lblProductID.Text <> "" AndAlso lblVariantID.Text <> "" AndAlso txtQty.Text <> ""
                End Get
            End Property
    
            Public ReadOnly Property Quantity() As Integer
                Get
                    Return txtQty.Text
                End Get
            End Property
    
            Public ReadOnly Property ProductID() As String
                Get
                    Return lblProductID.Text
                End Get
            End Property
    
            Public ReadOnly Property VariantID() As String
                Get
                    Return lblVariantID.Text
                End Get
            End Property
    
            Public ReadOnly Property isDirty() As Boolean
                Get
                    Return txtSKU.isDirty Or txtQty.isDirty Or lstSKUSuffix.isDirty
                End Get
            End Property
    
            Public Sub New(ByVal clientID As String, ByVal myRowID As String, ByVal myScriptManager As ScriptManager)
                MyBase.New()
    
                'this will save the controls ID to a hidden field for recall later to reset the focus
                Dim strJava As String = "document.getElementById('" & clientID & "').value = this.id;"
    
                RowID = myRowID
    
                tcTxtSKU = New TableCell
                tcLstSKU = New TableCell
                tcTxtQty = New TableCell
                tcLbl = New TableCell
    
                upTxtSKU = New UpdatePanel
                upTxtSKU.UpdateMode = UpdatePanelUpdateMode.Conditional
    
                upLstSKU = New UpdatePanel
                upLstSKU.UpdateMode = UpdatePanelUpdateMode.Conditional
    
                upTxtQty = New UpdatePanel
                upTxtQty.UpdateMode = UpdatePanelUpdateMode.Conditional
    
                upLbl = New UpdatePanel
                upLbl.UpdateMode = UpdatePanelUpdateMode.Conditional
    
                txtSKU = New CustomSKUBox
                txtSKU.AutoPostBack = True
                txtSKU.ID = NextID
                txtSKU.Attributes("onfocus") = strJava
                upTxtSKU.ContentTemplateContainer.Controls.Add(txtSKU)
                tcTxtSKU.Controls.Add(upTxtSKU)
    
                lstSKUSuffix = New CustomDropDownList
                lstSKUSuffix.Visible = False
                lstSKUSuffix.AutoPostBack = True
                lstSKUSuffix.ID = NextID
                lstSKUSuffix.Attributes("onfocus") = strJava
                upLstSKU.ContentTemplateContainer.Controls.Add(lstSKUSuffix)
                tcLstSKU.Controls.Add(upLstSKU)
    
                txtQty = New CustomQtyBox
                txtQty.Columns = 4
                txtQty.AutoPostBack = True
                txtQty.ID = NextID
                txtQty.Attributes("onfocus") = strJava
                upTxtQty.ContentTemplateContainer.Controls.Add(txtQty)
                tcTxtQty.Controls.Add(upTxtQty)
    
                lblStatus = New Label
                upLbl.ContentTemplateContainer.Controls.Add(lblStatus)
    
                lblProductID = New Label
                lblProductID.Visible = False
                upLbl.ContentTemplateContainer.Controls.Add(lblProductID)
    
                lblVariantID = New Label
                lblVariantID.Visible = False
                upLbl.ContentTemplateContainer.Controls.Add(lblVariantID)
    
                tcLbl.Controls.Add(upLbl)
    
                Me.Controls.Add(tcTxtSKU)
                Me.Controls.Add(tcLstSKU)
                Me.Controls.Add(tcTxtQty)
                Me.Controls.Add(tcLbl)
    
                'needed to register the controls for async operations to prevent page refreshes
                myScriptManager.RegisterAsyncPostBackControl(txtSKU)
                myScriptManager.RegisterAsyncPostBackControl(lstSKUSuffix)
                myScriptManager.RegisterAsyncPostBackControl(txtQty)
    
            End Sub
    
            Protected Overrides Function OnBubbleEvent(ByVal source As Object, ByVal args As System.EventArgs) As Boolean
                'all the changable controls will force a Bubble event that will be handled here by updating the fields
                If isDirty Then
                    GetNameAndIDs()
                End If
    
                If txtSKU.isDirty Then
                    upTxtSKU.Update()
                End If
                If lstSKUSuffix.isDirty Then
                    upLstSKU.Update()
                End If
                If txtQty.isDirty Then
                    upTxtQty.Update()
                End If
    
                Return MyBase.OnBubbleEvent(source, args)
            End Function
    
            Public Sub DisableAll()
                txtSKU.Enabled = False
                lstSKUSuffix.Enabled = False
                txtQty.Enabled = False
            End Sub
    
            Public Sub Clear()
                lstSKUSuffix.Items.Clear()
                txtQty.Text = ""
                lblStatus.Text = ""
                lblProductID.Text = ""
                lblVariantID.Text = ""
            End Sub
    
            Public Sub GetNameAndIDs()
    
                If txtSKU.isDirty Then
                    lstSKUSuffix.Items.Clear()
                    lstSKUSuffix.Items.Add("--Choose One--")
                    Using dbconn As New SqlConnection(DB.GetDBConn())
                        dbconn.Open()
                        Using rs As IDataReader = DB.GetRS("Select ProductVariant.SKUSuffix FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (Product.SKU = N'" & txtSKU.Text & "')", dbconn)
                            While rs.Read()
                                lstSKUSuffix.Items.Add(DB.RSField(rs, "SKUSuffix"))
                            End While
                        End Using
                    End Using
    
                    If lstSKUSuffix.Items.Count > 2 Then
                        lstSKUSuffix.Visible = True
                    Else
                        lstSKUSuffix.Visible = False
                    End If
                    upLstSKU.Update()
                End If
    
                'clear old data
                lblStatus.Text = ""
                lblProductID.Text = ""
                lblVariantID.Text = ""
    
                If lstSKUSuffix.Visible Then 'if there are SKUSuffixes
                    If lstSKUSuffix.SelectedIndex = 0 Then 'if a SKUSuffix hasn't been choosen
    
                        'get just the name
                        Using dbconn As New SqlConnection(DB.GetDBConn)
                            dbconn.Open()
                            Using rs As IDataReader = DB.GetRS("SELECT Product.Name FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (ProductVariant.IsDefault = 1) AND (Product.SKU = N'" & txtSKU.Text & "')", dbconn)
                                While rs.Read
                                    lblStatus.Text = DB.RSField(rs, "Name") & " - Please Choose A Variant."
                                    Exit While 'only get the first one, should only be one
                                End While
                            End Using
                        End Using
    
                    Else 'if a SKUSuffix has been choose, get the info
                        Using dbconn As New SqlConnection(DB.GetDBConn)
                            dbconn.Open()
                            Using rs As IDataReader = DB.GetRS("SELECT Product.Name + '; ' + ProductVariant.Name AS Name, Product.ProductID, ProductVariant.VariantID FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (Product.SKU = N'" & txtSKU.Text & "') AND (ProductVariant.SKUSuffix = N'" & lstSKUSuffix.Text & "')", dbconn)
                                While rs.Read()
                                    lblStatus.Text = DB.RSField(rs, "Name")
                                    lblProductID.Text = DB.RSFieldInt(rs, "ProductID")
                                    lblVariantID.Text = DB.RSFieldInt(rs, "VariantID")
                                    Exit While 'only get the first one, should only be one
                                End While
                            End Using
                        End Using
                    End If
    
                Else 'if there aren't SKUSuffixes, try to get the info on what we have
                    If txtSKU.Text <> "" Then
                        lblStatus.Text = "Product Not Found"
    
                        Using dbconn As New SqlConnection(DB.GetDBConn)
                            dbconn.Open()
                            Using rs As IDataReader = DB.GetRS("SELECT Product.ProductID, ProductVariant.VariantID, Product.Name FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (ProductVariant.IsDefault = 1) AND (Product.SKU = N'" & txtSKU.Text & "')", dbconn)
                                While rs.Read
                                    lblStatus.Text = DB.RSField(rs, "Name")
                                    lblProductID.Text = DB.RSFieldInt(rs, "ProductID")
                                    lblVariantID.Text = DB.RSFieldInt(rs, "VariantID")
                                    Exit While 'only get the first one, should only be one
                                End While
                            End Using
                        End Using
                    Else
                        Clear()
                    End If
                End If
    
                'if we found a product, but don't have a quantity, request quantity
                If lblProductID.Text <> "" AndAlso lblVariantID.Text <> "" AndAlso txtQty.Text = "" Then
                    lblStatus.Text &= " - Please enter a quantity."
                End If
    
                upLbl.Update()
    
            End Sub
    
            Public Sub AddToCart(ByVal myCart As ShoppingCart, ByVal myCustomer As Customer)
    
                Dim CartType As CartTypeEnum = CartTypeEnum.ShoppingCart
                Dim ChosenColor As String = String.Empty
                Dim ChosenSize As String = String.Empty
                Dim ChosenColorSKUModifier As String = String.Empty
                Dim ChosenSizeSKUModifier As String = String.Empty
                Dim TextOption As String = String.Empty
                Dim CustomerEnteredPrice As Decimal = Decimal.Zero
    
                If ReadyToAddToCart Then
                    myCart.AddItem(myCustomer, 0, ProductID, VariantID, Quantity, ChosenColor, ChosenColorSKUModifier, ChosenSize, ChosenSizeSKUModifier, TextOption, CartType, False, False, 0, CustomerEnteredPrice)
                    lblStatus.Text &= " - Added To Cart"
                    DisableAll()
                Else
                    GetNameAndIDs()
                End If
    
            End Sub
    
        End Class
    
        Partial Public Class quickorderform
            Inherits SkinBase
    
            Private _CurrentID As Integer = 0
    
            'make sure that the IDs are assigned the same every time for ViewState consistancy
            Private ReadOnly Property NextID() As Integer
                Get
                    _CurrentID += 1
                    Return _CurrentID
                End Get
            End Property
    
            Private ReadOnly Property scriptMgr() As ScriptManager
                Get
                    Return DirectCast(Master.FindControl("scrptMgr"), ScriptManager)
                End Get
            End Property
    
            Public Overrides ReadOnly Property RequireScriptManager() As Boolean
                Get
                    Return True
                End Get
            End Property
    
            Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
    
                If AppLogic.AppConfigBool("GoNonSecureAgain") Then
                    SkinBase.GoNonSecureAgain()
                End If
    
                Try
                    'set the focus to the control that had it last
                    scriptMgr.SetFocus(inhControlWithFocus.Value)
                Catch ex As Exception
                End Try
            End Sub
    
            Protected Sub quickorderform_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
                'check to see if the user is logged on or not
                If Me.ThisCustomer.IsRegistered Then
                    DirectCast(Master.FindControl("PageContent"), ContentPlaceHolder).Controls.Remove(topicWelcome)
                Else
                    topicWelcome.Visible = True
                    pnlUpdatePanel.Visible = False
                End If
    
                SectionTitle = "Quick Order Form"
    
            End Sub
    
            Protected Sub btnAddToCart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddToCart.Click
                'some javascript on the onclick event will change the text and the ViewState will change it back when the page refreshes
    
                Dim CartType As CartTypeEnum = CartTypeEnum.ShoppingCart
    
                Me.ThisCustomer.RequireCustomerRecord()
    
                Dim cart As New ShoppingCart(1, Me.ThisCustomer, CartType, 0, False)
    
                'look at all the controls in the table
                'if it is a quickorderformrow (a custom table row) then try to add it
                For Each ctrlRow As Control In QuickOrderTable.Controls
                    Dim myOrderRow As QuickOrderFormRow = TryCast(ctrlRow, QuickOrderFormRow)
    
                    If myOrderRow Is Nothing Then
                        Continue For
                    End If
    
                    myOrderRow.AddToCart(cart, ThisCustomer)
                Next
    
                'update the label and then for the updatepanel to update
                'this requires a modificaiton of the masterpage
                DirectCast(Master.FindControl("lrtNum_Cart_Items"), Literal).Text = ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString()
                DirectCast(Master.FindControl("CartUpdate"), UpdatePanel).Update()
    
            End Sub
    
            Private Sub AddRows()
                AddRows(intNumOfRows.Value)
            End Sub
    
            Private Sub AddRows(ByVal intRows As Integer)
                For x As Integer = 1 To intRows
                    AddRow()
                Next
    
            End Sub
    
            Private Sub AddRow()
                Dim myOrderRow As New QuickOrderFormRow(inhControlWithFocus.ClientID, NextID, scriptMgr)
    
                QuickOrderTable.Rows.Add(myOrderRow)
    
            End Sub
    
            Protected Sub btnVerifyAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnVerifyAll.Click
                'some javascript on the onclick event will change the text and the ViewState will change it back when the page refreshes
    
                For Each ctrlRow As Control In QuickOrderTable.Controls
                    Dim myOrderRow As QuickOrderFormRow = TryCast(ctrlRow, QuickOrderFormRow)
    
                    If myOrderRow Is Nothing Then
                        Continue For
                    End If
    
                    myOrderRow.GetNameAndIDs()
                Next
    
            End Sub
    
            Protected Sub btnAddMoreRows_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddMoreRows.Click
                intNumOfRows.Value += 4
    
                AddRows(4)
            End Sub
    
            Protected Sub quickorderform_PreLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreLoad
                'add rows before the StateView information is added back to the page
                AddRows()
    
            End Sub
    
        End Class
    End Namespace
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  21. #21
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    Thanks a lot cjbarth!

    It recognizes the product as I enter it but the click events aren't firing.

    It's been a little while since I've worked in C# so I bet I either messed something up in the code conversion or I don't have the events wired up at all. HA

    Thanks again!!! I'm sure I'll figure it out.

  22. #22
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    C# conversions often leave off the Handles part of this code:

    Code:
    Protected Sub btnVerifyAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnVerifyAll.Click
    If it has you can add it back in. There is another way to specify the handler at run-time, but I'm not sure of the specific code to do that.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  23. #23
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    Thanks cjbarth. That did the trick. I guess it helps to do that. HA

    Yeah, if memory serves, you can add the handlers somewhere in the code but I just explicitly wired them up.

    I just have two more issues to figure out and I'm all set.

    I never get the status message. The product gets in the cart but the button holds the "Adding" text and the " - Added To Cart" text never appears.

    Also, when I click the "Add 4 More Rows" button, it adds 4 the first time but then a lot after that.

    I'm not sure if the AJAX extensions are installed on the server I'm testing on...if that would make a difference.

    Thanks for all your help.
    Last edited by awoomer; 11-04-2010 at 10:19 AM.

  24. #24
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Which browser are you testing on?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  25. #25
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    FireFox 3.6.12

  26. #26
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    I would just step thorough the code and see what is happening. I know that AJAX is broken in ASP.Net and Chrome, so you need to add in some JavaScript to fix that. Since you are on Firefox, that isn't the problem. If you can find out exactly where the problem is or what line isn't working like it should then I can take a closer look.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  27. #27
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    Code:
    //update the label and then for the updatepanel to update
                //this requires a modificaiton of the masterpage
                ((Literal)Master.FindControl("lrtNum_Cart_Items")).Text = ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString();
                ((UpdatePanel)Master.FindControl("CartUpdate")).Update();
    I don't have any of this on my master page?

  28. #28
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    For the textboxes, it looks like the hidden field never gets cleared out so it goes from 4 to 44 to 444 to 4444...etc.

    That should be an easy enough fix.

  29. #29
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    You just have to set up your cart code in the template.master to be something like this:

    Code:
      <asp:UpdatePanel runat="server" ID="CartUpdate" UpdateMode="Conditional">
    	<ContentTemplate>
    	  You have
    	  <asp:Literal ID="lrtNum_Cart_Items" runat="server" Text='<%$ Tokens:Num_Cart_Items %>' />
    	  item(s) in your <a class="username" href="shoppingcart.aspx">
    		<asp:Literal ID="lrtCartPrompt" runat="server" Text='<%$ Tokens:CartPrompt %>' /></a>&nbsp;
    	  </span>&nbsp;</ContentTemplate>
      </asp:UpdatePanel>
    The key is to have the label named and it surrounded by an UpdatePanel.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  30. #30
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    I don't think the problem is that the hidden field never gets cleared out (at least not in my VB code). I run it and I can add 4 more rows as much as I'd like and it always works.

    Might I suggest that you drop those two files in your site just they way they are without converting (you can have mixed pages in a site as long as you specify the page language at the top of the page if it differs from the site default, which VB is already set in the sample I posted). By doing that you can see if everything on your system is configured properly, then you can go about converting to C# if you want.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  31. #31
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    Might I suggest that you drop those two files in your site just they way they are without converting (you can have mixed pages in a site as long as you specify the page language at the top of the page if it differs from the site default, which VB is already set in the sample I posted). By doing that you can see if everything on your system is configured properly, then you can go about converting to C# if you want.
    Are you sure I can do that? I'm getting a compilation error.

  32. #32
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    You just have to set up your cart code in the template.master to be something like this:


    Code:
    <asp:UpdatePanel runat="server" ID="CartUpdate" UpdateMode="Conditional">
    <ContentTemplate>
    You have
    <asp:Literal ID="lrtNum_Cart_Items" runat="server" Text='<%$ Tokens:Num_Cart_Items %>' />
    item(s) in your <a class="username" href="shoppingcart.aspx">
    <asp:Literal ID="lrtCartPrompt" runat="server" Text='<%$ Tokens:CartPrompt %>' /></a>&nbsp;
    </span>&nbsp;</ContentTemplate>
    </asp:UpdatePanel>The key is to have the label named and it surrounded by an UpdatePanel.
    I gotcha, so this doesn't have anything to do with the button and status text not changing then. I didn't notice if the items in cart text was changing in my skin or not.

  33. #33
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    I just tried it on my VB.Net site and it worked fine:

    ctest.aspx
    Code:
    <%@ Page Language="c#" Inherits="AspDotNetStorefront.quickorderform" CodeFile="ctest.aspx.cs"
      EnableEventValidation="true" MasterPageFile="~/App_Templates/Skin_1/template.master"
      Async="true" %>
    
    <%@ Register TagPrefix="aspdnsf" TagName="Topic" Src="~/Controls/TopicControl.ascx" %>
    <asp:Content ID="Content1" runat="server" ContentPlaceHolderID="PageContent">
      <aspdnsf:Topic ID="topicWelcome" runat="server" EnforceDisclaimer="true" EnforcePassword="true"
        EnforceSubscription="true" AllowSEPropogation="true" TopicName="Welcome" Visible="False" />
      <asp:UpdatePanel ID="pnlUpdatePanel" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
          <asp:HiddenField ID="intNumOfRows" runat="server" Value="4" />
          <asp:HiddenField ID="inhControlWithFocus" runat="server" />
          <asp:Table ID="QuickOrderTable" runat="server">
            <asp:TableHeaderRow>
              <asp:TableHeaderCell>APN/Variant:
              </asp:TableHeaderCell>
              <asp:TableHeaderCell>
              </asp:TableHeaderCell>
              <asp:TableHeaderCell HorizontalAlign="Center">Quantity:
              </asp:TableHeaderCell>
              <asp:TableHeaderCell>
              </asp:TableHeaderCell>
            </asp:TableHeaderRow>
          </asp:Table>
          <style type="text/css">
            .buttonTable, .buttonTable tr, .buttonTable tr td
            {
              padding: 4px;
            }
          </style>
          <asp:Table ID="Table1" runat="server" CssClass="buttonTable">
            <asp:TableRow>
              <asp:TableCell>
                <asp:Button ID="btnVerifyAll" runat="server" Text="Verify All" OnClientClick="this.value='Verifying...'" />
              </asp:TableCell>
              <asp:TableCell>
                <asp:Button ID="btnAddToCart" runat="server" Text="Add To Cart" OnClientClick="this.value='Adding...'" />
              </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
              <asp:TableCell ColumnSpan="2" HorizontalAlign="Center">
                <asp:Button ID="btnAddMoreRows" runat="server" Text="Add 4 More Rows" />
              </asp:TableCell>
            </asp:TableRow>
          </asp:Table>
        </ContentTemplate>
      </asp:UpdatePanel>
    </asp:Content>
    ctest.aspx.cs
    Code:
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using AspDotNetStorefrontCore;
    using System.Security.Permissions;
    
    namespace AspDotNetStorefront
    {
        public partial class quickorderform : SkinBase
        {
        }
    }
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  34. #34
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    I think I have everything working. Thanks a ton cjbarth!!!

    Would you happen to know how to update the ajax mini cart after you add the items in the quick order form?

    The item number updates but when you click on the link the mini cart is still empty.

    Thanks again for all of your help.

  35. #35
    awoomer is offline Member
    Join Date
    Jul 2006
    Posts
    73

    Default

    Never mind cjbarth.

    I had to instantiate a new cart and then move the code that binds the mini cart and it's working now.

    Thanks again for your help.

  36. #36
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    In my implementation I just forced people to log on before using a quick order page.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  37. #37
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    Thanks for these directions cjbarth! I have been trying to convert this all to C# to use on my site but have a few issues. I used your example c# .aspx page but am having trouble with the codebehind page. Here is what I have:

    Code:
    <%@ Page Language="c#" Inherits="AspDotNetStorefront.quickorderform" CodeFile="quickorder.aspx.cs" EnableEventValidation="true" MasterPageFile="~/App_Templates/Skin_1/companyinfo.master" Async="true" %>
    <%@ Register TagPrefix="aspdnsf" TagName="Topic" Src="~/Controls/TopicControl.ascx" %>
    
    <asp:Content ID="Content1" runat="server" ContentPlaceHolderID="PageContent">
      <asp:UpdatePanel ID="pnlUpdatePanel" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
          <asp:HiddenField ID="intNumOfRows" runat="server" Value="4" />
          <asp:HiddenField ID="inhControlWithFocus" runat="server" />
          <asp:Table ID="QuickOrderTable" runat="server">
            <asp:TableHeaderRow>
              <asp:TableHeaderCell>SKU:</asp:TableHeaderCell>
              <asp:TableHeaderCell HorizontalAlign="Center">Quantity:</asp:TableHeaderCell>
            </asp:TableHeaderRow>
          </asp:Table>
          <style type="text/css">
            .buttonTable, .buttonTable tr, .buttonTable tr td
            {
              padding: 4px;
            }
          </style>
          <asp:Table ID="Table1" runat="server" CssClass="buttonTable">
            <asp:TableRow>
              <asp:TableCell>
                <asp:Button ID="btnVerifyAll" runat="server" Text="Verify All" OnClientClick="this.value='Verifying...'" />
              </asp:TableCell>
              <asp:TableCell>
                <asp:Button ID="btnAddToCart" runat="server" Text="Add To Cart" OnClientClick="this.value='Adding...'" />
              </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
              <asp:TableCell ColumnSpan="2" HorizontalAlign="Center">
                <asp:Button ID="btnAddMoreRows" runat="server" Text="Add 4 More Rows" />
              </asp:TableCell>
            </asp:TableRow>
          </asp:Table>
        </ContentTemplate>
      </asp:UpdatePanel>
    </asp:Content>
    Code:
    using System;
    using System.Web.UI;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.Data.SqlClient;
    using AspDotNetStorefrontCore;
    using System.Security.Permissions;
    using System.Text.RegularExpressions;
    using System.Web.UI.WebControls;
    
    namespace AspDotNetStorefront
    {
    
        public class quickorderformrow : TableRow
        {
            private sealed class CustomSKUBox : System.Web.UI.WebControls.TextBox
            {
                public bool isDirty = false;
                protected override void OnTextChanged(System.EventArgs e)
                {
                    base.OnTextChanged(e);
                    isDirty = true;
                    RaiseBubbleEvent(this, e);
                }
            }
    
            private sealed class CustomQtyBox : System.Web.UI.WebControls.TextBox
            {
                public bool isDirty = false;
                protected override void OnTextChanged(System.EventArgs e)
                {
                    base.OnTextChanged(e);
                    this.Text = Regex.Replace(this.Text, "[^0-9]", "");
                    isDirty = true;
                    RaiseBubbleEvent(this, e);
                }
            }
    
            private sealed class CustomDropDownList : System.Web.UI.WebControls.DropDownList
            {
                public bool isDirty = false;
                protected override void OnSelectedIndexChanged(System.EventArgs e)
                {
                    base.OnSelectedIndexChanged(e);
                    isDirty = true;
                    RaiseBubbleEvent(this, e);
                }
            }
    
            private TableCell tcTxtSKU;
            private TableCell tcLstSKU;
            private TableCell tcTxtQty;
    
            private TableCell tcLbl;
            private UpdatePanel upTxtSKU;
            private UpdatePanel upLstSKU;
            private UpdatePanel upTxtQty;
    
            private UpdatePanel upLbl;
            private UpdatePanel upLabels;
            private CustomSKUBox txtSKU;
            private CustomDropDownList lstSKUSuffix;
            private CustomQtyBox txtQty;
            private Label lblStatus;
            private Label lblProductID;
            private Label lblVariantID;
    
            private string RowID;
            private int _CurrentID = 0;
    
            private int NextID
            {
                get
                {
                    _CurrentID += 1;
                    return _CurrentID;
                }
            }
    
            public bool ReadyToAddToCart
            {
                get { return txtQty.Enabled && !string.IsNullOrEmpty(lblProductID.Text) && !string.IsNullOrEmpty(lblVariantID.Text) && !string.IsNullOrEmpty(txtQty.Text); }
            }
    
            public int Quantity
            {
                get { return Convert.ToInt32(txtQty.Text); }
            }
    
            public int ProductID
            {
                get { return Convert.ToInt32(lblProductID.Text); }
            }
    
            public int VariantID
            {
                get { return Convert.ToInt32(lblVariantID.Text); }
            }
    
            public bool isDirty
            {
                get { return txtSKU.isDirty | txtQty.isDirty | lstSKUSuffix.isDirty; }
            }
    
            public void QuickOrderFormRow(string clientID, string myRowID, ScriptManager myScriptManager)
            {
                string strJava = "document.getElementById('" + clientID + "').value = this.id;";
    
                RowID = myRowID;
    
                tcTxtSKU = new TableCell();
                tcLstSKU = new TableCell();
                tcTxtQty = new TableCell();
                tcLbl = new TableCell();
    
                upTxtSKU = new UpdatePanel();
                upTxtSKU.UpdateMode = UpdatePanelUpdateMode.Conditional;
    
                upLstSKU = new UpdatePanel();
                upLstSKU.UpdateMode = UpdatePanelUpdateMode.Conditional;
    
                upTxtQty = new UpdatePanel();
                upTxtQty.UpdateMode = UpdatePanelUpdateMode.Conditional;
    
                upLbl = new UpdatePanel();
                upLbl.UpdateMode = UpdatePanelUpdateMode.Conditional;
    
                txtSKU = new CustomSKUBox();
                txtSKU.AutoPostBack = true;
                txtSKU.ID = NextID.ToString();
                txtSKU.Attributes["onfocus"] = strJava;
                upTxtSKU.ContentTemplateContainer.Controls.Add(txtSKU);
                tcTxtSKU.Controls.Add(upTxtSKU);
    
                lstSKUSuffix = new CustomDropDownList();
                lstSKUSuffix.Visible = false;
                lstSKUSuffix.AutoPostBack = true;
                lstSKUSuffix.ID = NextID.ToString();
                lstSKUSuffix.Attributes["onfocus"] = strJava;
                upLstSKU.ContentTemplateContainer.Controls.Add(lstSKUSuffix);
                tcLstSKU.Controls.Add(upLstSKU);
    
                txtQty = new CustomQtyBox();
                txtQty.Columns = 4;
                txtQty.AutoPostBack = true;
                txtQty.ID = NextID.ToString();
                txtQty.Attributes["onfocus"] = strJava;
                upTxtQty.ContentTemplateContainer.Controls.Add(txtQty);
                tcTxtQty.Controls.Add(upTxtQty);
    
                lblStatus = new Label();
                upLbl.ContentTemplateContainer.Controls.Add(lblStatus);
    
                lblProductID = new Label();
                lblProductID.Visible = false;
                upLbl.ContentTemplateContainer.Controls.Add(lblProductID);
    
                lblVariantID = new Label();
                lblVariantID.Visible = false;
                upLbl.ContentTemplateContainer.Controls.Add(lblVariantID);
    
                tcLbl.Controls.Add(upLbl);
    
                this.Controls.Add(tcTxtSKU);
                this.Controls.Add(tcLstSKU);
                this.Controls.Add(tcTxtQty);
                this.Controls.Add(tcLbl);
    
                //needed to register the controls for async operations to prevent page refreshes
                myScriptManager.RegisterAsyncPostBackControl(txtSKU);
                myScriptManager.RegisterAsyncPostBackControl(lstSKUSuffix);
                myScriptManager.RegisterAsyncPostBackControl(txtQty);
    
            }
    
            protected override bool OnBubbleEvent(object source, System.EventArgs args)
            {
                if (isDirty)
                {
                    GetNameAndIDs();
                }
                if (txtSKU.isDirty)
                {
                    upTxtSKU.Update();
                }
                if (lstSKUSuffix.isDirty)
                {
                    upLstSKU.Update();
                }
                if (txtQty.isDirty)
                {
                    upTxtQty.Update();
                }
    
                return base.OnBubbleEvent(source, args);
            }
    
            public void DisableAll()
            {
                txtSKU.Enabled = false;
                lstSKUSuffix.Enabled = false;
                txtQty.Enabled = false;
            }
    
            public void Clear()
            {
                lstSKUSuffix.Items.Clear();
                txtQty.Text = "";
                lblStatus.Text = "";
                lblProductID.Text = "";
                lblVariantID.Text = "";
            }
    
    
            public void GetNameAndIDs()
            {
                if (txtSKU.isDirty)
                {
                    lstSKUSuffix.Items.Clear();
                    lstSKUSuffix.Items.Add("--Choose One--");
                    using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
                    {
                        dbconn.Open();
                        using (IDataReader rs = DB.GetRS("Select ProductVariant.SKUSuffix FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (Product.SKU = N'" + txtSKU.Text + "') OR (ProductVariant.SkuSuffix = N'" + txtSKU.Text + "')", dbconn))
                        {
                            while (rs.Read())
                            {
                                lstSKUSuffix.Items.Add(DB.RSField(rs, "SKUSuffix"));
                            }
                        }
                    }
    
                    if (lstSKUSuffix.Items.Count > 2)
                    {
                        lstSKUSuffix.Visible = true;
                    }
                    else
                    {
                        lstSKUSuffix.Visible = false;
                    }
                    upLstSKU.Update();
                }
    
                //clear old data
                lblStatus.Text = "";
                lblProductID.Text = "";
                lblVariantID.Text = "";
    
                //if there are SKUSuffixes
                if (lstSKUSuffix.Visible)
                {
                    //if a SKUSuffix hasn't been choosen
                    if (lstSKUSuffix.SelectedIndex == 0)
                    {
    
                        //get just the name
                        using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
                        {
                            dbconn.Open();
                            using (IDataReader rs = DB.GetRS("SELECT Product.Name FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (ProductVariant.IsDefault = 1) AND (Product.SKU = N'" + txtSKU.Text + "')", dbconn))
                            {
                                while (rs.Read())
                                {
                                    lblStatus.Text = DB.RSField(rs, "Name") + " - Please Choose A Variant.";
                                    break;
                                }
                            }
                        }
    
                        //if a SKUSuffix has been choose, get the info
                    }
                    else
                    {
                        using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
                        {
                            dbconn.Open();
                            using (IDataReader rs = DB.GetRS("SELECT Product.Name + '; ' + ProductVariant.Name AS Name, Product.ProductID, ProductVariant.VariantID FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (Product.SKU = N'" + txtSKU.Text + "') AND (ProductVariant.SKUSuffix = N'" + lstSKUSuffix.Text + "')", dbconn))
                            {
                                while (rs.Read())
                                {
                                    lblStatus.Text = DB.RSField(rs, "Name");
                                    lblProductID.Text = DB.RSFieldInt(rs, "ProductID").ToString();
                                    lblVariantID.Text = DB.RSFieldInt(rs, "VariantID").ToString();
                                    break; // TODO: might not be correct. Was : Exit While
                                    //only get the first one, should only be one
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(txtSKU.Text))
                    {
                        lblStatus.Text = "Product Not Found";
    
                        using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
                        {
                            dbconn.Open();
                            using (IDataReader rs = DB.GetRS("SELECT Product.ProductID, ProductVariant.VariantID, Product.Name FROM Product INNER JOIN ProductVariant ON Product.ProductID = ProductVariant.ProductID WHERE (ProductVariant.IsDefault = 1) AND (Product.SKU = N'" + txtSKU.Text + "')", dbconn))
                            {
                                while (rs.Read())
                                {
                                    lblStatus.Text = DB.RSField(rs, "Name");
                                    lblProductID.Text = DB.RSFieldInt(rs, "ProductID").ToString();
                                    lblVariantID.Text = DB.RSFieldInt(rs, "VariantID").ToString();
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        Clear();
                    }
                }
    
                //if we found a product, but don't have a quantity, request quantity
                if (!string.IsNullOrEmpty(lblProductID.Text) && !string.IsNullOrEmpty(lblVariantID.Text) && string.IsNullOrEmpty(txtQty.Text))
                {
                    lblStatus.Text += " - Please enter a quantity.";
                }
    
                upLbl.Update();
    
            }
    
    
            public void AddToCart(ShoppingCart myCart, Customer myCustomer)
            {
                CartTypeEnum CartType = CartTypeEnum.ShoppingCart;
                string ChosenColor = string.Empty;
                string ChosenSize = string.Empty;
                string ChosenColorSKUModifier = string.Empty;
                string ChosenSizeSKUModifier = string.Empty;
                string TextOption = string.Empty;
                decimal CustomerEnteredPrice = decimal.Zero;
    
                if (ReadyToAddToCart)
                {
                    myCart.AddItem(myCustomer, 0, ProductID, VariantID, Quantity, ChosenColor, ChosenColorSKUModifier, ChosenSize, ChosenSizeSKUModifier, TextOption, CartType, false, false, 0, CustomerEnteredPrice);
                    lblStatus.Text += " - Added To Cart";
                    DisableAll();
                }
                else
                {
                    GetNameAndIDs();
                }
            }
        }
    
        public partial class quickorderform : SkinBase
        {
            private int _CurrentID = 0;
            private int NextID
            {
                get
                {
                    _CurrentID += 1;
                    return _CurrentID;
                }
            }
    
            private ScriptManager scriptMgr
            {
                get { return (ScriptManager)this.Page.FindControl("scriptmgr"); }
            }
    
            public override bool RequireScriptManager
            {
                get { return true; }
            }
    
    
            protected void Page_Load(object sender, EventArgs e)
            {
                if (AppLogic.AppConfigBool("GoNonSecureAgain"))
                {
                    SkinBase.GoNonSecureAgain();
                }
                try
                {
                    scriptMgr.SetFocus(inhControlWithFocus.Value);
                }
                catch (Exception ex)
                {
                }
            }
    
            protected void quickorderform_Init(object sender, System.EventArgs e)
            {
                SectionTitle = "Quick Order Form";
            }
    
            protected void btnAddToCart_Click(object sender, System.EventArgs e)
            {
                CartTypeEnum CartType = CartTypeEnum.ShoppingCart;
    
                this.ThisCustomer.RequireCustomerRecord();
    
                ShoppingCart cart = new ShoppingCart(1, this.ThisCustomer, CartType, 0, false);
    
                foreach (Control ctrlRow in QuickOrderTable.Controls)
                {
                    quickorderformrow myOrderRow = ctrlRow as quickorderformrow;
                    if (myOrderRow == null)
                    {
                        continue;
                    }
    
                    myOrderRow.AddToCart(cart, ThisCustomer);
                }
    
                ((Literal)this.Page.FindControl("lrtNum_Cart_Items")).Text = ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString();
                ((UpdatePanel)this.Page.FindControl("CartUpdate")).Update();
            }
    
            private void AddRows()
            {
                AddRows(Convert.ToInt32(intNumOfRows.Value));
            }
    
            private void AddRows(int intRows)
            {
                for (int x = 1; x <= intRows; x++)
                {
                    AddRow();
                }
    
            }
    
            private void AddRow()
            {
                quickorderformrow myOrderRow = new quickorderformrow();
                QuickOrderTable.Rows.Add(myOrderRow);
    
            }
    
            protected void btnVerifyAll_Click(object sender, System.EventArgs e)
            {
                foreach (Control ctrlRow in QuickOrderTable.Controls)
                {
                    quickorderformrow myOrderRow = ctrlRow as quickorderformrow;
    
                    if (myOrderRow == null)
                    {
                        continue;
                    }
    
                    myOrderRow.GetNameAndIDs();
                }
    
            }
    
            protected void btnAddMoreRows_Click(object sender, System.EventArgs e)
            {
                intNumOfRows.Value += 4;
                AddRows(4);
            }
    
            protected void quickorderform_PreLoad(object sender, System.EventArgs e)
            {
                AddRows();
            }
            public quickorderform()
            {
                PreLoad += quickorderform_PreLoad;
                Init += quickorderform_Init;
            }
    
        }
    }
    The page loads but I am not seeing any input boxes and the add 4 rows button doesn't do anything.
    Last edited by chrismartz; 10-27-2011 at 06:38 AM. Reason: updated quickorder.aspx.cs code

  38. #38
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Have you stepped through the code to see what is happening?

    Initially it seems as if you haven't wired up any of the event handlers. Also, have in included the AJAX libraries in your site?

    Also, as I suggested before, why not just use the files as they are. You can use VB and C# simultaneously on a web site. At least do that initially to make sure everything in your setup is working correctly.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  39. #39
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    It was because I didn't have things wired up. I now have it working in C# but had to modify the Master.FindControl to be Master.Master.FindControl since I am using nested master pages on my site. Thanks!

  40. #40
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    I have found one issue. When trying to update the cart total, it acts like the total hasn't been updated yet. I'm using the following to update the subtotal:

    Code:
    ((Literal)Master.Master.FindControl("ltrCartSubTotal")).Text = Localization.CurrencyStringForDisplayWithoutExchangeRate(cart.SubTotal(true,false,true,true));
                ((UpdatePanel)Master.Master.FindControl("CartTotal")).Update();

  41. #41
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Did you wrap the code the displays the cart total in an UpdatePanel?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  42. #42
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    I have. When I do update, it just shows the total that was prior to adding whatever was just added.

    If I add $5 to the cart, the price shows as $0. When I add another $5 to the cart, the price show's as $5 when it should be $10. It seems as though there is a lag in the cart.SubTotal() function?

  43. #43
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    That is indicative of the update panel not working. I used to have the same issue. Are you seeing this in all browsers you try?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  44. #44
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    I have only tried in IE and Chrome but it is happening this way in both browsers. I have the following to update the price in the same location that I have the quantity of items updating.

    Code:
    ((Literal)Master.Master.FindControl("ltrNumCartItems")).Text = ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString();
                if (ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString() == "1")
                {
                    ((Literal)Master.Master.FindControl("ltrNumCartItemsOrItem")).Text = "Item";
                }
                else
                {
                    ((Literal)Master.Master.FindControl("ltrNumCartItemsOrItem")).Text = "Items";
                }
                ((Literal)Master.Master.FindControl("ltrCartSubTotal")).Text = Localization.CurrencyStringForDisplayWithoutExchangeRate(cart.SubTotal(true, false, true, true));
                ((UpdatePanel)Master.Master.FindControl("CartTotal")).Update();
                ((UpdatePanel)Master.Master.FindControl("CartUpdate")).Update();
    In my master template, I have the following:
    Code:
    <li class="cart-items"><asp:UpdatePanel runat="server" ID="CartUpdate" UpdateMode="Conditional"><ContentTemplate><a runat="server" href="~/shoppingcart.aspx"><strong>Shopping Cart</strong><span>(<asp:Literal ID="ltrNumCartItems" runat="server" Text="<%$ Tokens:Num_Cart_Items %>" /> <asp:Literal ID="ltrNumCartItemsOrItem" runat="server" Text="<%$ Tokens:Num_Cart_Items_Or_Item %>" />)</span></a></ContentTemplate></asp:UpdatePanel></li>
                                <li class="cart-total"><asp:UpdatePanel runat="server" ID="CartTotal" UpdateMode="Conditional"><ContentTemplate><a runat="server" href="~/shoppingcart.aspx"><asp:Literal ID="ltrCartSubTotal" runat="server" Text="<%$ Tokens:Cart_Subtotal %>" /></a></ContentTemplate></asp:UpdatePanel></li>
    The number of items updates as well as the wording "Item" or "Items".

  45. #45
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    So the number of items updates correctly, but not the total in the cart?

    When you browse the store and add items to the cart using other means, do the number of items and the total update correctly? Does the page refresh cause the values to update correctly?

    When you step through the code are the values you are setting correct?

    Are you executing the [OrderRow].AddToCart method before you try to update the cart or after?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  46. #46
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    That's correct. The number of items in the cart updates correctly but the subtotal of the cart doesn't update correctly.

  47. #47
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    So as you step through the code, is the value generated correct?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  48. #48
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    For some reason, cart.SubTotal is prior to whatever was added. I guess I need to move it out of btnAddToCart_Click function and into something else. Any suggestions?

  49. #49
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Can you show me your entire _Click routine?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  50. #50
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    Here is what the btnAddToCart_Click looks like. Whenit gets to updating the ltrCartSubtotal, the value of cart.subtotal is $0.

    Code:
    protected void btnAddToCart_Click(object sender, System.EventArgs e)
            {
                CartTypeEnum CartType = CartTypeEnum.ShoppingCart;
    
                this.ThisCustomer.RequireCustomerRecord();
    
                ShoppingCart cart = new ShoppingCart(1, this.ThisCustomer, CartType, 0, false);
                
    
                foreach (Control ctrlRow in QuickOrderTable.Controls)
                {
                    QuickOrderFormRow myOrderRow = ctrlRow as QuickOrderFormRow;
                    if (myOrderRow == null)
                    {
                        continue;
                    }
    
                    myOrderRow.AddToCart(cart, ThisCustomer);
                }
    
                ((Literal)Master.Master.FindControl("ltrNumCartItems")).Text = ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString();
                if (ShoppingCart.NumItems(ThisCustomer.CustomerID, CartTypeEnum.ShoppingCart).ToString() == "1")
                {
                    ((Literal)Master.Master.FindControl("ltrNumCartItemsOrItem")).Text = "Item";
                }
                else
                {
                    ((Literal)Master.Master.FindControl("ltrNumCartItemsOrItem")).Text = "Items";
                }
                ((Literal)Master.Master.FindControl("ltrCartSubTotal")).Text = Localization.CurrencyStringForDisplayWithoutExchangeRate(cart.SubTotal(true, false, true, true));
                ((UpdatePanel)Master.Master.FindControl("CartTotal")).Update();
                ((UpdatePanel)Master.Master.FindControl("CartUpdate")).Update();
            }

  51. #51
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Why not use the EstimatedTotal property or SubTotalRate property instead and see if that value is correct? Or perhaps the Total function or TotalRate property. Where possible it is best to use properties for recalling data from ASPDNSF.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  52. #52
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    I changed it to cart.SubTotalRate but that does the same thing. I don't understand why this is.

  53. #53
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Do all those values return the same value?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  54. #54
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    They do. They show the previous subtotal prior to adding items to the cart.

  55. #55
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    I wonder if calling the routine twice in a row would yield different results. Have you tried breaking execution at the time is trys to calculate the total and then looking in the database to see if the new item was committed yet?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  56. #56
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    So everything is working for you now?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  57. #57
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    I tried calling it twice but it still pulls the same amount. I'm totally lost in stopping the runtime to check the db. Still working on it but it's looking like I may have to go another route.

  58. #58
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    Do you know how to insert breakpoints in Visual Studio?
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM

  59. #59
    chrismartz is offline Senior Member
    Join Date
    Apr 2010
    Posts
    339

    Default

    Yes. So I just put a break point at the part where it's pulling the price and see if it's in the db? It should be shouldn't it since the number of items is correct.

  60. #60
    cjbarth is offline Senior Member
    Join Date
    Oct 2008
    Posts
    392

    Default

    If you put in a break point you can step through the code and see how the total is being calculated. If the total number of items is correct then the data must be in the database, so there might be a caching issue. Or you can query the database yourself and see what is actually in the tables as far as pricing goes.
    ML9.3.1.1
    SQL 2012 Express
    VS 2010
    Azure VM