CSS&javascript 產品分頁&購物車清單
這是接續購物產品列表的部份
之前透過DataList產生出全部的產品列表
css&javascript 連製資料庫撈出圖片(datalist)
這有個滿大的問題就是…他沒有分頁
沒錯,抓出來所有的資料都會在同一頁
實在滿痛的,中文北風只有77個產品還好一點
如果今天有7千個呢?光圖片就很耗流量了
所以今天要實現將抓出來的產品分頁,並接著完成購物車的事件
首先,必須在SQL Server中先建立好預存程序
並賦予可以使用PROCEDURE的權限:
以上如果不懂可以參考之前做過SQL Server的筆記:
SQL Server 資料庫的權限設定
SQL Server 一般資料表運算式(CTE)
SQL Server EXECUTE指令及STORED PROCEDURE
SQL Server Row相關的函數
產品分頁1 或 產品分頁2 都是一樣的
會跟據使用者選擇的頁數,回傳該頁數的結果
例如點選1,會回傳1~10筆的產品
=============================================================================
接著,我們要對NWDB資料庫繫結的類別庫進行修改
這邊會執行2個部份:
=============================================================================
資料庫是前置作業,設定完成後,接著網頁介面aspx撰寫:
看起來很複雜,其實是aspx元件DataList拉一拉改改配置
並在最下面放個Literal,會利用程式碼來實現變身的行為
接著就是網頁裡的的程式碼:
=============================================================================
以上即完成分頁,最後就是購物清單
在網頁撰寫的部份,每個產品都已經放入了購物車圖
並設定連結為:<a href="AddToCart.aspx?pid=<%# Eval("產品編號") %>">
就是會傳該產品編號給 AddToCart.aspx 這個網頁
在這個網頁介面其實只拉出了一個GridView元件
所有清單的增加都是用後面的AddToCart.aspx.cs在做事:
到此,完成產品分頁及購物車採買的事件
寫起來落落長,其實真的在寫還好懂的
aspx到此真的告一段落,開始進入MVC的世界吧!
之前透過DataList產生出全部的產品列表
css&javascript 連製資料庫撈出圖片(datalist)
這有個滿大的問題就是…他沒有分頁
沒錯,抓出來所有的資料都會在同一頁
實在滿痛的,中文北風只有77個產品還好一點
如果今天有7千個呢?光圖片就很耗流量了
所以今天要實現將抓出來的產品分頁,並接著完成購物車的事件
首先,必須在SQL Server中先建立好預存程序
並賦予可以使用PROCEDURE的權限:
use 中文北風 go --sql 2012前 用cte----------------------------------------------------- CREATE PROCEDURE 產品分頁1 @page INT AS DECLARE @start INT DECLARE @end INT SET @start = (@page-1)*10+1 SET @end = @page*10; WITH temp as ( SELECT 產品資料.產品編號, 產品資料.產品, 供應商.供應商, 產品類別.類別名稱, 產品資料.單位數量, 產品資料.單價, 產品資料.庫存量 ,ROW_NUMBER() OVER(ORDER BY 產品編號) AS 序號 FROM 供應商 INNER JOIN 產品資料 ON 供應商.供應商編號 = 產品資料.供應商編號 INNER JOIN 產品類別 ON 產品資料.類別編號 = 產品類別.類別編號 ) SELECT 產品編號,產品,供應商,類別名稱,單位數量,單價,庫存量 FROM temp WHERE 序號 BETWEEN @start AND @end GO --sql 2012後才有的offset------------------------------------------------------ CREATE PROCEDURE 產品分頁2 @page INT AS DECLARE @skip INT SET @skip = (@page-1)*10; SELECT 產品資料.產品編號, 產品資料.產品, 供應商.供應商, 產品類別.類別名稱, 產品資料.單位數量, 產品資料.單價, 產品資料.庫存量 FROM 供應商 INNER JOIN 產品資料 ON 供應商.供應商編號 = 產品資料.供應商編號 INNER JOIN 產品類別 ON 產品資料.類別編號 = 產品類別.類別編號 ORDER BY 產品編號 OFFSET @skip ROWS FETCH NEXT 10 ROWS ONLY --由於原本sqluser 沒有執行proc的權限,所以要賦予給他 GRANT EXECUTE TO SQLuser
以上如果不懂可以參考之前做過SQL Server的筆記:
SQL Server 資料庫的權限設定
SQL Server 一般資料表運算式(CTE)
SQL Server EXECUTE指令及STORED PROCEDURE
SQL Server Row相關的函數
產品分頁1 或 產品分頁2 都是一樣的
會跟據使用者選擇的頁數,回傳該頁數的結果
例如點選1,會回傳1~10筆的產品
=============================================================================
接著,我們要對NWDB資料庫繫結的類別庫進行修改
這邊會執行2個部份:
- 要求資料庫回傳產品的總數,如此才可以做分頁
- 當使用者點選購物車,會去資料庫找出產品資料並加入購物清單列表
先修改介面IProduct.cs
public interface IProduct { DataTable SearchProduct();//這裡不做,可以不理 int ProductCount(); Dictionary<string object=""> GetProductInfoId(int productId); }
再修改實作ImpIProduct.cs
public class ImpIProduct:IProduct { private SqlConnection cnn; public ImpIProduct(SqlConnection cnn) { this.cnn = cnn; } //----------------------------------------------------------------- #region 尋找產品 public DataTable SearchProduct() { //先不做,之後進入MVC再做 return null; } #endregion 尋找產品 //----------------------------------------------------------------- #region 產品總數 public int ProductCount() { SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM 產品資料", cnn); cnn.Open(); int ProductCount =(int) cmd.ExecuteScalar(); cmd.Dispose(); cnn.Close(); return ProductCount; } #endregion 產品總數 //----------------------------------------------------------------- #region 購物車加入 public Dictionary<string, object> GetProductInfoId(int productId) { SqlCommand cmd = new SqlCommand("SELECT 產品,單價 FROM 產品資料 WHERE 產品編號 = @Pid", cnn); cmd.Parameters.Add("@Pid", SqlDbType.Int).Value = productId; Dictionary<string, object> result = null; cnn.Open(); SqlDataReader mydr = cmd.ExecuteReader(); //如果有資料 if (mydr.HasRows) { result = new Dictionary<string,object>(); mydr.Read(); result.Add("產品編號",productId); result.Add("產品名稱", mydr[0]); result.Add("單價", mydr[1]); } cmd.Dispose(); cnn.Close(); return result; } #endregion 購物車加入 }
最後修改NWDB.cs中「#region 產品」裡的方法
//引入實作的方法 #region 產品 public DataTable SearchProduct() { return ip.SearchProduct(); } public int ProductCount() { return ip.ProductCount(); } public DictionaryGetProductInfoId(int productId) { return ip.GetProductInfoId(productId); } #endregion 產品
=============================================================================
資料庫是前置作業,設定完成後,接著網頁介面aspx撰寫:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Data3.aspx.cs" Inherits="WebPractice.Data.data3" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <style type="text/css"> //使整個產品資料表置中 #ResultDiv { margin-left:auto; margin-right:auto; width:800px; } </style> </head> <body> <form id="form1" runat="server"> <div id="ResultDiv"> <asp:DataList ID="DataList1" runat="server" DataKeyField="產品編號" DataSourceID="SqlDataSource1" Width="700px"> <ItemTemplate> <table cellpadding="5" cellspacing="0" width="100%"> <tr> <td width="150"><img src="/Tools/GetProductImage.ashx?pid=<%# Eval("產品編號") %>" /></td> <td> <table cellpadding="10" cellspacing="0" class="auto-style1"> <tr> <td colspan="4"><asp:Label ID="產品Label" runat="server" Text='<%# Eval("產品") %>' /></td> </tr> <tr> <td align="right" width="80">產品編號:</td> <td><asp:Label ID="產品編號Label" runat="server" Text='<%# Eval("產品編號") %>' /></td> <td align="right" width="80">單位數量:</td> <td><asp:Label ID="單位數量Label" runat="server" Text='<%# Eval("單位數量") %>' /></td> </tr> <tr> <td align="right" width="80">單價:</td> <td> <asp:Label ID="單價Label" runat="server" Text='<%# Eval("單價") %>' /> </td> <td align="right" width="80">供應商:</td> <td> <asp:Label ID="供應商Label" runat="server" Text='<%# Eval("供應商") %>' /> </td> </tr> <tr> <td align="right" width="80">類別名稱:</td> <td> <asp:Label ID="類別名稱Label" runat="server" Text='<%# Eval("類別名稱") %>' /> </td> <td align="right" width="80">庫存量:</td> <td> <asp:Label ID="庫存量Label" runat="server" Text='<%# Eval("庫存量") %>' /> </td> </tr> <tr> <!-- ============================購物車圖放入 ============================--> <!-- 放入購物車圖,並設定連結pid = 產品的編號 --> <td colspan="4"><a href="AddToCart.aspx?pid=<%# Eval("產品編號") %>"><img src="/images/Shapping_cart.png" title="買了他!" border="0"/></a></td> <td> </td> <td> </td> <td> </td> </tr> </table> </td> </tr> </table> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:中文北風ConnectionString %>" SelectCommand="產品分頁1" SelectCommandType="StoredProcedure"> <SelectParameters> <asp:QueryStringParameter DefaultValue="1" Name="Page" QueryStringField="p" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <p style="text-align:center"> <!-- ===========================Literal放入 ============================--> <!-- 程式執行分頁行為 --> <asp:Literal ID="PageLiteral" runat="server"></asp:Literal></p> </div> </form> </body> </html>
看起來很複雜,其實是aspx元件DataList拉一拉改改配置
並在最下面放個Literal,會利用程式碼來實現變身的行為
接著就是網頁裡的的程式碼:
public partial class data3 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { int currentPage = 0; //如果TryParse「不」成功,回傳第1頁,成功就out currentPage if(!int.TryParse(Request.QueryString["p"] ,out currentPage)) currentPage =1; //繫結資料庫 NWDB.NWDB nwdb = new NWDB.NWDB(); NWDB.IProduct ip = new NWDB.ImpIProduct(nwdb.Connection); nwdb.SetProduct(ip); int productcount = nwdb.ProductCount(); //總頁數,Ceiling是無條件進位,或是回傳大於或等於指定數值運算式的最小整數。 int totalPage = (int)Math.Ceiling(productcount / 10.0); StringBuilder sb = new StringBuilder(); for(int i = 1 ; i <= totalPage; i++) { if (i == currentPage) sb.Append(String.Format("{0} ", i)); else sb.Append(String.Format("<a href=\"Data3.aspx?p={0}\">{0}</a> ", i)); } //將PageLiteral變身成頁碼 PageLiteral.Text = sb.ToString(); } }
=============================================================================
以上即完成分頁,最後就是購物清單
在網頁撰寫的部份,每個產品都已經放入了購物車圖
並設定連結為:<a href="AddToCart.aspx?pid=<%# Eval("產品編號") %>">
就是會傳該產品編號給 AddToCart.aspx 這個網頁
在這個網頁介面其實只拉出了一個GridView元件
所有清單的增加都是用後面的AddToCart.aspx.cs在做事:
protected void Page_Load(object sender, EventArgs e) { int productId = 0; if (!int.TryParse(Request.QueryString["Pid"], out productId)) Response.Redirect("Data3.aspx"); //設定一個空的Datatable DataView dv; //如果沒買過 if (Session["Cart"] == null) { DataTable tt = new DataTable(); tt.Columns.Add("產品編號", Type.GetType("System.Int32")); tt.Columns.Add("產品名稱", Type.GetType("System.String")); tt.Columns.Add("單價", Type.GetType("System.Double")); tt.Columns.Add("數量", Type.GetType("System.Int32")); tt.Columns.Add("金額", Type.GetType("System.Int32"), "單價*數量"); //放入datatable dv = tt.DefaultView; } else { dv =(DataView)Session["Cart"]; } //要先排列清單才可抓出沒買過的產品 dv.Sort = "產品編號 ASC"; //找出傳過來的值,是否有在購買列表中 int index = dv.Find(productId); //如果找不到index會是-1,小於零 if (index < 0) { DataTable ttt = dv.Table; DataRow rr = ttt.NewRow(); NWDB.NWDB mydb = new NWDB.NWDB(); NWDB.IProduct ip = new NWDB.ImpIProduct(mydb.Connection); mydb.SetProduct(ip); //將網頁傳來的productId放入nwdb中的查找方法 Dictionary<string object> getResult = mydb.GetProductInfoId(productId); //如果資料庫中沒有這個產品,就跳轉回產品清單 if (getResult == null) Response.Redirect("Data3.aspx"); rr["產品編號"] = getResult["產品編號"]; rr["產品名稱"] = getResult["產品名稱"]; rr["單價"] = getResult["單價"]; rr["數量"] = 1; ttt.Rows.Add(rr); } else { //找出dv列中,index那一列,「數量」那一格,找出後+1 dv[index]["數量"] =(int) dv[index]["數量"] + 1; } //寫回Session,如此才會增加一筆 Session["Cart"] = dv; GridView1.DataSource = dv; GridView1.DataBind(); }
到此,完成產品分頁及購物車採買的事件
寫起來落落長,其實真的在寫還好懂的
aspx到此真的告一段落,開始進入MVC的世界吧!
留言
張貼留言