Hướng Dẫn Xây Dựng Trang Shopping Cart Bằng HTML, CSS Và Javascript

Hôm nay mình sẽ hướng dẫn các bạn tạo một trang shopping cart bằng JS, HTML và CSS. Mình không sử dụng bất kì thư viện và framwork nào để code giao diện cũng như các chức năng của shopping cart. Shopping cart ở đây là mình sẽ tạo một trang bán hàng trong đó mình sẽ hướng dẫn các bạn cách thêm một sản phẩm vào giỏ hàng, tổng tiền của giỏ hàng là bao nhiêu,…

  • Bài viết nhằm mục đích giúp các bạn học hỏi nhiều kiến thức mới.
  • Ôn lại những kiến thức được học như: JS, HTML và CSS.
  • Nắm vững hơn các kiến thức về JS và xây dựng một giao diện và reponsive nó như thế nào.
  • Tự chính tay mình làm được một project trong quá trình mình học đươc, sẽ giúp các bạn học tốt hơn và cảm thấy hứng thú khi học.
  • Bài này rất hay, sẽ tập hợp rất nhiều kiến thức và khá quan trọng mình mong các bạn đọc kĩ càng để có thể hiều một cách đầy đủ nhất nha.

Lên Ý Tưởng Về Giao Diện Trang Shopping Cart

Ý tưởng ở đây của mình là sẽ tạo một trang page gồm 3 phần: Header, Content và Footer. Trong phần header mình sẽ hiển thị logo, menu và giỏ hàng. Trong phần content đây là nới mà chúng ta sẽ hiển thị các sản phẩm cần thêm vào giỏ hàng. Cuối cùng mà không thể thiếu trong quá trình làm giao diện đó là reponsive.Untitled-10

Phân Tích Các Chức Năng Trong Shopping Cart

Các chức năng quan trọng trong shopping cart mà chúng ta cần làm:Thứ nhất là chức năng hiển thị giỏ hàng. Chúng ta hiển thị giỏ hàng bằng cách sử dụng modal, có nghĩa là khi chúng ta click vào giỏ hàng sẽ hiển thị một modal chứa các sản phẩm được thêm vào giỏ hàng.

Thứ hai là chức năng thêm sản phẩm vào giỏ hàng, trong chức năng này nếu chúng ta muốn thêm được sản phẩm vào trong giỏ hàng chúng ta cần lấy được các tham số của sản phẩm. Sau đó thêm vào modal của giỏ hàng.

Thứ ba là chức năng xóa sản phẩm. Chúng ta sẽ bắt sự kiện khi click vào button xóa thì các element cha của nó sẽ xóa. Và còn nhiều chức năng khác nữa.

Bắt Đầu Code Thôi Lào

Code Giao Diện Trang Shopping Cart

Trước tiên trong một website nào thì bước đầu tiên mà chúng ta cần làm đó là code giao diện cho nó. Thì trang shopping cart này cũng không ngoại lệ.

Code HTML

Header Thì trong phần header này thì mình cũng đã nói ở trên gồm những thành phần gì rồi. Nhưng trong đó phần mà quan trọng nhất của header đố là giỏ hàng. Mình sẽ sử dụng modal để hiển thị giỏ hàng. Bây giờ chúng ta sẽ code HTML và CSS cho nó, còn phần hiển thị giỏ hàng mình sẽ nói ở phần Code JS ở trong phần nay.

<!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8″> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> <meta http-equiv=”X-UA-Compatible” content=”ie=edge”> <title>Shopping-cart</title> <link href=”https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css” rel=”stylesheet” integrity=”sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN” crossorigin=”anonymous”> <link rel=”stylesheet” href=”css/style.css” /> <link rel=”stylesheet” href=”css/reponsive.css” /> </head> <body> <!- header -> <header> <nav> <div class=”img-nav”> <img src=”img/logo.png” alt=”” /> </div> <div class=”content-nav”> <ul> <li><a href=”#”>Trang Chủ</a></li> <li><a href=”#”>Sản Phẩm</a></li> <li><a href=”#”>Liên Hệ</a></li> <li><a href=”#”>Giới Thiệu</a></li> </ul> <form> <input type=”text” name=”search” placeholder=”Tìm kiếm sản phẩm…” /> <button type=”submit”><i class=”fa fa-search” aria-hidden=”true”></i></button> </form> </div> <!- The Modal -> <button id=”cart”> <i class=”fa fa-shopping-basket” aria-hidden=”true”></i> Giỏ Hàng </button> <div id=”myModal” class=”modal”> <div class=”modal-content”> <div class=”modal-header”> <h5 class=”modal-title”>Giỏ Hàng</h5> <span class=”close”>&times;</span> </div> <div class=”modal-body”> <div class=”cart-row”> <span class=”cart-item cart-header cart-column”>Sản Phẩm</span> <span class=”cart-price cart-header cart-column”>Giá</span> <span class=”cart-quantity cart-header cart-column”>Số Lượng</span> </div> <div class=”cart-items”> </div> <div class=”cart-total”> <strong class=”cart-total-title”>Tổng Cộng:</strong> <span class=”cart-total-price”>0VNĐ</span> </div> </div> <div class=”modal-footer”> <button type=”button” class=”btn btn-secondary close-footer”>Đóng</button> <button type=”button” class=”btn btn-primary order”>Thanh Toán</button> </div> </div> </div> </nav> </header>

