searchRecipe.js 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. import getParams from './getParams.js';
  2. searchRecipe = function () {
  3. //private menbers
  4. const kolUrl = "./json/kolData.json";
  5. const ordinaryUrl_left = "./json/ordinaryData_left.json";
  6. const ordinaryUrl_right = "./json/ordinaryData_right.json";
  7. const tagUrl = "./json/tagData.json"
  8. let tagData;
  9. let kolData; // kol資料
  10. let ordinaryData_left; // 素人資料
  11. let ordinaryData_right; // 素人資料
  12. let allData = []; //kol+素人資料
  13. let searchTarget = []; // 搜尋標籤
  14. let searchData; // 搜尋後資料
  15. let groupNum = 5; // 一組幾個
  16. let groupData=[]; //一組的資料
  17. let pageActive = 1 //正在第幾頁
  18. let pageItemNum = 5; //一次秀幾頁
  19. let $searchList = $(".search__result__list") // 菜單容器
  20. let $searchPagination = $(".search__result__pagination") // 頁碼容器
  21. //private methods
  22. function init() {
  23. console.log('searchRecipe is loaded.');
  24. // 網址搜尋的tag
  25. if (getParams('search') != null) {
  26. searchTarget.push(getParams('search'))
  27. // 滑至推薦食譜
  28. srollToRecommend();
  29. } else {
  30. searchTarget = [] // 預設tag;
  31. }
  32. // console.log(searchTarget)
  33. // 取得所有食譜資料
  34. getAllrecipeData();
  35. }
  36. // 取得所有食譜資料
  37. function getAllrecipeData() {
  38. // get kolData
  39. fetch(kolUrl)
  40. .then(res => res.json())
  41. .then(data => {
  42. kolData = data.map(item => (
  43. {
  44. sort: 1,
  45. category: "kol",
  46. id: item.kol.id,
  47. index: item.kol.index,
  48. name: item.name + item.text,
  49. tag: item.tag.split(",")
  50. }
  51. ));
  52. // console.log(kolData)
  53. allData = kolData.concat([...allData])
  54. // console.log(allData)
  55. })
  56. .then(() => {
  57. // get ordinaryData_left
  58. fetch(ordinaryUrl_left)
  59. .then(res => res.json())
  60. .then(data => {
  61. ordinaryData_left = data.map(item => {
  62. let tag = []
  63. let tag_1 = item.tag_1.split(",")
  64. let tag_2 = item.tag_2.split(",")
  65. let tag_3 = item.tag_3.split(",")
  66. let tag_4 = item.tag_4.split(",")
  67. if (tag_1.length > 1) {
  68. for (let i = 0; i < tag_1.length; i++) {
  69. tag.push(tag_1[i])
  70. }
  71. } else {
  72. tag.push(item.tag_1)
  73. }
  74. if (tag_2.length > 1) {
  75. for (let i = 0; i < tag_2.length; i++) {
  76. tag.push(tag_2[i])
  77. }
  78. } else {
  79. tag.push(item.tag_2)
  80. }
  81. if (tag_3.length > 1) {
  82. for (let i = 0; i < tag_3.length; i++) {
  83. tag.push(tag_3[i])
  84. }
  85. } else {
  86. tag.push(item.tag_3)
  87. }
  88. if (tag_4.length > 1) {
  89. for (let i = 0; i < tag_4.length; i++) {
  90. tag.push(tag_4[i])
  91. }
  92. } else {
  93. tag.push(item.tag_4)
  94. }
  95. return (
  96. {
  97. sort: 2,
  98. category: "ordinary",
  99. id: item.id,
  100. index: item.index,
  101. name: item.text,
  102. tag: tag
  103. }
  104. )
  105. });
  106. // console.log(ordinaryData_left)
  107. allData = ordinaryData_left.concat([...allData])
  108. // console.log(allData)
  109. })
  110. .then(() => {
  111. fetch(ordinaryUrl_right)
  112. .then(res => res.json())
  113. .then(data => {
  114. ordinaryData_right = data.map(item => {
  115. let tag = []
  116. let tag_1 = item.tag_1.split(",")
  117. let tag_2 = item.tag_1.split(",")
  118. let tag_3 = item.tag_1.split(",")
  119. let tag_4 = item.tag_4.split(",")
  120. if (tag_1.length > 1) {
  121. for (let i = 0; i < tag_1.length; i++) {
  122. tag.push(tag_1[i])
  123. }
  124. } else {
  125. tag.push(item.tag_1)
  126. }
  127. if (tag_2.length > 1) {
  128. for (let i = 0; i < tag_2.length; i++) {
  129. tag.push(tag_2[i])
  130. }
  131. } else {
  132. tag.push(item.tag_2)
  133. }
  134. if (tag_3.length > 1) {
  135. for (let i = 0; i < tag_3.length; i++) {
  136. tag.push(tag_3[i])
  137. }
  138. } else {
  139. tag.push(item.tag_3)
  140. }
  141. if (tag_4.length > 1) {
  142. for (let i = 0; i < tag_4.length; i++) {
  143. tag.push(tag_4[i])
  144. }
  145. } else {
  146. tag.push(tag_4)
  147. }
  148. return (
  149. {
  150. sort: 3,
  151. category: "ordinary",
  152. id: item.id,
  153. index: item.index,
  154. name: item.text,
  155. tag: tag
  156. }
  157. )
  158. });
  159. // console.log(ordinaryData_right)
  160. allData = ordinaryData_right.concat([...allData])
  161. // console.log(allData)
  162. })
  163. .then(() => {
  164. initHandler();
  165. })
  166. .then(() => {
  167. updatePage();
  168. srollToTop();
  169. });
  170. });
  171. });
  172. // get tagData
  173. fetch(tagUrl)
  174. .then(res => res.json())
  175. .then(data => {
  176. tagData = {
  177. fast: [],
  178. main: [],
  179. style: [],
  180. ingredient: []
  181. }
  182. data.forEach((item) => {
  183. if (item.tag_1 != "") {
  184. tagData.fast.push(item.tag_1);
  185. }
  186. if (item.tag_2 != "") {
  187. tagData.main.push(item.tag_2);
  188. }
  189. if (item.tag_3 != "") {
  190. tagData.style.push(item.tag_3);
  191. }
  192. if (item.tag_4 != "") {
  193. tagData.ingredient.push(item.tag_4);
  194. }
  195. });
  196. console.log(tagData)
  197. })
  198. .then(() => {
  199. createTagHtml();
  200. })
  201. .then(() => {
  202. $(".search__form__item[data-tag='" + getParams('search') + "']").addClass("active");
  203. searchTagOption();
  204. searchTagSubmit();
  205. searchFormClear();
  206. })
  207. }
  208. async function initHandler(){
  209. const sortDataBuild = await sortData();
  210. const searchDataBuild = await searchFilter(allData, searchTarget);
  211. const groupDataBuild = await getGroupData();
  212. }
  213. // 排序
  214. function sortData(){
  215. allData.sort(function(a,b){
  216. // console.log(a.index,b.index)
  217. return a.sort - b.sort
  218. })
  219. // console.log(allData)
  220. }
  221. // 找tag
  222. function searchFilter(data,tag){
  223. searchData = data.filter(function(item){
  224. let tagItems = item.tag;
  225. // console.log(item)
  226. return tagItems.filter(function(tagItem){
  227. return tag.indexOf(tagItem)>-1
  228. }).length === tag.length
  229. })
  230. // console.log(tag)
  231. console.log(searchData)
  232. }
  233. // 多少筆資料為一組
  234. function getGroupData(){
  235. groupData = [];
  236. for (let i = 0; i < searchData.length; i += groupNum) {
  237. groupData.push(searchData.slice(i, i + groupNum))
  238. }
  239. // console.log(searchData.length)
  240. console.log(groupData)
  241. if (groupData.length>0) {
  242. createResultHtml();
  243. }else {
  244. $searchList.html("目前無推薦料理<br>搜尋其他靈感吧");
  245. $searchPagination.html("");
  246. }
  247. }
  248. // 更新該頁碼內容
  249. function updatePage(){
  250. $(".search__result__pagination").on("click",".search__result__pageitem",function(){
  251. let activeNum = $(this).data("page");
  252. if (activeNum == "back") {
  253. pageActive--
  254. } else if (activeNum == "next") {
  255. pageActive++
  256. }else {
  257. pageActive = activeNum;
  258. }
  259. updatePageHandler();
  260. });
  261. }
  262. // 更新頁碼內容程序
  263. async function updatePageHandler(){
  264. const RecipeDataBuild = await createResultHtml();
  265. }
  266. // 標籤選項點擊
  267. function searchTagOption(){
  268. $(".search__form__list").on("click",".search__form__item",function(e){
  269. let tagCategory = $(this).parent(".search__form__list").data("category");
  270. if(!$(this).hasClass("active")) {
  271. $(".search__form__list[data-category='" + tagCategory + "']").find(".search__form__item").removeClass("active");
  272. $(this).addClass("active");
  273. }else {
  274. $(this).removeClass("active");
  275. }
  276. });
  277. }
  278. // 搜尋菜色
  279. function searchTagSubmit(){
  280. $(".search__form__cta").click(function(e){
  281. e.preventDefault();
  282. searchTagHandler();
  283. });
  284. }
  285. // 收集被選中的tag
  286. function tagAssemble() {
  287. searchTarget = [];
  288. $(".search__form__item").each(function () {
  289. let tagName = $(this).data("tag");
  290. if ($(this).hasClass("active")) {
  291. searchTarget.push(tagName)
  292. }
  293. });
  294. console.log(searchTarget)
  295. }
  296. // 點擊清除全部
  297. function searchFormClear(){
  298. $(".search__form__clear").click(function(){
  299. tagClear();
  300. pageActive = 1
  301. });
  302. }
  303. // 清除標籤
  304. function tagClear(){
  305. $(".search__form__item").removeClass("active")
  306. }
  307. function clearToInit(){
  308. pageActive = 1
  309. }
  310. async function searchTagHandler(){
  311. const tagAssembleBuild = await tagAssemble();
  312. const searchDataBuild = await searchFilter(allData, searchTarget);
  313. const clearToInitBuild = await clearToInit();
  314. const groupDataBuild = await getGroupData();
  315. const srollToRecommendBuild = await srollToRecommend();
  316. }
  317. // 產生標籤 tag HTML
  318. function createTagHtml(){
  319. for (let i = 0; i < tagData.fast.length ; i++) {
  320. $(".search__form__list-fast").append(`
  321. <div class="search__form__item" data-tag="${tagData.fast[i]}">
  322. ${tagData.fast[i]}
  323. </div>
  324. `);
  325. }
  326. for (let i = 0; i < tagData.main.length; i++) {
  327. $(".search__form__list-main").append(`
  328. <div class="search__form__item" data-tag="${tagData.main[i]}">
  329. ${tagData.main[i]}
  330. </div>
  331. `);
  332. }
  333. for (let i = 0; i < tagData.style.length; i++) {
  334. $(".search__form__list-style").append(`
  335. <div class="search__form__item" data-tag="${tagData.style[i]}">
  336. ${tagData.style[i]}
  337. </div>
  338. `);
  339. }
  340. for (let i = 0; i < tagData.ingredient.length; i++) {
  341. $(".search__form__list-ingredient").append(`
  342. <div class="search__form__item" data-tag="${tagData.ingredient[i]}">
  343. ${tagData.ingredient[i]}
  344. </div>
  345. `);
  346. }
  347. }
  348. // 滑至推薦食譜
  349. function srollToRecommend(){
  350. $("html,body").animate({
  351. scrollTop: $(".search__result").offset().top - 55
  352. });
  353. }
  354. // 滑至頂端
  355. function srollToTop() {
  356. $(".goTop").click(function(){
  357. $("html,body").animate({
  358. scrollTop: 0
  359. });
  360. });
  361. }
  362. // 產生推薦食譜
  363. function createResultHtml(){
  364. $searchList.html("");
  365. $searchPagination.html("");
  366. // 推薦菜單內容
  367. for (let i = 0; i < groupData[pageActive-1].length;i++){
  368. let item = groupData[pageActive-1][i]
  369. // console.log(item.name)
  370. if (item.category == 'kol') {
  371. $searchList.append(`
  372. <li class="search__result__item">
  373. <a href="./recipe.html?kol=${item.id}">${item.name}</a>
  374. </li>
  375. `)
  376. }else {
  377. $searchList.append(`
  378. <li class="search__result__item">
  379. <a href="./recipe_ordinary.html?ordinary=${item.id}">${item.name}</a>
  380. </li>
  381. `)
  382. }
  383. }
  384. //頁碼
  385. let elsePageNum = Math.ceil(pageItemNum / 2)
  386. // console.log("pageActive: " + pageActive)
  387. // console.log("groupData.length: " + groupData.length)
  388. // console.log("elsePageNum: " + elsePageNum)
  389. $searchPagination.append(`
  390. <li class="search__result__pageitem" data-page="back"><img src="./images/searchPage/pageitem-back.png"></li>
  391. `)
  392. if (pageActive >= elsePageNum && pageActive <= (groupData.length - elsePageNum)) {
  393. // 頁數於中間
  394. for (let i = (pageActive - (elsePageNum-1)); i < pageActive ;i++) {
  395. $searchPagination.append(`
  396. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  397. `)
  398. }
  399. $searchPagination.append(`
  400. <li class="search__result__pageitem active" data-page="${pageActive}">${pageActive}</li>
  401. `)
  402. for (let i = (pageActive+1); i < (pageActive + (elsePageNum)); i++) {
  403. $searchPagination.append(`
  404. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  405. `)
  406. }
  407. // console.log("pageActive >= elsePageNum && pageActive <= (groupData.length - elsePageNum)")
  408. }
  409. else if (pageActive >= (groupData.length - elsePageNum) && (groupData.length - elsePageNum)>0) {
  410. // 頁數於最後
  411. for (let i = (groupData.length - (pageItemNum - 1)); i < pageActive; i++) {
  412. $searchPagination.append(`
  413. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  414. `)
  415. }
  416. $searchPagination.append(`
  417. <li class="search__result__pageitem active" data-page="${pageActive}">${pageActive}</li>
  418. `)
  419. for (let i = (pageActive+1); i <= groupData.length; i++) {
  420. $searchPagination.append(`
  421. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  422. `)
  423. }
  424. // console.log("pageActive >= (groupData.length - elsePageNum)")
  425. }
  426. else if (pageActive <= (pageItemNum - (elsePageNum - 1)) && groupData.length > pageItemNum){
  427. // 頁數於最前
  428. for (let i = 1; i < pageActive; i++) {
  429. $searchPagination.append(`
  430. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  431. `)
  432. }
  433. $searchPagination.append(`
  434. <li class="search__result__pageitem active" data-page="${pageActive}">${pageActive}</li>
  435. `)
  436. for (let i = (pageActive+1); i <= pageItemNum; i++) {
  437. $searchPagination.append(`
  438. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  439. `)
  440. }
  441. // console.log("pageActive <= (pageItemNum - (elsePageNum-1)")
  442. }
  443. else {
  444. for (let i = 1; i < pageActive; i++) {
  445. $searchPagination.append(`
  446. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  447. `)
  448. }
  449. $searchPagination.append(`
  450. <li class="search__result__pageitem active" data-page="${pageActive}">${pageActive}</li>
  451. `)
  452. for (let i = (pageActive + 1); i <= groupData.length; i++) {
  453. $searchPagination.append(`
  454. <li class="search__result__pageitem" data-page="${i}">${i}</li>
  455. `)
  456. }
  457. // console.log("else")
  458. }
  459. $searchPagination.append(`
  460. <li class="search__result__pageitem" data-page="next"><img src="./images/searchPage/pageitem-next.png"></li>
  461. `)
  462. if ($(".search__result__pageitem[data-page='back']").hasClass("disabled")) {
  463. $(".search__result__pageitem[data-page='back']").removeClass("disabled");
  464. }
  465. if ($(".search__result__pageitem[data-page='next']").hasClass("disabled")) {
  466. $(".search__result__pageitem[data-page='next']").removeClass("disabled");
  467. }
  468. if(pageActive == 1 ) {
  469. if (!$(".search__result__pageitem[data-page='back']").hasClass("disabled")) {
  470. $(".search__result__pageitem[data-page='back']").addClass("disabled");
  471. }
  472. }
  473. if(pageActive == groupData.length) {
  474. if (!$(".search__result__pageitem[data-page='next']").hasClass("disabled")) {
  475. $(".search__result__pageitem[data-page='next']").addClass("disabled");
  476. }
  477. }
  478. }
  479. {
  480. $(document).ready(function () {
  481. init();
  482. });
  483. }
  484. //public
  485. return {
  486. intoPage: function(){
  487. intoPage();
  488. },
  489. };
  490. };
  491. var searchRecipe = new searchRecipe();