<div class="wrap">
<div class="main rounded">
<h2 class="text-center mb-4">蔬菜比價網</h2>
<div class="button-group d-flex justify-content-center mb-4">
<!-- 埋藏 data-type 的 DOM -->
<button type="button" class="allBtn btn btn-type border-dark border-2">全部</button>
<button data-type="N04" type="button" class="vegetablesBtn btn btn-type border-dark border-2">蔬果</button>
<button data-type="N05" type="button" class="fruitsBtn btn btn-type border-dark border-2">水果</button>
<button data-type="N06" type="button" class="flowersBtn btn btn-type border-dark border-2">花卉</button>
</div>
<div class="search-group d-flex flex-md-row flex-column align-items-center">
<div class="crop-input d-flex mb-2 ">
<label class="rounded-start text-white" for="crop">作物名稱</label>
<input class="rounded-end" type="search" placeholder="請輸入作物名稱" id="crop" name="crop">
</div>
<button type="button" class="search text-white btn mb-2">搜尋</button>
</div>
<select id="js-select" class="sort-select border-secondary rounded mb-3 p-2 pe-4">
<option>排序篩選</option>
<option>依上價排序</option>
<option>依中價排序</option>
<option>依下價排序</option>
<option>依平均價排序</option>
<option>依交易量排序</option>
</select>
<table class="market table me-4">
<thead class="js-sort-advanced">
<tr>
<th width="16.6%">作物名稱</th>
<th width="16.6%">上價
<span>
<i data-price="上價" data-sort="up" class="fas fa-caret-up"></i>
<i data-price="上價" data-sort="down" class="fas fa-caret-down"></i>
</span>
</th>
<th width="16.6%">中價
<span>
<i data-price="中價" data-sort="up" class="fas fa-caret-up"></i>
<i data-price="中價" data-sort="down" class="fas fa-caret-down"></i>
</span>
</th>
<th width="16.6%">下價
<span>
<i data-price="下價" data-sort="up" class="fas fa-caret-up"></i>
<i data-price="下價" data-sort="down" class="fas fa-caret-down"></i>
</span>
</th>
<th width="16.6%">平均價
<span>
<i data-price="平均價" data-sort="up" class="fas fa-caret-up"></i>
<i data-price="平均價" data-sort="down" class="fas fa-caret-down"></i>
</span>
</th>
<th width="16.6%">交易量
<span>
<i data-price="交易量" data-sort="up" class="fas fa-caret-up"></i>
<i data-price="交易量" data-sort="down" class="fas fa-caret-down"></i>
</span>
</th>
</tr>
</thead>
<tbody class="showList">
<tr>
<td colspan="6" class="text-center p-3">請輸入並搜尋想比價的作物名稱^_^</td>
</tr>
</tbody>
</table>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
*,
*::before,
*::after {
box-sizing: border-box;
}
img {
max-width: 100%;
height: auto;
}
body {
background: url(https://hexschool.github.io/js-filter/assets/bg.jpg);
background-size: cover;
height: 100vh;
font-family: "NotoSansCJKtc-Bold";
color: #2a2a2a;
letter-spacing: 1px;
white-space: nowrap;
}
.wrap {
max-width: 1140px;
margin: 1rem auto;
}
.main {
background: #fff;
border: 5px solid #fff8d45a;
padding: 2.5rem;
}
@media (max-width: 767px) {
.main {
padding: 0.75rem;
}
}
.btn-type {
padding: 0.5rem 2.5rem;
color: #2a2a2a;
letter-spacing: 1px;
margin: 0 0.625rem 1.25rem 0;
}
.btn-type:hover,
.btn-type:active {
background: #f8d45a;
}
@media (max-width: 767px) {
.btn-type {
padding: 0.5rem 2.25rem;
margin: 0 0.375rem 1rem 0;
}
}
.active{
background: #f8d45a;
}
.seach-group {
white-space: nowrap;
display: flex;
align-items: center;
margin-bottom: 2.5rem;
width: 100%;
}
.crop-input {
width: 60%;
margin: auto;
}
.crop-input label {
background: #899e39;
display: flex;
align-items: center;
padding: 0.5rem 1rem;
width: 27.5%;
}
.crop-input input {
width: 80%;
border: 2px #899e39 solid;
padding: 0.375rem;
margin-left: -0.3125rem;
margin-right: 1rem;
}
.search {
width: 40%;
background: #899e39;
padding: 0.5rem 3.375rem;
}
@media (max-width: 767px) {
.seach-group {
margin-bottom: 1.5rem;
}
.crop-input {
width: 100%;
}
.search {
width: 100%;
}
}
.market thead {
background: #f4f1ea;
border-top: 2px solid #2a2a2a;
border-bottom: 2px solid #2a2a2a;
}
.market tbody {
border-bottom: 2px solid #d9d9d9;
}
@media (max-width: 480px) {
table {
display: block;
overflow-x: auto;
white-space: nowrap;
}
}
.sort-select {
appearance: none;
appearance: none;
appearance: none;
background: url('data:image/svg+xml;utf8,<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sort-down" class="svg-inline--fa fa-sort-down fa-w-2" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="10 0 320 900"><path fill="currentColor" d="M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z"></path></svg>')
no-repeat;
background-position: 105px 5px;
}
.sort-content {
margin-bottom: 1.25rem;
}
// JSON 檔案網址
const url = "https://shannon945.github.io/farm_produce/data.json";
const productsList = document.querySelector(".showList");
let data = [];
/** 步驟一 取得資料**/
function getData(){
axios.get(url)
.then(function(response){
// 檢查:
console.log(response.data);
// 將取得資料帶入空陣列 data 中
data = response.data;
// 執行渲染 (請留意非同步)
renderData(data);
})
}
getData();
/** 步驟二 渲染**/
function renderData(arr) {
// 宣告空字串,可存入資料
let str = "";
//請透過 data 陣列跑 forEach ,並至少帶入第一個參數
arr.forEach(function(item){
str +=`
<tr>
<td>${item.作物名稱}</td>
<td>${item.上價}</td>
<td>${item.中價}</td>
<td>${item.下價}</td>
<td>${item.平均價}</td>
<td>${item.交易量}</td>
</tr>`
})
// 檢查:console.log(str);
productsList.innerHTML = str;
}
/** 步驟三 點擊到該按鈕時,按鈕能維持變色!**/
const btnGroup = document.querySelector('.button-group');
// 監聽蔬果、水果、花卉按鈕
btnGroup.addEventListener('click', (e)=>{
// 重新渲染的陣列內容
let update = [];
//點擊後,先全部清除 active,然後再添加 active
const tabs = document.querySelectorAll(".button-group button");
// 因為監聽的 btnGroup 範圍有包 div,所以要確保只點到 button 才會換色
if(e.target.nodeName === "BUTTON"){
tabs.forEach((item)=>{
return item.classList.remove('active')
});
// filter 篩選蔬果、水果、花卉
// 使用 .classList.contains 找到其中一個 class
// 或使用 dataset
if(e.target.classList.contains('vegetablesBtn')){
// 蔬果 "種類代碼": type="N04"
update = data.filter((item)=> item.種類代碼 === 'N04')
}else if(e.target.dataset.type === 'N05'){
// 水果 "種類代碼": type="N05"
update = data.filter((item)=> item.種類代碼 === 'N05')
}else if(e.target.dataset.type === 'N06'){
// 花卉 "種類代碼": type="N05"
update = data.filter((item)=> item.種類代碼 === 'N06')
}else if(e.target.classList.contains('allBtn')){
// 蔬果 "種類代碼": type="N04"
update = data;
}
e.target.classList.add('active');
renderData(update);
}
})
/** 搜尋 **/
const searchBtn = document.querySelector('.search')
searchBtn.addEventListener('click', (e)=>{
const searchInput = document.querySelector('.rounded-end');
// 篩選 data 賦予到一個空陣列上
let filterData = [];
// 如果輸入框為空值,會提醒
if(searchInput.value === ""){
alert('請輸入作物名稱')
} else {
filterData = data.filter((item)=> {
// 回傳 .match 符合的匹配結果
// data 中的作物名稱與搜尋框中的 value 相互 match 篩選的內容,並回傳空陣列
return item.作物名稱.match(searchInput.value);
})
// 如果 filterData 篩選出來仍為空陣列,回傳無此作物名稱
if(filterData.length === 0){
productsList.innerHTML = `<tr>
<td colspan="6" class="text-center p-3">查無此作物名稱^_^</td>
</tr>`
} else {
renderData(filterData);
}
}
})
/** 排序篩選 **/
const jsSelect = document.getElementById('js-select');
// 點擊選單,利用 switch 選取篩選特定內容 + .sort() 排序資料
jsSelect.addEventListener('change', (e)=>{
switch(e.target.value){
case '依上價排序':
selectSort('上價');
break;
case '依中價排序':
selectSort('中價');
break;
case '依下價排序':
selectSort('下價');
break;
case '依平均價排序':
selectSort('平均價');
break;
case '依交易量排序':
selectSort('交易量');
break;
default:
}
})
function selectSort(value){
data.sort((a, b)=> {
return a[value] - b[value];
})
renderData(data);
}
/** 進階排序(上下箭頭) **/
const sortAdvanced = document.querySelector('.js-sort-advanced');
sortAdvanced.addEventListener('click', (e)=>{
if (e.target.dataset.sort === 'up'){
data.sort((a, b) => {
// b - a 可實現從大排到小
return b[e.target.dataset.price]-a[e.target.dataset.price]
})
}else {
data.sort((a, b)=>{
return a[e.target.dataset.price] - b[e.target.dataset.price]
})
}
// 呼叫函式
renderData(data);
})
This Pen doesn't use any external CSS resources.