加入購物車功能
先簡單了解一下主題中的檔案:
使用Shopping cart JS
- style.css 主題的格式宣告與主要的格式
- index.php 顯示部落客文章的索引頁面
- page.php 靜態頁面的範本
- page-full.php 無sidebar(側欄)的靜態頁面範本
- header.php及footer.php 供index.php、page.php、page-full.php等索引頁面、靜態頁面範本含入的頭及尾巴部份。
- sidebar.php 側欄
使用Shopping cart JS
-
- 將上面網站中的cart.js加到主題目錄中的assets/js (因為WordPress的關係,不能使用jQuery特殊的$字符,這部份必須改為jQuery,所以這個源碼是我改過的)。
// ************************************************
// Shopping Cart API
// ************************************************
var shoppingCart = (function() {
// =============================
// Private methods and propeties
// =============================
cart = [];
// Constructor
function Item(name, price, count) {
this.name = name;
this.price = price;
this.count = count;
}
// Save cart
function saveCart() {
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
}
// Load cart
function loadCart() {
cart = JSON.parse(sessionStorage.getItem('shoppingCart'));
}
if (sessionStorage.getItem("shoppingCart") != null) {
loadCart();
}
// =============================
// Public methods and propeties
// =============================
var obj = {};
// Add to cart
obj.addItemToCart = function(name, price, count) {
for(var item in cart) {
if(cart[item].name === name) {
cart[item].count ++;
saveCart();
return;
}
}
var item = new Item(name, price, count);
cart.push(item);
saveCart();
}
// Set count from item
obj.setCountForItem = function(name, count) {
for(var i in cart) {
if (cart[i].name === name) {
cart[i].count = count;
break;
}
}
};
// Remove item from cart
obj.removeItemFromCart = function(name) {
for(var item in cart) {
if(cart[item].name === name) {
cart[item].count --;
if(cart[item].count === 0) {
cart.splice(item, 1);
}
break;
}
}
saveCart();
}
// Remove all items from cart
obj.removeItemFromCartAll = function(name) {
for(var item in cart) {
if(cart[item].name === name) {
cart.splice(item, 1);
break;
}
}
saveCart();
}
// Clear cart
obj.clearCart = function() {
cart = [];
saveCart();
}
// Count cart
obj.totalCount = function() {
var totalCount = 0;
for(var item in cart) {
totalCount += cart[item].count;
}
return totalCount;
}
// Total cart
obj.totalCart = function() {
var totalCart = 0;
for(var item in cart) {
totalCart += cart[item].price * cart[item].count;
}
return Number(totalCart.toFixed(2));
}
// List cart
obj.listCart = function() {
var cartCopy = [];
for(i in cart) {
item = cart[i];
itemCopy = {};
for(p in item) {
itemCopy[p] = item[p];
}
itemCopy.total = Number(item.price * item.count).toFixed(2);
cartCopy.push(itemCopy)
}
return cartCopy;
}
// cart : Array
// Item : Object/Class
// addItemToCart : Function
// removeItemFromCart : Function
// removeItemFromCartAll : Function
// clearCart : Function
// countCart : Function
// totalCart : Function
// listCart : Function
// saveCart : Function
// loadCart : Function
return obj;
})();
// *****************************************
// Triggers / Events
// *****************************************
// Add item
jQuery('.add-to-cart').click(function(event) {
event.preventDefault();
var name = jQuery(this).data('name');
var price = Number(jQuery(this).data('price'));
shoppingCart.addItemToCart(name, price, 1);
displayCart();
});
// Clear items
jQuery('.clear-cart').click(function() {
shoppingCart.clearCart();
displayCart();
});
function displayCart() {
var cartArray = shoppingCart.listCart();
var output = "";
for(var i in cartArray) {
output += "<tr>"
+ "<td>" + cartArray[i].name + "</td>"
+ "<td>(" + cartArray[i].price + ")</td>"
+ "<td><div class='input-group'><button class='minus-item input-group-addon btn btn-primary' data-name=" + cartArray[i].name + ">-</button>"
+ "<input type='number' class='item-count form-control' data-name='" + cartArray[i].name + "' value='" + cartArray[i].count + "'>"
+ "<button class='plus-item btn btn-primary input-group-addon' data-name=" + cartArray[i].name + ">+</button></div></td>"
+ "<td><button class='delete-item btn btn-danger' data-name=" + cartArray[i].name + ">X</button></td>"
+ " = "
+ "<td>" + cartArray[i].total + "</td>"
+ "</tr>";
}
jQuery('.show-cart').html(output);
jQuery('.total-cart').html(shoppingCart.totalCart());
jQuery('.total-count').html(shoppingCart.totalCount());
}
// Delete item button
jQuery('.show-cart').on("click", ".delete-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.removeItemFromCartAll(name);
displayCart();
})
// -1
jQuery('.show-cart').on("click", ".minus-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.removeItemFromCart(name);
displayCart();
})
// +1
jQuery('.show-cart').on("click", ".plus-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.addItemToCart(name);
displayCart();
})
// Item count input
jQuery('.show-cart').on("change", ".item-count", function(event) {
var name = jQuery(this).data('name');
var count = Number(jQuery(this).val());
shoppingCart.setCountForItem(name, count);
displayCart();
});
displayCart();
// ************************************************
// Shopping Cart API
// ************************************************
var shoppingCart = (function() {
// =============================
// Private methods and propeties
// =============================
cart = [];
// Constructor
function Item(name, price, count) {
this.name = name;
this.price = price;
this.count = count;
}
// Save cart
function saveCart() {
sessionStorage.setItem('shoppingCart', JSON.stringify(cart));
}
// Load cart
function loadCart() {
cart = JSON.parse(sessionStorage.getItem('shoppingCart'));
}
if (sessionStorage.getItem("shoppingCart") != null) {
loadCart();
}
// =============================
// Public methods and propeties
// =============================
var obj = {};
// Add to cart
obj.addItemToCart = function(name, price, count) {
for(var item in cart) {
if(cart[item].name === name) {
cart[item].count ++;
saveCart();
return;
}
}
var item = new Item(name, price, count);
cart.push(item);
saveCart();
}
// Set count from item
obj.setCountForItem = function(name, count) {
for(var i in cart) {
if (cart[i].name === name) {
cart[i].count = count;
break;
}
}
};
// Remove item from cart
obj.removeItemFromCart = function(name) {
for(var item in cart) {
if(cart[item].name === name) {
cart[item].count --;
if(cart[item].count === 0) {
cart.splice(item, 1);
}
break;
}
}
saveCart();
}
// Remove all items from cart
obj.removeItemFromCartAll = function(name) {
for(var item in cart) {
if(cart[item].name === name) {
cart.splice(item, 1);
break;
}
}
saveCart();
}
// Clear cart
obj.clearCart = function() {
cart = [];
saveCart();
}
// Count cart
obj.totalCount = function() {
var totalCount = 0;
for(var item in cart) {
totalCount += cart[item].count;
}
return totalCount;
}
// Total cart
obj.totalCart = function() {
var totalCart = 0;
for(var item in cart) {
totalCart += cart[item].price * cart[item].count;
}
return Number(totalCart.toFixed(2));
}
// List cart
obj.listCart = function() {
var cartCopy = [];
for(i in cart) {
item = cart[i];
itemCopy = {};
for(p in item) {
itemCopy[p] = item[p];
}
itemCopy.total = Number(item.price * item.count).toFixed(2);
cartCopy.push(itemCopy)
}
return cartCopy;
}
// cart : Array
// Item : Object/Class
// addItemToCart : Function
// removeItemFromCart : Function
// removeItemFromCartAll : Function
// clearCart : Function
// countCart : Function
// totalCart : Function
// listCart : Function
// saveCart : Function
// loadCart : Function
return obj;
})();
// *****************************************
// Triggers / Events
// *****************************************
// Add item
jQuery('.add-to-cart').click(function(event) {
event.preventDefault();
var name = jQuery(this).data('name');
var price = Number(jQuery(this).data('price'));
shoppingCart.addItemToCart(name, price, 1);
displayCart();
});
// Clear items
jQuery('.clear-cart').click(function() {
shoppingCart.clearCart();
displayCart();
});
function displayCart() {
var cartArray = shoppingCart.listCart();
var output = "";
for(var i in cartArray) {
output += "<tr>"
+ "<td>" + cartArray[i].name + "</td>"
+ "<td>(" + cartArray[i].price + ")</td>"
+ "<td><div class='input-group'><button class='minus-item input-group-addon btn btn-primary' data-name=" + cartArray[i].name + ">-</button>"
+ "<input type='number' class='item-count form-control' data-name='" + cartArray[i].name + "' value='" + cartArray[i].count + "'>"
+ "<button class='plus-item btn btn-primary input-group-addon' data-name=" + cartArray[i].name + ">+</button></div></td>"
+ "<td><button class='delete-item btn btn-danger' data-name=" + cartArray[i].name + ">X</button></td>"
+ " = "
+ "<td>" + cartArray[i].total + "</td>"
+ "</tr>";
}
jQuery('.show-cart').html(output);
jQuery('.total-cart').html(shoppingCart.totalCart());
jQuery('.total-count').html(shoppingCart.totalCount());
}
// Delete item button
jQuery('.show-cart').on("click", ".delete-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.removeItemFromCartAll(name);
displayCart();
})
// -1
jQuery('.show-cart').on("click", ".minus-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.removeItemFromCart(name);
displayCart();
})
// +1
jQuery('.show-cart').on("click", ".plus-item", function(event) {
var name = jQuery(this).data('name')
shoppingCart.addItemToCart(name);
displayCart();
})
// Item count input
jQuery('.show-cart').on("change", ".item-count", function(event) {
var name = jQuery(this).data('name');
var count = Number(jQuery(this).val());
shoppingCart.setCountForItem(name, count);
displayCart();
});
displayCart();
// ************************************************ // Shopping Cart API // ************************************************ var shoppingCart = (function() { // ============================= // Private methods and propeties // ============================= cart = []; // Constructor function Item(name, price, count) { this.name = name; this.price = price; this.count = count; } // Save cart function saveCart() { sessionStorage.setItem('shoppingCart', JSON.stringify(cart)); } // Load cart function loadCart() { cart = JSON.parse(sessionStorage.getItem('shoppingCart')); } if (sessionStorage.getItem("shoppingCart") != null) { loadCart(); } // ============================= // Public methods and propeties // ============================= var obj = {}; // Add to cart obj.addItemToCart = function(name, price, count) { for(var item in cart) { if(cart[item].name === name) { cart[item].count ++; saveCart(); return; } } var item = new Item(name, price, count); cart.push(item); saveCart(); } // Set count from item obj.setCountForItem = function(name, count) { for(var i in cart) { if (cart[i].name === name) { cart[i].count = count; break; } } }; // Remove item from cart obj.removeItemFromCart = function(name) { for(var item in cart) { if(cart[item].name === name) { cart[item].count --; if(cart[item].count === 0) { cart.splice(item, 1); } break; } } saveCart(); } // Remove all items from cart obj.removeItemFromCartAll = function(name) { for(var item in cart) { if(cart[item].name === name) { cart.splice(item, 1); break; } } saveCart(); } // Clear cart obj.clearCart = function() { cart = []; saveCart(); } // Count cart obj.totalCount = function() { var totalCount = 0; for(var item in cart) { totalCount += cart[item].count; } return totalCount; } // Total cart obj.totalCart = function() { var totalCart = 0; for(var item in cart) { totalCart += cart[item].price * cart[item].count; } return Number(totalCart.toFixed(2)); } // List cart obj.listCart = function() { var cartCopy = []; for(i in cart) { item = cart[i]; itemCopy = {}; for(p in item) { itemCopy[p] = item[p]; } itemCopy.total = Number(item.price * item.count).toFixed(2); cartCopy.push(itemCopy) } return cartCopy; } // cart : Array // Item : Object/Class // addItemToCart : Function // removeItemFromCart : Function // removeItemFromCartAll : Function // clearCart : Function // countCart : Function // totalCart : Function // listCart : Function // saveCart : Function // loadCart : Function return obj; })(); // ***************************************** // Triggers / Events // ***************************************** // Add item jQuery('.add-to-cart').click(function(event) { event.preventDefault(); var name = jQuery(this).data('name'); var price = Number(jQuery(this).data('price')); shoppingCart.addItemToCart(name, price, 1); displayCart(); }); // Clear items jQuery('.clear-cart').click(function() { shoppingCart.clearCart(); displayCart(); }); function displayCart() { var cartArray = shoppingCart.listCart(); var output = ""; for(var i in cartArray) { output += "<tr>" + "<td>" + cartArray[i].name + "</td>" + "<td>(" + cartArray[i].price + ")</td>" + "<td><div class='input-group'><button class='minus-item input-group-addon btn btn-primary' data-name=" + cartArray[i].name + ">-</button>" + "<input type='number' class='item-count form-control' data-name='" + cartArray[i].name + "' value='" + cartArray[i].count + "'>" + "<button class='plus-item btn btn-primary input-group-addon' data-name=" + cartArray[i].name + ">+</button></div></td>" + "<td><button class='delete-item btn btn-danger' data-name=" + cartArray[i].name + ">X</button></td>" + " = " + "<td>" + cartArray[i].total + "</td>" + "</tr>"; } jQuery('.show-cart').html(output); jQuery('.total-cart').html(shoppingCart.totalCart()); jQuery('.total-count').html(shoppingCart.totalCount()); } // Delete item button jQuery('.show-cart').on("click", ".delete-item", function(event) { var name = jQuery(this).data('name') shoppingCart.removeItemFromCartAll(name); displayCart(); }) // -1 jQuery('.show-cart').on("click", ".minus-item", function(event) { var name = jQuery(this).data('name') shoppingCart.removeItemFromCart(name); displayCart(); }) // +1 jQuery('.show-cart').on("click", ".plus-item", function(event) { var name = jQuery(this).data('name') shoppingCart.addItemToCart(name); displayCart(); }) // Item count input jQuery('.show-cart').on("change", ".item-count", function(event) { var name = jQuery(this).data('name'); var count = Number(jQuery(this).val()); shoppingCart.setCountForItem(name, count); displayCart(); }); displayCart();將Cart.js加入 bootScore
- 編輯主題裏的functions.php,找到function bootscore_scripts() ,加入cart.js的使用宣告:(注意//Cart JS這二行)
//Enqueue scripts and styles
function bootscore_scripts() {
(略)
// Bootstrap JS
wp_enqueue_script('bootstrap', get_template_directory_uri() . '/js/lib/bootstrap.bundle.min.js', array(), $modificated_bootstrapJs, true);
// Theme JS
wp_enqueue_script('bootscore-script', get_template_directory_uri() . '/js/theme.js', array('jquery'), $modificated_themeJs, true);
//Cart JS
wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/js/cart.js', array(), null, true );
if (is_singular() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
}
//Enqueue scripts and styles
function bootscore_scripts() {
(略)
// Bootstrap JS
wp_enqueue_script('bootstrap', get_template_directory_uri() . '/js/lib/bootstrap.bundle.min.js', array(), $modificated_bootstrapJs, true);
// Theme JS
wp_enqueue_script('bootscore-script', get_template_directory_uri() . '/js/theme.js', array('jquery'), $modificated_themeJs, true);
//Cart JS
wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/js/cart.js', array(), null, true );
if (is_singular() && comments_open() && get_option('thread_comments')) {
wp_enqueue_script('comment-reply');
}
}
//Enqueue scripts and styles function bootscore_scripts() { (略) // Bootstrap JS wp_enqueue_script('bootstrap', get_template_directory_uri() . '/js/lib/bootstrap.bundle.min.js', array(), $modificated_bootstrapJs, true); // Theme JS wp_enqueue_script('bootscore-script', get_template_directory_uri() . '/js/theme.js', array('jquery'), $modificated_themeJs, true); //Cart JS wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/js/cart.js', array(), null, true ); if (is_singular() && comments_open() && get_option('thread_comments')) { wp_enqueue_script('comment-reply'); } }Theme.JS
-
- 編輯主題裏的functions.php,找到XXXX_theme_scripts_loader() 這個函式(XXXX是當時在下載Theme.es的Bootstrap啟動主題給的主題名稱),我們要加入cart.js的使用宣告:wp_enqueue_script( ‘cartjs’, get_template_directory_uri() . ‘/assets/js/cart.js’, array(), $theme_version, true );
/**
* Loading All CSS Stylesheets and Javascript Files.
*
* @since v1.0
*/
function fgchen_theme_scripts_loader() {
$theme_version = wp_get_theme()->get( 'Version' );
// 1. Styles.
wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), $theme_version, 'all' );
wp_enqueue_style( 'main', get_template_directory_uri() . '/assets/css/main.css', array(), $theme_version, 'all' ); // main.scss: Compiled Framework source + custom styles.
if ( is_rtl() ) {
wp_enqueue_style( 'rtl', get_template_directory_uri() . '/assets/css/rtl.css', array(), $theme_version, 'all' );
}
// 2. Scripts.
wp_enqueue_script( 'mainjs', get_template_directory_uri() . '/assets/js/main.bundle.js', array(), $theme_version, true );
wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/assets/js/cart.js', array(), $theme_version, true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'fgchen_theme_scripts_loader' );
/**
* Loading All CSS Stylesheets and Javascript Files.
*
* @since v1.0
*/
function fgchen_theme_scripts_loader() {
$theme_version = wp_get_theme()->get( 'Version' );
// 1. Styles.
wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), $theme_version, 'all' );
wp_enqueue_style( 'main', get_template_directory_uri() . '/assets/css/main.css', array(), $theme_version, 'all' ); // main.scss: Compiled Framework source + custom styles.
if ( is_rtl() ) {
wp_enqueue_style( 'rtl', get_template_directory_uri() . '/assets/css/rtl.css', array(), $theme_version, 'all' );
}
// 2. Scripts.
wp_enqueue_script( 'mainjs', get_template_directory_uri() . '/assets/js/main.bundle.js', array(), $theme_version, true );
wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/assets/js/cart.js', array(), $theme_version, true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'fgchen_theme_scripts_loader' );
/** * Loading All CSS Stylesheets and Javascript Files. * * @since v1.0 */ function fgchen_theme_scripts_loader() { $theme_version = wp_get_theme()->get( 'Version' ); // 1. Styles. wp_enqueue_style( 'style', get_template_directory_uri() . '/style.css', array(), $theme_version, 'all' ); wp_enqueue_style( 'main', get_template_directory_uri() . '/assets/css/main.css', array(), $theme_version, 'all' ); // main.scss: Compiled Framework source + custom styles. if ( is_rtl() ) { wp_enqueue_style( 'rtl', get_template_directory_uri() . '/assets/css/rtl.css', array(), $theme_version, 'all' ); } // 2. Scripts. wp_enqueue_script( 'mainjs', get_template_directory_uri() . '/assets/js/main.bundle.js', array(), $theme_version, true ); wp_enqueue_script( 'cartjs', get_template_directory_uri() . '/assets/js/cart.js', array(), $theme_version, true ); if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { wp_enqueue_script( 'comment-reply' ); } } add_action( 'wp_enqueue_scripts', 'fgchen_theme_scripts_loader' );
-
- 將「購物車及清空購物車的導覽列」及「購物車對話方塊」加到header.php中(和原版本的不一樣,jQuery的HTML開啟與關閉對話方塊modal在WordPress無法工作,我加入標準的onclick來處理modal的開啟與關閉):
<!-- 購物車數量與清除購物車按鈕 -->
<div class="container">
<div class="row">
<div class="col">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#cart" onclick="jQuery('#cart').modal('show')">Cart (<span class="total-count"></span>)</button>
<button class="clear-cart btn btn-danger">Clear Cart</button>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="cart" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Cart</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="jQuery('#cart').modal('hide')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<table class="show-cart table">
</table>
<div>Total price: $<span class="total-cart"></span></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="jQuery('#cart').modal('hide')">Close</button>
<button type="button" class="btn btn-primary">Order now</button>
</div>
</div>
</div>
</div>
<!-- 購物車數量與清除購物車按鈕 -->
<div class="container">
<div class="row">
<div class="col">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#cart" onclick="jQuery('#cart').modal('show')">Cart (<span class="total-count"></span>)</button>
<button class="clear-cart btn btn-danger">Clear Cart</button>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="cart" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Cart</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="jQuery('#cart').modal('hide')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<table class="show-cart table">
</table>
<div>Total price: $<span class="total-cart"></span></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="jQuery('#cart').modal('hide')">Close</button>
<button type="button" class="btn btn-primary">Order now</button>
</div>
</div>
</div>
</div>
<!-- 購物車數量與清除購物車按鈕 --> <div class="container"> <div class="row"> <div class="col"> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#cart" onclick="jQuery('#cart').modal('show')">Cart (<span class="total-count"></span>)</button> <button class="clear-cart btn btn-danger">Clear Cart</button> </div> </div> </div> <!-- Modal --> <div class="modal fade" id="cart" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Cart</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="jQuery('#cart').modal('hide')"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <table class="show-cart table"> </table> <div>Total price: $<span class="total-cart"></span></div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="jQuery('#cart').modal('hide')">Close</button> <button type="button" class="btn btn-primary">Order now</button> </div> </div> </div> </div>