main.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // 載入共用 template
  2. $('#navbar').load('../../template/navbar.html');
  3. $('#footer').load('../../template/footer.html');
  4. $('#removeResultBtn').hide(); // 隱藏全部清除按鈕
  5. // 處理 radio 選取狀態
  6. $('.filter-list .form-check').click(function (e) {
  7. e.preventDefault();
  8. $(this).find('.form-check-input').prop('checked', true);
  9. // 取得 radio 按鈕的 label
  10. let radioLabel = $(this).find('.form-check-label').text().trim().replace(/\s+/g, ' '); // 移除換行空白
  11. // 取上一層 search-tab 按鈕文字
  12. let buttonValue = $(this).closest('.dropdown').find('.search-tab').text().trim();
  13. let buttonId = $(this).closest('.dropdown').find('.search-tab').attr('id');
  14. updateSelectedOptions(buttonId, buttonValue, radioLabel);
  15. });
  16. let filterList = []; // 篩選條件
  17. // 更新篩選狀態
  18. function updateSelectedOptions(id, button, radio) {
  19. page = 1;
  20. console.log('更新篩選狀態', button, radio);
  21. if (filterList.length) {
  22. let exists = false; // 判斷是否已存在
  23. for (let index = 0; index < filterList.length; index++) {
  24. const element = filterList[index];
  25. // 如有重複 button 只改 radio 狀態
  26. if (element.text === button) {
  27. element.value = radio;
  28. exists = true;
  29. // 更新篩選的值
  30. $(`.search-tab-result .budget:contains(${button})`).find('p').text(`${button}:${radio}`);
  31. }
  32. }
  33. // 如果 filterList 中不存在則新增
  34. if (!exists) {
  35. const newItem = {
  36. id: id,
  37. text: button,
  38. value: radio
  39. };
  40. filterList.push(newItem);
  41. createFilterHtml(newItem);
  42. }
  43. } else {
  44. // 儲存篩選條件
  45. filterList.push({
  46. id: id,
  47. text: button,
  48. value: radio
  49. })
  50. for (let index = 0; index < filterList.length; index++) {
  51. const element = filterList[index];
  52. createFilterHtml(element);
  53. }
  54. }
  55. videoSearch(); // 搜尋
  56. console.log('filterList', filterList);
  57. // 切換按鈕選取狀態
  58. $('.dropdown').each(function () {
  59. let hasCheckedRadio = $(this).find('input[type="radio"]:checked').length > 0;
  60. $(this).find('.search-tab').toggleClass('active', hasCheckedRadio);
  61. });
  62. }
  63. // 新增篩選條件 HTML
  64. function createFilterHtml(item) {
  65. let dom = `
  66. <span class="me-3">
  67. <span class="d-flex budget">
  68. <p class="me-1">${item.text}:${item.value}</p>
  69. <img onclick="removeBtn(this, '${item.id}', '${item.text}')" src="https://hhh.com.tw/assets/images/section/icon/close-btn-search.svg" alt="close-btn-search">
  70. </span>
  71. </span>`;
  72. $('.search-tab-result').append(dom);
  73. $('#removeResultBtn').show();
  74. }
  75. // 清除單一篩選條件
  76. function removeBtn(element, id, val) {
  77. console.log('id, val', id, val);
  78. filterList = filterList.filter(item => item.text !== val);
  79. ; // 移除 div & active
  80. $(element).closest('.me-3').remove();
  81. $(`#${id}`).removeClass('active');
  82. // 移除同一層級 ul 內所有 radio 的選取狀態
  83. $(`#${id}`).siblings('.dropdown-menu').find('input[type="radio"]').prop('checked', false);
  84. if (filterList.length === 0) {
  85. $('#removeResultBtn').hide();
  86. }
  87. }
  88. let assignOrder = ""; // 當前排序
  89. // new, hot, recommend 排序 (預設推薦)
  90. $(".search-btn-filter button").click(function () {
  91. // 切換選取狀態
  92. $('.search-btn-filter').find('.active').removeClass('active');
  93. $(this).addClass('active');
  94. assignOrder = $(this).attr('id');
  95. videoSearch("order_by");
  96. });
  97. let page = 1; // 當前頁數
  98. let pageSize = 18; // 每頁數量
  99. let isFirstLoad = true; // 初始載入
  100. // 列表篩選
  101. async function videoSearch(type = "") {
  102. let url;
  103. $('#videoSpinner').show();
  104. $('#videoList').hide();
  105. if (isFirstLoad) {
  106. // 第一次載入使用本地 JSON 文件
  107. // url = './json/designers_lists_data.json';
  108. url = `https://m3.hhh.com.tw:18673/video_search?page=${page}&page_size=${pageSize}&order_by=new`;
  109. } else {
  110. // 後續使用 API (預設排序為 recommend)
  111. url = `https://m3.hhh.com.tw:18673/video_search?page=${page}&page_size=${pageSize}`;
  112. if (type === "order_by") {
  113. url += `&${type}=${assignOrder}`;
  114. }
  115. if (assignOrder === "") {
  116. url += "&order_by=new";
  117. }
  118. let input = $(".keywords").val();
  119. if (input !== "") {
  120. url += `&keyword=${input}`;
  121. }
  122. if (filterList.length) {
  123. filterList.map(item => {
  124. url += `&${item.id}=${item.value}`;
  125. });
  126. }
  127. }
  128. try {
  129. const response = await axios.get(url);
  130. console.log('response.data.videos', response.data.videos);
  131. let totalCount = response.data.total_count;
  132. let totalPages = Math.ceil(totalCount / pageSize);
  133. $("#totalCount").html(totalCount);
  134. if (totalPages) {
  135. $('.filter-list .pagination').show();
  136. setPagination(totalPages); // 分頁處理
  137. } else {
  138. $('.filter-list .pagination').hide();
  139. }
  140. let resultHtml = '';
  141. if (response.data.videos.length) {
  142. response.data.videos.forEach((item) => {
  143. resultHtml += `
  144. <div class="col-md-4 mb-4">
  145. <a href="${item.DesignerLink}">
  146. <div class="card lists-card">
  147. <img src="${item.VideoCoverImg}" class="video-cover-img" alt="${item.DesignerName} ${item.DesignerTitle}">
  148. <div class="card-body d-flex align-items-center">
  149. <div class="person-img me-3 me-md-2 me-lg-3" style="background-image: url('${item.DesignerCoverImg}');"></div>
  150. <section>
  151. <h5 class="card-text text-muted mb-2">${item.DesignerTitle}</h5>
  152. <h6 class="card-title mb-0 text-dark">
  153. <span class="font-weight-bold">
  154. ${item.DesignerName}
  155. </span>
  156. 設計師
  157. </h6>
  158. </section>
  159. </div>
  160. </div>
  161. </a>
  162. </div>`;
  163. });
  164. } else {
  165. resultHtml += "<p class='text-center mt-5'>找不到符合的資料,請重新搜尋。</p>"
  166. }
  167. $('#videoList').html(resultHtml);
  168. setTimeout(() => {
  169. $('#videoList').show();
  170. $('#videoSpinner').hide();
  171. }, 100)
  172. // 更新初始載入狀態
  173. if (isFirstLoad) {
  174. isFirstLoad = false;
  175. }
  176. } catch (error) {
  177. console.log("error", error);
  178. }
  179. }
  180. videoSearch();
  181. let maxPagesMobile = 5; // 手機板最多顯示 5 頁
  182. let maxPagesDesktop = 10; // 電腦版最多顯示 10 頁
  183. // 分頁
  184. function setPagination(pages) {
  185. let screenWidth = $(window).width();
  186. let maxPages = screenWidth > 991 ? maxPagesDesktop : maxPagesMobile;
  187. function renderPagination(currentPage) {
  188. let dom = `
  189. <li class="page-item" onclick="handlePagination(this, 'previous')">
  190. <a class="page-link previous hidden" href="#" aria-label="Previous">
  191. <span aria-hidden="true"><</span>
  192. </a>
  193. </li>`;
  194. let startPage = Math.max(currentPage - Math.floor(maxPages / 2), 1);
  195. let endPage = Math.min(startPage + maxPages - 1, pages);
  196. if (endPage - startPage < maxPages) {
  197. startPage = Math.max(endPage - maxPages + 1, 1);
  198. }
  199. for (let index = startPage; index <= endPage; index++) {
  200. dom += `
  201. <li class="page-item ${index === currentPage ? 'active' : ''}" onclick="handlePagination(this)">
  202. <a class="page-link" href="#">${index}</a>
  203. </li>`;
  204. }
  205. dom += `
  206. <li class="page-item" onclick="handlePagination(this, 'next')">
  207. <a class="page-link next" href="#" aria-label="Next">
  208. <span aria-hidden="true">></span>
  209. </a>
  210. </li>`;
  211. $('.filter-list .pagination').html(dom);
  212. updateVisibility(currentPage, pages);
  213. }
  214. // 更新上頁 & 下頁的按鈕顯示狀態
  215. function updateVisibility(page, pages) {
  216. if (page === 1) {
  217. $('.page-link.previous').addClass('hidden');
  218. } else {
  219. $('.page-link.previous').removeClass('hidden');
  220. }
  221. if (page === pages) {
  222. $('.page-link.next').addClass('hidden');
  223. } else {
  224. $('.page-link.next').removeClass('hidden');
  225. }
  226. }
  227. window.handlePagination = function (item, type = "") {
  228. if (type === "previous" && page > 1) {
  229. page--;
  230. } else if (type === "next" && page < pages) {
  231. page++;
  232. } else if (!type) {
  233. page = parseInt($(item).find('.page-link').text());
  234. }
  235. renderPagination(page);
  236. videoSearch();
  237. }
  238. renderPagination(page);
  239. $(window).on('resize', function () {
  240. let newScreenWidth = $(window).width();
  241. if ((newScreenWidth > 991 && maxPages !== maxPagesDesktop) ||
  242. (newScreenWidth <= 991 && maxPages !== maxPagesMobile)) {
  243. maxPages = newScreenWidth > 991 ? maxPagesDesktop : maxPagesMobile;
  244. renderPagination(page);
  245. }
  246. });
  247. }
  248. // 頁碼處理
  249. function handlePagination(item, type = "") {
  250. if (type === "previous") {
  251. // 往前一頁
  252. if (page > 1) {
  253. page--;
  254. }
  255. console.log(page);
  256. } else if (type === "next") {
  257. // 往後一頁
  258. page++;
  259. console.log(page);
  260. } else {
  261. // 直接點擊頁碼
  262. page = parseInt($(item).find('.page-link')[0].innerText);
  263. }
  264. // 切換選取狀態
  265. $('.filter-list .page-item').removeClass('active');
  266. $('.filter-list .page-item').eq(page).addClass('active');
  267. // 設定上一頁按鈕的顯示狀態
  268. if (page === 1) {
  269. $('.page-link.previous').addClass('hidden');
  270. } else {
  271. $('.page-link.previous').removeClass('hidden');
  272. }
  273. videoSearch(); // 搜尋
  274. }
  275. // 熱搜關鍵字搜尋
  276. $(".search-bar-keyword a").click(function () {
  277. let keyword = $(this).text();
  278. $('.keywords').val(keyword);
  279. videoSearch();
  280. });
  281. // 全部清除
  282. $("#removeResultBtn").click(function () {
  283. console.log('全部清除');
  284. filterList.length = 0; // 清空篩選陣列
  285. $('#removeResultBtn').hide(); // 隱藏全部清除按鈕
  286. $('.search-tab-result').empty(); // 清空篩選條件 dom
  287. // 取消選取狀態
  288. $('.filter-list input[type="radio"]').prop('checked', false);
  289. $('.search-tab').removeClass('active');
  290. videoSearch();
  291. });