DB에서 꺼낸 INT 유형 필드를 별의 수로 표시하는 기능 구현

소개



Amazon 등의 EC 사이트에서, 상품에 대해 별을 붙여 상품의 평가를 하고 있는 것을,
본 적이 없습니까?

「이 상품은 5 스타! 이것은 3 스타!」와 같은.
아라비아 숫자로 「이것은 몇점」이라고 표기되고 있는 것보다, 몹시 몹시 알기 쉽지요.



배경



필자는 웹 프레임 워크의 공부의 과제로서,
「읽은 기술서를 평가해 리스트 업 한다」Web 어플리케이션을 제작중입니다만,
데이터베이스에 등록한 평가 칼럼의 숫자를 꺼내, 그 내용을 별의 개수로서 반영하는 것을 목표로 했습니다.



주의


  • 문제 해결 후 잠시 후 게시물이므로 데이터베이스 내용에 불일치가 발생합니다.
    (예를 들어, 해당 기술서의 평가 수가 스크린샷마다 다르다.)
  • 위의 예와 같이 별 3.5개와 같은 소수는 가정하지 않습니다.
    어디까지나 별 1, 2, 3, 4, 5개로서의 구현입니다.

  • 개발 환경


  • Node.js 12.16.3
  • Express 4.17.1
  • MySQL 8.0.19

  • 구현하고 싶은 것


  • 별의 수는 항상 5 개 표시
  • 평가 수에 따라 별의 색을 주황색으로 설정하여 평가 점을 확인할 수 있습니다
  • 평가 수 미만의 부분은 회색 별로 표시됩니다
  • 이것에 의해, 「평가점의 최대치가 얼마인가」 「이 책의 평가점이 몇개인가」의 가독성을 단번에 향상시킨다

  • 해결 방법



    우선 바닐라 HTML/CSS 준비



    먼저 별을 표시하는 소스 코드를 준비해야합니다.

    여기을 참고했습니다.

    변경한 곳 : unchecked라는 클래스도 준비했다 (문자색을 grey로 변경한다)

    소스 코드


    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    
    <span class="fa fa-star checked"></span>
    <span class="fa fa-star checked"></span>
    <span class="fa fa-star checked"></span>
    <span class="fa fa-star unchecked"></span>
    <span class="fa fa-star unchecked"></span>
    
    
    
    
    .checked {
        color: orange;
    }
    .unchecked {
        color: grey;
    }
    

    표시 결과





    구현해보기



    데이터베이스 내용



    이 테이블의 "good"라는 열이 평가 (별 수)에 해당합니다.



    구현 전 소스 코드 및 스크린샷



    app.js
    
    app.get("/", (req, res) => {
      const sql = "select * from book";
      connection.query(sql, function (err, result, fields) {
        if (err) throw err;
        res.render("index", { book: result });
      });
    });
    
    

    inex.ejs
    
          <table>
            <tr>
              <th>タイトル</th>
              <th>著者</th>
              <th>出版社</th>
              <th>評価</th>
              <th>更新</th>
              <th>削除</th>
            </tr>
            <% book.forEach(function (value) { %>
            <tr>
              <td class="title"><%= value.title %></td>
              <td><%= value.author %></td>
              <td><%= value.publisher %></td>
              <td><%= value.good %></td>
              <td><a href="/edit/<%= value.title %>">更新</a></td>
              <td>
                <a
                  href="/delete/<%= value.title %>"
                  onClick="disp('<%= value.title %>'); return false;"
                  >削除</a
                >
              </td>
            </tr>
            <% }); %>
          </table>
    



    구현 후 소스 코드와 스크린샷(및 보충 코멘트)



    app.js
    
    const maxStar = 5;
    
    app.get("/", (req, res) => {
      const sql = "select * from book";
      connection.query(sql, function (err, result, fields) {
        if (err) throw err;
        books = [];
        for (book of result) {
          book.colored = book.good;  // 評価の数(オレンジ色の星の数)
          book.uncolored = maxStar - book.good;  // 灰色の星の数
          books.push(book);
        }
        res.render("index", { book: books }); 
      });
    });
    

    index.ejs
    
          <table>
            <tr>
              <th>タイトル</th>
              <th>著者</th>
              <th>出版社</th>
              <th>評価</th>
              <th>更新</th>
              <th>削除</th>
            </tr>
            <% book.forEach(function (value) { %>
            <tr>
              <td class="title"><%= value.title %></td>
              <td><%= value.author %></td>
              <td><%= value.publisher %></td>
              <td>
                <% for (let i = 0; i < value.colored; i++){ %>
                <span class="fa fa-star checked"></span>
                <% } %> <% for (let i = 0; i < value.uncolored; i++){ %>
                <span class="fa fa-star unchecked"></span>
                <% } %>
              </td>
              <td><a href="/edit/<%= value.title %>">更新</a></td>
              <td>
                <a
                  href="/delete/<%= value.title %>"
                  onClick="disp('<%= value.title %>'); return false;"
                  >削除</a
                >
              </td>
            </tr>
            <% }); %>
          </table>
    



    app.js 정보



    구현 전에는 「평가의 수」만 있으면 좋았지만,
    이번에는 "오렌지색으로 물든 별의 수""색이 붙지 않은 (처럼 보이는 회색) 별의 수"라는 두 가지 변수가 필요합니다.
    데이터베이스에서 레코드를 검색한 후,
    평가 수의 최대 값 (5)에서 good 열 수를 빼서 회색 별 수를 얻고,
    이것들을 정리해 초기화한 배열 books 에 삽입, index.ejs에 렌더링 하는 것으로 해결을 도모하고 있습니다.

    index.ejs 정보



    ejs 파일은 일반적으로 HTML에서 사용하는 JavaScript뿐만 아니라,
    app.js에서 전달된 데이터를 활용한 JavaScript를 포함할 수 있습니다.

    별의 수에 대해 사용한 부분은 다음과 같습니다.
    colored 변수에 저장된 수만큼 for 루프하고 오렌지색 별을 표시,
    uncolored 변수에 저장된 수만큼 for 루프하여 회색 별을 표시합니다.
                <% for (let i = 0; i < value.colored; i++){ %>
                <span class="fa fa-star checked"></span>
                <% } %> <% for (let i = 0; i < value.uncolored; i++){ %>
                <span class="fa fa-star unchecked"></span>
                <% } %>
    

    좋은 웹페이지 즐겨찾기