Content Trong phần chúng ta sẽ hiển thị các sản phẩm cần thêm vào giỏ hàng. Mình sẽ sử dụng float để xây dựng các sản phẩm. Mình thì đam mê chế cháo nên các sản phẩm của mình là các đồ linh kiện điện tử.

Mỗi cái sản phẩm là một component chúng ta chỉ cần code một cái conponent sau đó copy ra nhiều các conponent khác rồi sau đó thay đổi ảnh và tiêu đề thôi.

Và các bạn sẽ để ý thấy là tại sao trong giá tiền mình không có ghi các dấu”.” để tách các số tiền ra như 85.000đ mà lại ghi 85000đ. Mình sẽ có phần giải thích ở dưới phần cập nhật giỏ hàng.

<!- content -> <section class=”wrapper”> <div class=”products”> <ul> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/sualai.jpg?v=1573720306000″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Mũi Hàn 500</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>25000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/sp1-57698689-e2c0-429a-bf4f-3bd0f39230d8.jpg?v=1575337954000″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Trạm Hàn Hakko 942 75W 200-480*C 220VAC Cực Nóng</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>1299000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/sp1-a45a32a1-38d4-4a8a-9c37-e936013858b2.jpg?v=1575877003000″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Máy Bơm Chìm Hộ Gia Đình QDX 1500W 220VAC 40L/1min H=8m</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>1599000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product no-margin”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/module-diy-sac-khong-day-5.jpg?v=1570011041000″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Module DIY Sạc Không Dây Qi IOS/Androi – Bộ phát V2</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>89000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/bo-dieu-chinh-dien-ap-sdty-200p.jpg?v=1560155769920″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Bộ Điều Chỉnh Điện Áp CHLVFU SDTY-200P 20KW 200A (BH 06 Tháng) </h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>2199000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/isd1760-thu-am-thanh-phat-am-thanh-2.jpg?v=1568951032960″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Module ISD1760 Thu Âm Thanh – Phát Âm Thanh 75s</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>115000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/new-arrival-b-plus-64-bit-quad-2.jpg?v=1568277329707″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Raspberry Pi 3 E14 Model B Plus B+ 2.4G/5G Bluetooth</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>1295000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> <li class=”main-product no-margin”> <div class=”img-product”> <img class=”img-prd” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/module-iot-esp8266-esp-12e-ch340-3.jpg?v=1565950165000″ alt=””> </div> <div class=”content-product”> <h3 class=”content-product-h3″>Module IOT ESP8266 ESP-12E CH340 V3</h3> <div class=”content-product-deltals”> <div class=”price”> <span class=”money”>85000đ</span> </div> <button type=”button” class=”btn btn-cart”>Thêm Vào Giỏ</button> </div> </div> </li> </ul> </div> </section>

Footer Trong thằng footer này mình cũng làm đơn giản thôi. Một bên thì mình sẽ hiển thị logo bên còn lại mình sẽ hiển thị các icon social.

<!- footer -> <footer> <div class=”footer-item”> <div class=”img-footer”> <img src=”img/logo.png” alt=”” /> </div> <div class=”social-footer”> <li><a target=”_blank” href=”https://www.facebook.com/thanhlongdev”> <i class=”fa fa-facebook-square” aria-hidden=”true”></i> </a></li> <li><a target=”_blank” href=”https://github.com/long1211″> <i class=”fa fa-github-square” aria-hidden=”true”></i> </a></li> </div> </div> </footer>

Đây là giao diện khi chúng ta chưa CSScart Nhìn nó tù thật đúng không mọi người. Bây giờ chúng ta CSS cho nó để trang shopping cart trở nên dễ nhìn hơn.

Code CSS

