zoukankan      html  css  js  c++  java
  • C#&JQuery非缓存式无刷新临时存储数据之仿购物车功能

    感谢广大博问博友的帮助和共同研究讨论,终于实现了一个无缓存无刷新仿购物车的小功能:

    一、实现效果简述:

    有一种列表,是由双层Repeater嵌套,第一层用来显示类别,第二层用来显示类别下的商品数据,

    其显示效果如下:

    且每一个菜名都可以单独点开进行配餐选择,效果如下:

    现在要在页面无刷新不计入缓存(在最后提交选餐数据的时候计入缓存,类似购物车,但这里不希望页面刷新)

    的情况下将所选择的商品名称和数量无重复的添加到一个叫做“餐饮盒”的容器里:

    最终实现结果:

    在修改订购数量的时候只修改餐饮盒中该商品的总价格,商品名称不能重复,并重新计算所有商品的总价格:

    二、实现代码:

    1.前台界面由2个Repeater组成:

                            <asp:Repeater ID="rptFoodKindList" runat="server" OnItemDataBound="rptFoodKindList_OnItemDataBound">
                                <ItemTemplate>
                                    <div class="Cp_fl">
                                        <%#Eval("CategoryTwoName") %><asp:HiddenField ID="hidCategoryTwoID" Value='<%#Eval("CategoryTwoID") %>'
                                            runat="server" />
                                    </div>
                                    <asp:Repeater ID="rptFoodList" runat="server" OnItemDataBound="rptFoodList_OnItemDataBound">
                                        <ItemTemplate>
                                            <div class="CP_con">
                                                <ul>
                                                    <li class="CP_xh"><span id="spIndex" runat="server"></span></li>
                                                    <li class="CP_name"><span id="spProName">
                                                        <%#Eval("ProductName") %></span></li>
                                                    <li class="CP_jg"><%#decimal.Parse(Eval("Price").ToString()).ToString("f2") %></li>
                                                    <li class="CP_fs">(已选<span id="spCount">0</span>份)<asp:HiddenField ID="hidProductID"
                                                        runat="server" Value='<%#Eval("ProductID") %>' />
                                                    </li>
                                                </ul>
                                                <div class="CP_mx" style="display: none;">
                                                    <div class="img">
                                                        <img src="../ProductImg/160x120/201403011616.png" />
                                                        <a href="#">点击查看大图</a>
                                                    </div>
                                                    <div class="right">
                                                        <div class="R_name">
                                                            菜名:<%#Eval("ProductName") %>
                                                        </div>
                                                        <div class="R_dj">
                                                            单价:<span id="spPrice" runat="server"><%#decimal.Parse(Eval("Price").ToString()).ToString("f2") %></span>
                                                            元/份</div>
                                                        <div class="R_numer">
                                                            <span>订购数量:</span><a id="aRed" class="Redu1" runat="server"></a><input id="txtBuyNum"
                                                                type="text" value="1" runat="server" /><a class="Add1" id="aAdd" runat="server"></a></div>
                                                        <div class="R_but">
                                                            <a class="Add_CD" id="aAddTo" runat="server">加到我的餐饮盒</a><a class="Redu_CD">取消</a></div>
                                                    </div>
                                                </div>
                                            </div>
                                        </ItemTemplate>
                                    </asp:Repeater>
                                </ItemTemplate>
                            </asp:Repeater>
    <asp:HiddenField ID="hidProInfo" runat="server" />

    2.主要Jquery代码:

    (1)控制商品详情的显示和隐藏:

             $(function(){
                var n = 0; //商品详情和订购选择区域默认隐藏
                $(".CP_con").each(function () {
                    var t = $(this);//获取当前的行
                    t.find("ul").click(function () {
                        if (n == 0) {//如果隐藏则显示
                            t.find(".CP_mx").show();
                            n = 1; //设置为显示
                        }
                        else {//如果显示则隐藏
                            t.find(".CP_mx").hide();
                            n = 0;
                        }
                    });
    
                    var $cancel = $(".Redu_CD");//取消
                    var $CP_mx = $(".CP_mx");
                    t.find($cancel).click(function () {
                        t.find($CP_mx).hide();
                    });
    //鼠标放置和离开时当前行的样式控制,这里是淡蓝色; $(".CP_con>ul").mouseover(function () { $(this).attr("style", "background-color:#F5F9FD"); }).mouseout(function () { $(this).removeAttr("style"); }); }); }); })

    (2)修改商品订购数量以及更新餐饮盒情况:

            //修改订购产品数量,type=1:添加;type=2:减少
            function UpdateProductNum(btn, type, price) {
                var text = $(btn).parent().find(":text");
    
                if (type == 1) {
                    text.val(parseInt(text.val()) + 1);
                    if (parseInt(text.val()) <= 0)
                        text.val("1");
                }
                else {
                    text.val(parseInt(text.val()) - 1);
                    if (parseInt(text.val()) <= 0)
                        text.val("1");
                }
            }
    
            //添加到我的餐饮盒,修改其品数量,商品详情变动和价格计算
            function AddProductNum(btn, price, proid, index) {
                var proAmount = 0;//每一种商品的总价格
                var text = $(btn).parent().parent().find(":text");//查找修改数量的文本框
                var count = $(".CP_fs>span")[index];//获取当前商品已选择份数控件
                var proname = $(".CP_name>span")[index];//获取当前商品名称控件
                var spCount = $(btn).parent().parent().parent().parent().find(count);
                var spProName = $(btn).parent().parent().parent().parent().find(proname);
    
                spCount.html(text.val());//将当前份数设置为文本框中选择的份数
                var curAmount = price * text.val();//计算当前总订购商品的价格
    
                if ($("#ul" + proid).length > 0) {//如果已经存在该商品
                    $("#ul" + proid).attr("class", proid + "|" + text.val());//样式妙用,class用来存放商品id和订购数量,便于以下隐藏域使用
                    $("#ul" + proid).attr("title", "单价:¥"+price+".00;数量:"+text.val()+"份");//设置提示信息
                    $("#ul" + proid).html("<li class='li_l' >" + spProName.html() + "</li><li class='li_r'>¥" + curAmount + ".00</li>");//修改该商品的总价格信息
                }
                else {//不存在则添加一行
                    $("#divFoodBox").html($("#divFoodBox").html() + "<ul id='ul" + proid + "' class='" + proid + "|" + text.val() + "' title='单价:¥"+price+".00;数量:"+text.val()+"份''><li class='li_l' >" + spProName.html() + "</li><li class='li_r'>¥" + curAmount + ".00</li><ul>");
                }
    
                $("#divFoodBox .li_r").each(function () {//循环查找显示总价格的li控件
                    proAmount += parseFloat($(this).html().replace("¥", ""));//计算当前行商品总价格并追加到临时变量中;
                });
    
                var arrClass="";//初始化样式字符串
                $("#divFoodBox>ul").each(function () {
                    arrClass+=$(this).attr("class")+",";
                });
    
                $("#hidProInfo").val(arrClass);
                $("#liSum").html("¥" + proAmount+ ".00");//更新所有订购商品总价格
            }

    3.后台第一个Reapeter绑定时追加前台js方法:

            /// <summary>
            /// 菜谱分类列表绑定事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void rptFoodKindList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
            {
                if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                {
                    Repeater rptFoodList = e.Item.FindControl("rptFoodList") as Repeater;//第一个Reapeter的每行绑定时查找第二层里面的Reapeter
                    HiddenField hidCategoryTwoID = e.Item.FindControl("hidCategoryTwoID") as HiddenField;
                    rptFoodList.DataSource = HSSM_Public_DB.PblicQuery("ProductID,ProductName,Price", "Product", "CategoryTwoID = " + hidCategoryTwoID.Value);
                    rptFoodList.DataBind();//绑定里面的Reapeter
    
                    //循环里面Reapeter的项,并给相应控件追加前台js方法
                    foreach (RepeaterItem item in rptFoodList.Items)
                    {
                        HtmlInputText txtBuyNum = item.FindControl("txtBuyNum") as HtmlInputText;//查找订购数量输入框
                        HtmlGenericControl spPrice = item.FindControl("spPrice") as HtmlGenericControl;//查找显示价格的控件
                        HtmlGenericControl spIndex = item.FindControl("spIndex") as HtmlGenericControl;//查找显示该商品所属分类的序号控件
                        string Price = spPrice.InnerText.Replace("", "");
                        spIndex.InnerText = item.ItemIndex + 1 + ".";//设置序号
    
                        HtmlAnchor aAdd = item.FindControl("aAdd") as HtmlAnchor;//添加订购数量的控件
                        HtmlAnchor aRed = item.FindControl("aRed") as HtmlAnchor;//减少订购数量的控件
                        HtmlAnchor aAddTo = item.FindControl("aAddTo") as HtmlAnchor;//添加到我的餐饮盒的控件
                        HiddenField hidProductID = item.FindControl("hidProductID") as HiddenField;//存放商品id的隐藏域                   aAdd.Attributes.Add("onclick", string.Format("UpdateProductNum(this,1,{0})", Price));//追加添加订购数量的js方法
                        aRed.Attributes.Add("onclick", string.Format("UpdateProductNum(this,2,{0})", Price));//追加减少订购数量的js方法
                        aAddTo.Attributes.Add("onclick", string.Format("AddProductNum(this,{0},{1},{2})", Price, hidProductID.Value, proIndex));//追加更新我的餐饮盒详情的js方法
    
                        proIndex++;//每绑定一行商品让这个全局变量值自加1,用于前台js调用find方法寻找当前商品已选择份数和商品名称时使用,
                    }
                }
            }
    
            /// <summary>
            /// 产品记录索引(全局变量)
            /// </summary>
            public int proIndex = 0;

    4.最后填写好订购人信息后计入缓存:

            /// <summary>
            /// 设置Cookie
            /// </summary>
            protected void SetFoodList()
            {
                string ProInfos = hidProInfo.Value.Substring(0, hidProInfo.Value.Length - 1);//获取最后所有的商品的id和数量信息,这里需要去掉最后一个逗号
                string[] arrProInfos = ProInfos.Split(',');
                HttpCookie cookieFood = new HttpCookie("MyShoppingCart");//初始化一个Cookie对象
    
                foreach (string strProInfo in arrProInfos)
                {
                    string strProID = strProInfo.Split('|')[0];//商品id
                    string strProCount = strProInfo.Split('|')[1];//该商品订购数量
    
                    ProModel = GetProModel(strProID);
                    ImagesModel = GetProImageModel(strProID);
    
                    //DateTime dt = DateTime.Now;
                    //TimeSpan ts = new TimeSpan(0, 0, 1, 0, 0);//过期时间为1分钟
                    //cookie.Expires = dt.Add(ts);//设置过期时间
    
                    //设置cookie的值
                    cookieFood.Values.Add("Company", ComModel.Company);
                    cookieFood.Values.Add("ProductID", strProID);
                    cookieFood.Values.Add("ProductName", ProModel.ProductName);
                    cookieFood.Values.Add("SaleUserID", SaleUserID.ToString());
                    cookieFood.Values.Add("ProductImg", ImagesModel.ImageUrl);
                    cookieFood.Values.Add("Price", ProModel.Price.Value.ToString("f2"));
                    cookieFood.Values.Add("Bonus", "1");
                    cookieFood.Values.Add("Count", strProCount);
    
                    Response.Cookies.Add(cookieFood);
                }
            }
    
            /// <summary>
            /// 保存配送信息
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void btnDispatch_Click(object sender, EventArgs e)
            {
                SetFoodList();
                Response.Redirect("OrderInfo.aspx");
            }

    小插曲→计入到关键隐藏域hidProInfo的值是这样的:

    ok,感谢主,这个功能就此结束了,之前有博问博友建议加到餐饮盒时就加入缓存,但是考虑到需要后台处理,页面会刷新,如果用ajax也可以实现局部异步刷新,过后我再尝试一下看看,不过我这种实现方法是另一种思路,我选择最后点击“OK,下一步”的时候计入缓存到那边选餐订单确认页面获取缓存显示商品情况。其实这当中关键点就是一个class的妙用(本来class是用来指定样式表,这里用来存放数据未尝不可)和隐藏域的使用。

  • 相关阅读:
    黄页js-sdk开发总结分享
    最近的shell脚本(updating)
    nginx location 的配置
    nodejs 的安全
    paypal之nodejs 框架 Kraken-js 源码分析
    nodejs express 框架解密5-视图
    nodejs express 框架解密4-路由
    nodejs express 框架解密3-中间件模块
    nodejs express 框架解密2-如何创建一个app
    nodejs express 框架解密1-总体结构
  • 原文地址:https://www.cnblogs.com/gawking/p/3584592.html
Copyright © 2011-2022 走看看