點讚和倒讚功能
功能製作教學
前情提要:
一間房子可以被使用者點讚/倒讚
一則留言可以被使用者點讚/倒讚
最終程式碼
控制留言喜歡/不喜歡按鈕的JS頁面
comment_like_controller.js
> import { Controller } from "@hotwired/stimulus"
> import { fetchWithoutParams } from "../controllers/lib/fetcher"
> import { library, dom } from '@fortawesome/fontawesome-svg-core'
> import { faThumbsUp as regularThumbsUp , faThumbsDown as regularThumbsUDown } from '@fortawesome/free-regular-svg-icons'
> import { faThumbsUp as solidThumbsUP, faThumbsDown as solidThumbsDown } from '@fortawesome/free-solid-svg-icons'
>
> export default class extends Controller {
>
> static targets = [ 'thumbsUp', "thumbsDown", "commentLikeCount", "commentDislikeCount" ]
>
> initialize(){
> library.add(regularThumbsUp, regularThumbsUDown, solidThumbsUP, solidThumbsDown, )
> }
> connect() {
> dom.watch()
>
>
> const commentLikeState = this.element.dataset.commentLikeState
> if (commentLikeState === 'true') {
> // 如果是正讚,讓正讚是solid,倒讚是regular
> this.likeButtonSolid()
> this.dislikeButtonRegular()
>
> } else if (commentLikeState === 'false') {
> this.dislikeButtonSolid()
> this.likeButtonRegular()
> }
>
> }
>
> like() {
>
> const commentId = this.element.dataset.commentId
> const token = document.querySelector("meta[name='csrf-token']").content
>
> // // 使用者點擊正讚後,傳到後端的東西
> fetch((`/comments/${commentId}/like`), {
> method: "PATCH",
> headers: {
> "X-CSRF-Token": token
> }
> })
> .then((resp) => {
> return resp.json()
> })
> .then(({status, likeCommentCount, dislikeCommentCount}) => {
>
> if (status === "liked comment") {
> this.likeButtonSolid()
> } else if (status === "delete comment like_state") {
> this.likeButtonRegular()
> } else {
> // 倒讚Regular
> this.dislikeButtonRegular()
> // 正讚Solid
> this.likeButtonSolid()
> }
>
> this.setTextContent(likeCommentCount, dislikeCommentCount)
>
> })
> .catch((err) => {
> console.log(err);
> })
>
> }
>
> dislike() {
>
> const commentId = this.element.dataset.commentId
> const token = document.querySelector("meta[name='csrf-token']").content
>
> // 使用者點擊倒讚後,傳到後端的東西
> fetch((`/comments/${commentId}/dislike`), {
> method: "PATCH",
> headers: {
> "X-CSRF-Token": token
> }
> })
> .then((resp) => {
> return resp.json()
> })
> .then(({status, likeCommentCount, dislikeCommentCount}) => {
>
> if (status === "disliked comment") {
> this.dislikeButtonSolid()
> } else if (status === "delete comment like_state") {
> this.dislikeButtonRegular()
> } else {
> // 正讚Regular
> this.likeButtonRegular()
> // 倒讚Solid
> this.dislikeButtonSolid()
> }
>
> this.setTextContent(likeCommentCount, dislikeCommentCount)
>
> })
> .catch((err) => {
> console.log(err);
> })
> }
>
>
> // 正讚solid
> likeButtonSolid() {
> this.thumbsUpTarget.classList.add("fa-solid")
> this.thumbsUpTarget.classList.remove("fa-regular")
> }
>
> // 正讚regular
> likeButtonRegular() {
> this.thumbsUpTarget.classList.remove("fa-solid")
> this.thumbsUpTarget.classList.add("fa-regular")
> }
>
> // 倒讚solid
> dislikeButtonSolid() {
> this.thumbsDownTarget.classList.add("fa-solid")
> this.thumbsDownTarget.classList.remove("fa-regular")
> }
>
> // 倒讚regular
> dislikeButtonRegular(){
> this.thumbsDownTarget.classList.add("fa-regular")
> this.thumbsDownTarget.classList.remove("fa-solid")
> }
>
>
>
> setTextContent(likeCommentCount, dislikeCommentCount) {
> this.commentLikeCountTarget.textContent = likeCommentCount
> this.commentDislikeCountTarget.textContent = dislikeCommentCount
> }
>
> }
控制房子喜歡/不喜歡按鈕的js頁面
house_like_controller.js
> import { Controller } from "@hotwired/stimulus"
> import { library, dom } from '@fortawesome/fontawesome-svg-core'
> import { faHeartCrack } from '@fortawesome/free-solid-svg-icons'
> import { faHeart } from '@fortawesome/free-regular-svg-icons'
>
> export default class extends Controller {
>
> static targets = [ 'heart', "heartCrack", "houseLikeCount" ]
>
> initialize(){
> library.add(faHeart, faHeartCrack)
> }
> connect() {
> dom.watch()
>
> // 一進來就先判斷,LikeState中的state到底是空的還是false還是true
> const likeState = this.element.dataset.likeState
>
> if (likeState === 'true') {
> this.heartBlue()
> } else if (likeState === 'false') {
> this.heartCrackBlue()
> }
>
> }
>
> // 點擊愛心的動作
> heart() {
> const houseID = this.element.dataset.id
> const token = document.querySelector("meta[name='csrf-token']").content
>
> // 這個是新增like的路徑 - /houses/:id/like
> fetch(`/houses/${houseID}/like`, {
> method: "PATCH",
> headers: {
> "X-CSRF-Token": token
> },
> body: JSON.stringify(params),
> })
> .then((resp) => {
> return resp.json()
> })
> .then(({status, houseLikeCount, houseDislikeCount}) => {
>
> if (status === "liked house") {
> this.heartBlue()
> } else if ( status === 'delete house like_state' ) {
> this.heartWhite()
> } else {
> this.heartBlue()
> this.heartCrackWhite()
> }
>
>
> // 這邊把後端傳來的實際數量,再用dispatch傳到顯示數量的controller
> const increaseCount = new CustomEvent("increase", {
> detail: {houseLikeCount: houseLikeCount, houseDislikeCount: houseDislikeCount}
> })
> window.dispatchEvent(increaseCount)
>
> })
> .catch((err) => {
> console.log(err);
> })
>
> }
>
> // 點擊破碎愛心的動作
> heartCrack() {
>
> const houseID = this.element.dataset.id
> const token = document.querySelector("meta[name='csrf-token']").content
>
> fetch(`/houses/${houseID}/dislike`, {
> method: "PATCH",
> headers: {
> "X-CSRF-Token": token
> }
> })
> .then((resp) => {
> return resp.json()
> })
> .then(({status, houseLikeCount, houseDislikeCount}) => {
> if (status === "disliked houses") {
> this.heartCrackBlue()
> } else if (status === "delete house like_state") {
> this.heartCrackWhite()
> } else {
> this.heartCrackBlue()
> this.heartWhite()
> }
>
> // 這邊把後端傳來的實際數量,再用dispatch傳到顯示數量的controller
> const decreaseCount = new CustomEvent("decrease", {
> detail: {houseLikeCount: houseLikeCount, houseDislikeCount: houseDislikeCount}
> })
> window.dispatchEvent(decreaseCount)
> })
> .catch((err) => {
> console.log(err);
> })
> }
>
>
> // 把愛心底色加上藍色
> heartBlue() {
> this.heartTarget.classList.add("bg-blue-100")
> }
>
> // 把愛心底色加上白色
> heartWhite() {
> this.heartTarget.classList.remove("bg-blue-100")
> }
>
> // 把破碎愛心底色加上藍色
> heartCrackBlue() {
> this.heartCrackTarget.classList.add("bg-blue-100")
> }
>
> // 把破碎愛心底色加上白色
> heartCrackWhite() {
> this.heartCrackTarget.classList.remove("bg-blue-100")
> }
>
> }