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

一、实现效果简述:

有一种列表,是由双层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 + + ".";//设置序号 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 = ;

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

        /// <summary>
/// 设置Cookie
/// </summary>
protected void SetFoodList()
{
string ProInfos = hidProInfo.Value.Substring(, hidProInfo.Value.Length - );//获取最后所有的商品的id和数量信息,这里需要去掉最后一个逗号
string[] arrProInfos = ProInfos.Split(',');
HttpCookie cookieFood = new HttpCookie("MyShoppingCart");//初始化一个Cookie对象 foreach (string strProInfo in arrProInfos)
{
string strProID = strProInfo.Split('|')[];//商品id
string strProCount = strProInfo.Split('|')[];//该商品订购数量 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", "");
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是用来指定样式表,这里用来存放数据未尝不可)和隐藏域的使用。

C#&JQuery非缓存式无刷新临时存储数据之仿购物车功能的更多相关文章

  1. 本篇文章主要是对jquery+ajax+C#实现无刷新操作数据库数据的简单实例进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助

    我们知道同步执行和异步执行的区别,为了更好的提高用户的体验,我们都会采用异步方式去处理一些问题,毕竟单线程的同步可能回造成卡死等现象,很不友好,所以可以使用ajax来完成用户的体验,现在我们就来说说如 ...

  2. asp.netajax与jquery和bootstrap的无刷新完美实现

    20190421asp.netajax与jquery和bootstrap的无刷新完美实现 设计代码和后台代码中重要部分加粗和深色以及字号加大. 设计前台代码: <%@ Page Title=&q ...

  3. jQuery+php+ajax实现无刷新上传文件功能

    jQuery+php+ajax实现无刷新上传文件功能,还带有上传进度条动画效果,支持图片.视频等大文件上传. js代码 <script type='text/javascript' src='j ...

  4. JSF中使用f:ajax标签无刷新页面改变数据

    ajax本是用在前端的一种异步请求数据的操作,广泛用于js中,一般的js框架如jq都有被封装好的方法,用于发起异步请求操作.异步操作可以增强用户体验和操作,越来越多的程序都在使用ajax.JSF的fa ...

  5. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  6. 前台JS(Jquery)调用后台方法 无刷新级联菜单示例

    前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 下面是做的一个前台用JQUERY,AJAX调用后台方法做的无刷新级联菜单 http://www.dtan.so CasMenu.aspx页 ...

  7. jQuery+AJAX实现网页无刷新上传

    新年礼,提供简单.易套用的 jQuery AJAX上传示例及代码下载.后台对文件的上传及检查,以 C#/.NET Handler 处理 (可视需要改写成 Java 或 PHP). 有时做一个网站项目 ...

  8. jquery ajax php+mysql 无刷新分页 详细实例

    最近在接触jquery和ajax,当前项目也会用到分页,为了用户体验更好一些,就准备用无刷新分页,这个demo很适合新手学习查看,写的比较清晰,话不多说,直接上代码吧. 首先是html页面,index ...

  9. jQuery Pagination分页插件--无刷新

    源码:https://github.com/SeaLee02/FunctionModule/blob/master/UploadFiles/WebDemo/FenYE/FenYeAjax.aspx 代 ...

随机推荐

  1. 【原】SparkContex源码解读(一)

    版权声明:本文为原创文章,未经允许不得转载. SparkContext(简称sc)是Spark程序的主入口,代表一个连接到Spark集群(Standalone.YARN.Mesos三种集群部署模式)的 ...

  2. synchronize学习

    这个例子我们看到,java中将对象或者Class对象当做锁 package synchronized简单使用; public class Test7 extends Thread{ public st ...

  3. oracle rac IP详解

    rac环境下vip/public/private IP的区别 每个节点要2块网卡, 3个IP,虚拟IP或者叫做业务IP,单个网卡当掉可以“漂”到其他网卡是继续提供服务 在Oracle RAC环境下,每 ...

  4. 使用C#模拟ASP.NET页面中按钮点击

    c# 模拟Asp.net页面中的某个按钮的点击,向web服务器发出请求 主要就组织要提交的数据,然后以post方式提交. 假设我们有如下的网页 1 <% @ Page Language = &q ...

  5. java 小结1(static ,final,泛型)

    static,final. (1)final: final:属于“终态”,意思就是不可以改变.可以修饰非抽象类,非抽象类的方法等.反正就是不能够再改变赋值了. 注意:1)fina类不能被继承,所以它没 ...

  6. 每个android项目都应该使用的android 库

    http://blog.teamtreehouse.com/android-libraries-use-every-project A good developer knows to never re ...

  7. A Tour of Go Making slices

    Slices are created with the make function. It works by allocating a zeroed array and returning a sli ...

  8. C++下字符串转换

    引用自:http://blog.sina.com.cn/s/blog_a98e39a20101ari9.html 把最近用到的各种unicode下类型转换总结了一下,今后遇到其他的再补充: 1.str ...

  9. 横竖屏事件响应(viewWillLayoutSubviews和通知)两种方式

    转载:http://blog.csdn.net/nogodoss/article/details/17246489 最近搞横竖屏,获得一些心得,特记录下来. 做横竖屏最重要的是确定横竖屏响应的接口.目 ...

  10. Unity: How to build and debug external DLLs

    法一:http://forum.unity3d.com/threads/161685-How-to-build-and-debug-external-DLLs http://docs.unity3d. ...