Header Trong phần header này chúng ta cho sử dụng flex để chia layout và chỉnh sửa theo mình mong muốn Còn phần modal khi hiển thị giỏ hàng chúng ta sẽ canh chúng ra giữa và ẩn modal đó đi.

* { padding: 0; margin: 0; box-sizing: border-box; font-family: ‘Muli’, -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif, ‘Apple Color Emoji’, ‘Segoe UI Emoji’, ‘Segoe UI Symbol’, ‘Noto Color Emoji’; } li { list-style: none; } /* header */ nav { padding: 15px; width: 100%; display: flex; background: #f1df11; } nav .content-nav { display: flex; line-height: 2rem; flex-direction: row; justify-content: flex-end; width: 60%; } nav .content-nav ul { display: flex; } nav .content-nav ul li a { text-decoration: none; color: #43433e; text-transform: uppercase; padding: 0 15px; font-weight: 800; } nav .content-nav ul li a:hover { color: #fff; } .content-nav form { position: relative; } .content-nav form input { border: none; background: #fff; padding: 7px; outline: none; border-radius: 12px; } .content-nav form button { padding: 5px; border-radius: 12px; position: absolute; right: 0; top: 2px; border: none; outline: none; background: #fff; } /* modal */ .modal { display: none; position: fixed; z-index: 1; padding-top: 100px; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgb(0, 0, 0); background-color: rgba(0, 0, 0, 0.4); } .modal-content { margin: 0 auto; width: 50%; position: relative; display: flex; flex-direction: column; background-color: #fff; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, .2); border-radius: .3rem; outline: 0; } .modal-body { padding: 1rem; } .modal-footer { display: flex; border-top: 1px solid #aaaaaa; padding: 1rem; flex-direction: row; justify-content: flex-end; border-top: 1px solid #aaaaaa; padding: 1rem; } .modal-footer>:not(:first-child) { margin-left: .25rem; } .btn { cursor: pointer; outline: none; font-weight: 400; line-height: 1.25; text-align: center; white-space: nowrap; vertical-align: middle; border: 1px solid transparent; padding: .5rem 1rem; font-size: 1rem; border-radius: .25rem; transition: all .2s ease-in-out; } .btn-secondary { color: #292b2c; background-color: #fff; border-color: #ccc; } .btn-primary { color: #fff; background-color: #0275d8; border-color: #0275d8; } .modal-header { align-items: center; display: flex; justify-content: space-between; border-bottom: 1px solid #aaaaaa; padding: 1rem; } h5.modal-title { font-size: 1.5rem; } .close { color: #aaaaaa; font-size: 28px; font-weight: bold; display: flex; flex-direction: row; justify-content: flex-end; } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; } #cart { font-size: 15px; color: #fff; background: #c7b200; border: 1px solid transparent; border-radius: 10px; outline: none; margin-left: 1rem; padding: 12px; cursor: pointer; } #cart:hover { border-color: #fff; }

Content Chúng ta sử dụng width và float:left để chia layout cho các sản thẩm trong content.

/* wrapper */ .wrapper { padding: 2rem; } .products ul { display: inline-block; } .products ul .main-product { margin-bottom: 2rem; margin-right: 1rem; display: block; float: left; width: 24%; } .products ul .no-margin { margin-right: 0; } .products ul .img-product img { width: 100%; } .content-product .content-product-h3 { padding: .5rem 0; overflow: hidden; color: #222; font-weight: 500; font-size: 16px; max-height: 50px; min-height: 50px; text-align: center; line-height: 19px; margin: 0 0 5px; } .content-product .content-product-deltals { display: flex; justify-content: center; padding-top: 1rem; } .main-product .content-product .content-product-deltals .price { color: #c7b200; font-weight: 700; margin-right: 1rem; vertical-align: middle; font-size: 20px; } .content-product .content-product-deltals .price .money { vertical-align: middle; } .content-product .content-product-deltals .btn-cart { background: #f1df11; border-radius: 5px; color: #fff; font-weight: 500; } .content-product .content-product-deltals .btn-cart:hover { background: #c7b200; } /* footer */ .footer-item { padding: .5rem 2rem; background: #f1df11; display: flex; } .footer-item .img-footer { align-items: center; display: flex; } .footer-item .img-footer img { width: 100%; } .footer-item .social-footer { display: flex; align-items: center; width: 100%; justify-content: flex-end; } .footer-item .social-footer li a { color: #000000; font-size: 2rem; } .footer-item .social-footer li:last-child { margin-left: .5rem; }

Footer Trong footer này mình sử dụng flex để chia layout cho footer

/* footer */ .footer-item { padding: .5rem 2rem; background: #f1df11; display: flex; } .footer-item .img-footer { align-items: center; display: flex; } .footer-item .img-footer img { width: 100%; } .footer-item .social-footer { display: flex; align-items: center; width: 100%; justify-content: flex-end; } .footer-item .social-footer li a { color: #000000; font-size: 2rem; } .footer-item .social-footer li:last-child { margin-left: .5rem; }

Và đây là giao diện khi chúng ta đã CSS cho nó:page-2Code JS Trong file main.js bây giờ các bạn code cho mình một đoạn code để hiển thị giỏ hàng(modal). Để hiển thị giỏ hàng thì cũng đơn giản thôi. Các bạn gọi HTML Dom ra thôi Mình sẽ giải thích cách hoạt động của nó cho mấy bạn dễ hiểu nha Đó là khi chúng ta click vào giỏ hàng(button) thì nó sẽ xuất hiện modal. Khi chúng ta click vào nút ‘Đóng’, dấu ‘x’ hay là khi click bên ngoài modal thì nó sẽ ẩn modal đó đi.

// Modal var modal = document.getElementById(“myModal”); var btn = document.getElementById(“cart”); var close = document.getElementsByClassName(“close”)[0]; // tại sao lại có [0] như thế này bởi vì mỗi close là một html colection nên khi mình muốn lấy giá trị html thì phải thêm [0]. Nếu mình có 2 cái component cùng class thì khi [0] nó sẽ hiển thị component 1 còn [1] thì nó sẽ hiển thị component 2. var close_footer = document.getElementsByClassName(“close-footer”)[0]; var order = document.getElementsByClassName(“order”)[0]; btn.onclick = function () { modal.style.display = “block”; } close.onclick = function () { modal.style.display = “none”; } close_footer.onclick = function () { modal.style.display = “none”; } order.onclick = function () { alert(“Cảm ơn bạn đã thanh toán đơn hàng”) } window.onclick = function (event) { if (event.target == modal) { modal.style.display = “none”; } }

Và đây là kết quả khi chúng ta đã code js để hiển thị giỏ hàng.3m713a

Reponsive Giao Diện Trang Shopping Cart

Giao diện mobile

Khi chúng ta chuyển sang chế độ mobile thì giao diện mobile bị vỡ và vỡ như thế nào thì chúng ta cùng xem nó bị vỡ như nào nha:Untitled-11 Vậy bây giờ chúng ta sẽ làm như thế nào để các sản phẩm không bị vỡ nha. Mỗi sản phẩm là 1 conponent bây giờ chúng ta chỉ cần width:100% cho nó là được. Trong phần header các bạn ẩn các menu trong .content-nav đi nha. Mình sẽ viết một cái .nav-mobile trong đó chứa toàn bộ các menu mà nó được hiển thị trên desktop.Code HTML

<header> <nav> <!- bắt đầu nav-mobile -> <div class=”nav-mobile”> <div class=”icon-mobile” id=”btnmenu”> <i class=”fa fa-bars” aria-hidden=”true”></i> </div> <div class=”item_menu” id=”menutop”> <form> <input type=”text” name=”search” placeholder=”Tìm kiếm sản phẩm…” /> <button type=”submit”><i class=”fa fa-search” aria-hidden=”true”></i></button> </form> <ul> <li><a href=”#”>Trang Chủ</a></li> <li><a href=”#”>Sản Phẩm</a></li> <li><a href=”#”>Liên Hệ</a></li> <li><a href=”#”>Giới Thiệu</a></li> </ul> </div> </div> <!- kết thúc nav-mobile -> ……. ……. ……. ……. </nav> </header>

Code CSS Trong phần này thì chúng ta sẽ CSS cho nó thằng nav-mobile và các item bên trong nó như: form, nav-content,..Và ẩn các .item_menu và .nav-mobile đó đi là được.

/* nav mobile */ .nav-mobile { display: none; } .nav-mobile .icon-mobile { padding: .5rem; font-size: 35px; flex-direction: column; justify-content: center; align-items: center; display: flex; outline: none; } .nav-mobile .item_menu { background: #f1df11; position: absolute; top: 100%; width: 100%; display: none; padding-bottom: 1rem; } .item_menu ul li a { color: #43433e; display: block; padding: .5rem 1rem; text-decoration: none; text-transform: uppercase; font-weight: 800; letter-spacing: 0.05rem; } .item_menu ul li a:hover { color: #fff; } .item_menu form { margin: 0 1rem; position: relative; } .item_menu form input { width: 100%; border: none; background: #fff; padding: 7px; outline: none; border-radius: 12px; } .item_menu form button { padding: 5px; border-radius: 12px; position: absolute; right: 0; top: 2px; border: none; outline: none; background: #fff; }

Reponsive Trong file reponsive.css các bạn ẩn thằng .content-nav đó đi là được nha. Còn phần modal các bạn width lớn hơn một tí để nó có thể hiển thị rõ nhất.

/*mobile*/ @media only screen and (min-width:240px) and (max-width:480px) { /* nav */ nav .content-nav { display: none; } nav { position: fixed !important; top: 0px; left: 0; width: 100%; display: flex; padding: 0; } .nav-mobile { display: flex; } .img-nav { align-items: center; display: flex; flex-direction: row; justify-content: center; } .img-nav img { padding-top: 0.5rem; vertical-align: middle; width: 90%; } .content-nav, .item_menu form button { right: 10px; } /* wrapper */ .wrapper { padding: 1rem; } .products { margin-top: 3rem; } .products ul .main-product { width: 100%; } /* modal */ .modal-content { width: 95%; } .cart-item-title { font-size: 0.6em; } .cart-column { margin-right: 0.5em; } .cart-price { margin-right: 1rem; } #cart { margin: .5rem; padding: 3px; } }

Code JS Trong file main.js các bạn code cho thằng nav-mobile này là khi click vài icon-mobile thì nó sẽ display:block, còn nếu nó đã hiển thị rồi khi click lại thì display:none;

// menu mobile var btn_menu = document.getElementById(“btnmenu”); btn_menu.addEventListener(“click”, function () { var item_menu = document.getElementById(“menutop”); if (item_menu.style.display === “block”) { item_menu.style.display = “none”; } else { item_menu.style.display = “block”; } })

Và đây là giao diện mobile khi chúng ta đã reponsive cho nó:Untitled-12

Giao Diện Tablet

Chúng ta cùng xem thử giao diện trang shopping cart nó hiển thị như thế nào nha.Untitled-13 Thì các bạn sẽ thấy giao diện hơi bị vỡ một chút, bây giờ các bạn cần tăng width các sản phẩm lên một chút thì sẽ thấy ok. Còn phần header các bạn chỉ cần chỉnh sửa lại font-size của các menu trong .content-nav và width:100% cho .content-nav là được.

/*tablet*/ @media (min-width:480px) and (max-width:768px) { .wrapper { padding: 1.5rem; } .img-nav img { vertical-align: middle; width: 100%; } nav .content-nav ul li a { font-size: 12px; padding: 0px 8px; } nav .content-nav { width: 100%; } #cart { font-size: 12px; margin-left: 0.3rem; padding: 0; } .products ul .main-product { width: 31%; } .main-product .content-product .content-product-deltals .price { font-size: 18px; } .products ul .no-margin { margin-right: 1rem; } .cart-item-title { font-size: 0.5em; } .cart-column { margin-right: 0.5em; } .cart-price { margin-right: 1rem; } }

Và đây là giao diện tablet khi đã được reponsiveUntitled-14Vậy là chúng ta đã là xong giao diện cho trang shopping cart rồi nha.Tiếp đến là phần quan trọng nhất trong shopping cart. Các bạn cùng theo dõi tiếp nha.

Xây Dựng Các Chức Năng Trang Shopping Cart

Xóa Sản Phẩm Trong Giỏ Hàng

Các bạn sẽ đặt một câu hỏi lại tại sao chưa thêm sản phẩm vào giỏ hàng mà lại xóa rồi thì các bạn cứ bình tĩnh, từ từ để mình giải thích.Tại sao mình lại làm chức năng xóa sản phẩm trước và làm như thế nào?Mình làm chức năng trước vì khi mình làm chức năng này thì trước tiên mình phải mình phải tạo một sản phẩm trong giỏ hàng khi chia được thêm. Nhằm mục đích là giúp chúng ta tạo được bố cục, kết cấu của giỏ hàng. Sau khi làm chức năng xóa xong, tiếp đến là chức năng tính tổng tiền trong giỏ hàng.

Sau khi chúng ta làm xong các bước trên thì đến bước thêm sản phẩm vào giỏ hàng cũng dựa theo các bố cục,…ở trên. Sau đó các bạn sẽ xóa các các sản phẩm mà mình tự tạo trong giỏ hàng đi là được. Không linh tinh liêng thiêng nữa.

Chúng ta bắt tay vào làm thôi nào:Code HTML Trong file index.html phần .modal-body các bạn thêm cho mình đoạn code HTMl này vào bên trong .cart-items này giúp mình nha.

// modal <div class=”modal-body”> <div class=”cart-row”> <span class=”cart-item cart-header cart-column”>Sản Phẩm</span> <span class=”cart-price cart-header cart-column”>Giá</span> <span class=”cart-quantity cart-header cart-column”>Số Lượng</span> </div> <div class=”cart-items”> <div class=”cart-row”> <div class=”cart-item cart-column”> <img class=”cart-item-image” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/sualai.jpg?v=1573720306000″ width=”100″ height=”100″> <span class=”cart-item-title”>Mũi Hàn 500</span> </div> <span class=”cart-price cart-column”>25000đ</span> <div class=”cart-quantity cart-column”> <input class=”cart-quantity-input” type=”number” value=”1″> <button class=”btn btn-danger” type=”button”>Xóa</button> </div> </div> <div class=”cart-row”> <div class=”cart-item cart-column”> <img class=”cart-item-image” src=”https://bizweb.dktcdn.net/thumb/large/100/228/168/products/sp1-a45a32a1-38d4-4a8a-9c37-e936013858b2.jpg?v=1575877003000″ width=”100″ height=”100″> <span class=”cart-item-title”>Máy Bơm Chìm Hộ Gia Đình QDX 1500W 220VAC 40L/1min H=8m</span> </div> <span class=”cart-price cart-column”>1599000đ</span> <div class=”cart-quantity cart-column”> <input class=”cart-quantity-input” type=”number” value=”2″> <button class=”btn btn-danger” type=”button”>Xóa</button> </div> </div> <div class=”cart-total”> <strong class=”cart-total-title”>Tổng Cộng:</strong> <span class=”cart-total-price”>3223000VNĐ</span> </div> </div>

Code CSS Trong file style.css các bạn sử dụng flex và width để chia layout cho các .cart-item nha.

/* cart */ .cart-header { font-weight: bold; font-size: 1.25em; color: #333; } .cart-column { display: flex; align-items: center; border-bottom: 1px solid black; margin-right: 1.5em; padding-bottom: 10px; margin-top: 10px; } .cart-row { display: flex; } .cart-item { width: 45%; } .cart-price { width: 20%; font-size: 1.2em; color: #333; } .cart-quantity { width: 35%; } .cart-item-title { color: #333; margin-left: .5em; font-size: 1.2em; } .cart-item-image { width: 75px; height: auto; border-radius: 10px; } .btn-danger { color: white; background-color: #EB5757; border: none; border-radius: .3em; font-weight: bold; } .btn-danger:hover { background-color: #CC4C4C; } .cart-quantity-input { height: 34px; width: 50px; border-radius: 5px; border: 1px solid #56CCF2; background-color: #eee; color: #333; padding: 0; text-align: center; font-size: 1.2em; margin-right: 25px; } .cart-row:last-child { border-bottom: 1px solid black; } .cart-row:last-child .cart-column { border: none; } .cart-total { text-align: end; margin-top: 10px; margin-right: 10px; } .cart-total-title { font-weight: bold; font-size: 1.5em; color: black; margin-right: 20px; } .cart-total-price { color: #333; font-size: 1.1em; }

Và đây là kết quả khi chúng ta thêm các sản phẩm vào trong giỏ hàng:Untitled-15Code JS Trong file main.js chúng ta sẽ gọi HTML Dom của button “xóa” trong sản phẩm. Tại sao mình lại dùng vòng lặp mà lại không sử dụng [0]. Bởi vì khi sử dụng [0] thì nó chỉ lấy giá trị button đầu tiên mà thôi. Ví dụ như mình có 4 sản phẩm thì có 4 button “xóa” nếu như mình sử dụng [0] thì chỉ có thể xóa được sản phẩm đầu tiên vì thế nên mình sẽ sử dụng vòng lặp. Nó sẽ lặp qua tất cả các sản phẩm mà bạn thêm vào giỏ hàng và xem thử có bao nhiêu button “xóa”. Sau khi biết bao nhiêu button “xóa” sau đó add sự kiện click. Khi click vào button xóa thì nó sẽ xóa phần cha bọc nó. Ở đây có hai parentElement thì nó sẽ xóa phần tử cha bọc ngoài cùng (xóa sản phẩm ấy).

// xóa cart var remove_cart = document.getElementsByClassName(“btn-danger”); for (var i = 0; i < remove_cart.length; i++) { var button = remove_cart[i] button.addEventListener(“click”, function () { var button_remove = event.target button_remove.parentElement.parentElement.remove() }) }

Và đây là kết quả chúng ta làm xong chức năng xóa sản phẩm trong giỏ hàng.cart

Cập Nhật Giỏ Hàng

Sau khi mình làm xong chức năng xóa sản phẩm trong giỏ hàng, bây giờ sẽ đến phần cập nhật giỏ hàng, cập nhật tổng tiền trong giỏ hàng,..Code JS Trong file main.js các bạn cũng gọi HTML DOM như ở trên. Mình sẽ giải thích cơ chế hoạt động của updatecart() này cho các bạn dễ hiểu nha. Thì nó sẽ gọi .cart_items trong .cart_items có nhiều .cart_row trong mỗi cart_row chứa các thông tin của sản phẩm như hình ảnh, tiêu đề, giá tiền của sản phẩm. Bởi vì .cart-row này trong .cart-items nên không thể gọi document được mà phải gọi dựa trên DOM của .cart_items.

Sau khi gọi được cart_rows chúng ta sẽ chạy vòng lặp để biết có bao nhiêu .cart_row. Tiếp đến chúng ta sẽ gọi HTML DOM của .cart-price và .cart-quantity-input, bởi vì chỉ có một giá tiền và số lượng sản phẩm nên chúng ta sử dụng [0] Tiếp đến chúng ta sẽ lấy giá trị của giá tiền và số lượng của sản phẩm.

Cuối cùng là tính tổng tiền, ở đây mình sẽ nói rõ ra tí. Total sẽ gán bằng 0 đúng không nào. Sau khi chúng ta tính tổng tiền của sản phẩm đầu tiên sẽ được gán vào total. Thì bây giờ total được gán bằng tổng số tiền của sản phẩm đầu tiên, nếu bạn có sản phẩm thứ hai trong giỏ hàng thì total = total của sản phẩm đầu tiên + tổng tiền của sản phẩm thứ hai và gán vào total tổng, cứ thế nhiều sản phẩm hơn cũng làm như vậy đó.

// update cart function updatecart() { var cart_item = document.getElementsByClassName(“cart-items”)[0]; var cart_rows = cart_item.getElementsByClassName(“cart-row”); var total = 0; for (var i = 0; i < cart_rows.length; i++) { var cart_row = cart_rows[i] var price_item = cart_row.getElementsByClassName(“cart-price “)[0] var quantity_item = cart_row.getElementsByClassName(“cart-quantity-input”)[0] var price = parseFloat(price_item.innerText)// chuyển một chuổi string sang number để tính tổng tiền. var quantity = quantity_item.value // lấy giá trị trong thẻ input total = total + (price * quantity) } document.getElementsByClassName(“cart-total-price”)[0].innerText = total + ‘VNĐ’ // Thay đổi text = total trong .cart-total-price. Chỉ có một .cart-total-price nên mình sử dụng [0]. }

Sau đó các bạn gọi hàm updatecart() trong phần xóa sản phẩm trong giỏ hàng nhá. Tại đây thì mình cũng sẽ giải thích một lý do vì sao số tiền trong sản phẩm mình không ngăn cách bằng dấu ‘.’ thì khi sử dụng parseFloat() nó sẽ lấy những số ban đầu và bỏ những số 0 sau dấu ‘.’ vì thế đó là lý do mà mình không dùng dấu ‘.’Và đây là kết quả khi chúng ta thêm phần cập nhật sản phẩm trong giỏ hàng: Các bạn thử xóa sản phẩm để xem total nó có thay đổi không nha.cart-1

Thay Đổi Số Lượng Sản Phẩm Trong Giỏ Hàng

Sau khi chúng ta xong phần cập nhật giỏ hàng. Tiếp đến chúng ta sẽ làm phần thay đổi số lượng sản phẩm, chúng ta bắt sự kiện khi mình thay đổi(change) số lượng thì gọi function updatecart(). Nhưng có một cái lỗi nhỏ ở đây là khi mình cho type=’number’ thì số có thể dưới 0, mà số lượng sản phẩm thì không bao giờ có giá trị âm hoặc bằng 0 cả nên mình sẽ viết code là nếu giá trị mà <= 0 thì sẽ set giá trị cho thẻ input = 1.

// thay đổi số lượng sản phẩm var quantity_input = document.getElementsByClassName(“cart-quantity-input”); for (var i = 0; i < quantity_input.length; i++) { var input = quantity_input[i]; input.addEventListener(“change”, function (event) { var input = event.target if (isNaN(input.value) || input.value <= 0) { input.value = 1; } updatecart() }) }

Và đây là kết quả khi chúng ta thay đổi số lượng sản phẩm trong giỏ hàng:3mh1jk

Thêm Sản Phẩm Vào Giỏ Hàng

Đây là mục khá là quan trọng cũng như là mục cuối cùng trong phần này. Thì phần này mình làm cũng dựa những mục ở trên mà mình đẫ làm thôi. Chúng ta sẽ bắt sự kiện khi click vào button ‘Thêm Vào Giỏ’. Khi click vào sẽ lấy đường dẫn ảnh, tiêu đề và giá của sản phẩm. Khi lấy được các giá trị của một sản phẩm thì bước tiếp theo là chúng ta sẽ là đưa nó lên giỏ hàng. Vậy làm sao để được đưa lên được giỏ hàng. Muốn đưa lên được giỏ hàng thì chúng ta phải tạo cho nó một bộ khung. Trước tiên các bạn tạo cho mình một thẻ div và addClass cart-row tiếp theo tạo cho nó một bộ khung html giống bộ khung mà mình tạo để xây dựng chức năng xóa giỏ hàng để có thể thêm sản phẩm vào giỏ hàng, sau đó gán cái khung html vào cart-row và chèn vào trong class cart-items được gọi. Tiếp đến các bạn vào file index.html xóa hai sản phẩm mà mình đã thêm vào để làm chức năng xóa sản phẩm trong giỏ hàng và nhớ sửa tổng tiền thành 0VNĐ nha. Các bạn xóa nhớ chừa lại class cart-items.

// Thêm vào giỏ var add_cart = document.getElementsByClassName(“btn-cart”); for (var i = 0; i < add_cart.length; i++) { var add = add_cart[i]; add.addEventListener(“click”, function (event) { var button = event.target; var product = button.parentElement.parentElement; var img = product.parentElement.getElementsByClassName(“img-prd”)[0].src var title = product.getElementsByClassName(“content-product-h3”)[0].innerText var price = product.getElementsByClassName(“price”)[0].innerText addItemToCart(title, price, img) // Khi thêm sản phẩm vào giỏ hàng thì sẽ hiển thị modal modal.style.display = “block”; updatecart() }) } function addItemToCart(title, price, img) { var cartRow = document.createElement(‘div’) cartRow.classList.add(‘cart-row’) var cartItems = document.getElementsByClassName(‘cart-items’)[0] var cart_title = cartItems.getElementsByClassName(‘cart-item-title’) Nếu title của sản phẩm bằng với title mà bạn thêm vao giỏ hàng thì sẽ thông cho user. for (var i = 0; i < cart_title.length; i++) { if (cart_title[i].innerText == title) { alert(‘Sản Phẩm Đã Có Trong Giỏ Hàng’) return } } var cartRowContents = ` <div class=”cart-item cart-column”> <img class=”cart-item-image” src=”${img}” width=”100″ height=”100″> <span class=”cart-item-title”>${title}</span> </div> <span class=”cart-price cart-column”>${price}</span> <div class=”cart-quantity cart-column”> <input class=”cart-quantity-input” type=”number” value=”1″> <button class=”btn btn-danger” type=”button”>Xóa</button> </div>` cartRow.innerHTML = cartRowContents cartItems.append(cartRow) cartRow.getElementsByClassName(‘btn-danger’)[0].addEventListener(‘click’, function () { var button_remove = event.target button_remove.parentElement.parentElement.remove() updatecart() }) cartRow.getElementsByClassName(‘cart-quantity-input’)[0].addEventListener(‘change’, function (event) { var input = event.target if (isNaN(input.value) || input.value <= 0) { input.value = 1; } updatecart() }) }

Và đây là kết quả khi chúng ta đã thêm sản phẩm vào giỏ hàng.cart-2 Vậy là xong rồi nha, bài này mình viết khá dài mong mọi người thông cảm. Các bạn có thể tham khảo trang shopping cart mà mình đã deploy lên firebase tại đây

Vậy Là Xong bài Hướng dẫn xây dựng trang shopping cart bằng html, css và javascript rồi nhé. Mình mong muốn sau bài topic này các bạn có thể nắm vững thêm kiến thức về JS cũng như tự mình design một giao diện thông qua các project thực tế.

Nếu các bạn cảm thấy bài viết của mình hay thì các bạn có thể ủng hộ mình để mình có thêm động lực để ra những bài topic hay và chất lượng hơn ủng hộ mình tại đây nha.

Chúc Các Bạn Thành Công!!