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 Dictionary GetProductInfoId(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的世界吧!


留言
張貼留言