jQuery+LocalStorageで簡易家計簿ツールを作りました

今年の11月からjQueryを勉強し始めて2カ月が経ちました。

まだjavasriptやjQueryを使いこなせてるわけではないけど、大分苦手意識は無くなりました。

jQueryの勉強は引き続き継続し来ますが、今年ももうすぐ終わすので、今まで勉強しことを総動員して何か作ってみようと思います。
( ・`◡・´)

■勉強した内容(抜粋)

 

自分は社内SEなので作るものは地味なものばかりだなと思いますが、基本的を抑えるのは大事。

アニメーションのような派手なことは今後勉強してできるようにしていけばいいんです。

今回作ったものも「簡易家計簿ツール」という地味なものですが、今まで勉強した内容をすべて詰め込んだ、我ながら大作ができたと自画自賛しています。
╰(*´︶`*)╯

 

簡易家計簿ツール

※LocalStrageは1.0MBが限界のため、過度にデータを登録するのは控えてください。

 

使い方

購入した明細の登録、保存、削除、閲覧が可能です。

初回で開いた時は、現在の日付のをもとに当月分の明細が表示されます。(左上に表示されて年月の家計簿が表示されています。)

2段目の両端にある「<<前月」と「翌月>>」のリンクはクリックすることでそれぞれ前月と翌月の家計簿に切り替わります。

登録する際は2つあるテキストボックスのうち、左側に商品名を入力し右側に金額を入力して登録ボタンを押せば登録され、自動で登録日が登録される形で一覧に表示される仕組みです。(バリデーションチェックとして、空欄チェックと数値チェックを行っています。)

家計簿の削除も簡単にできます。一つずつ消す場合は家計簿の一覧にある削除ボタンを押すことで可能です。

クリアボタンを押せば当月分の家計簿をすべて削除することもできます。

 

仕組みの概要

家計簿のデータはすべてLocalStorageに保存する仕組みになっています。

ポイントは月ごとのデータを別名のLocalStorageに保存している点です。左上になる年月を参照し、その年月をもとにLocalStorageのキーを作成して操作しています。

処理の流れの一部を簡単に説明します。

例えば、データを登録する際は以下の流れで処理しています。
 1、入力した商品名と価格のバリデーションチェックを行う
 2、バリエーションチェックが問題なければテーブルの最後に行を追加
 3、左上の年月を参照し、キーを作成
 4、キーを使ってLocalStorageから当月分の家計簿データを取得
 5、家計簿データをJSON形式から連想配列に変換
 6、登録した商品名と価格を配列にして5で作成した家計簿データをマージ
 7、6のデータをJSON形式に変換してLocalStorageに上書き保存

一行削除の処理は以下の通り。
 1、削除した1行をテーブルから削除
 2、テーブルの内容を読み込み、連想配列を作成
 3、2の連想配列をJSON形式に変換
 4、左上の年月を参照し、キーを作成
 5、4のキーを使ってLocalStorageに3のJSONデータを上書き保存

前月の家計簿を表示するには以下の処理をします。
 1、左上の年月を参照し、それをもとに前月の日付を作成
 2、前月の日付をもとにLocalStorageのキーを作成
 3、キーを使ってLocalStorageから当月分の家計簿データを取得
 3、家計簿データをJSON形式から連想配列に変換
 4、現状表示しているテーブルのbody部分を削除
 5、3のデータをもとに明細情報のテーブルを作成し表示

 

ソースの全文

HTML

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf8">
    <title>sum price</title>
  </head>
  <body>
    <div class="content">
      <p><b>日付:<span id="target_month"></span></b></p>
      <p>
        <a id="get_before_month" href="javascript:void(0);"><<前月</a>
        <input type="text" id="product_name" placeholder="商品">
        <input type="text" id="product_price" placeholder="価格">
        <input type="button" id="add" value="追加">
        <input type="button" id="clear" value="クリア">
        <a id="get_next_month" href="javascript:void(0);">翌月>></a>
      </p>
      <table>
        <thead>
          <tr>
            <th width="25%">日付</th>
            <th width="40%">商品</th>
            <th width="25%">価格</th>
            <th width="10%"></th>
          </tr>
        </thead>
        <tbody>
        </tbody>
      </table>
    <div>
      <b><p class="sum_price">合計:0円</p></b>
    </div>
  </div>
  </body>
</html>

CSS

body {
  background-color: #a3d5d3;
  width: 600px;
  font-family: 'Helvetica', 'Arial', sans-serif;
  margin: 0 auto;
  padding: 20px;
}

div.content {
  /* 要素をはみ出さない */
  width: 600px;
  table-layout: fixed;
  word-wrap: break-word;
  word-break: break-all;
  overflow: visible;
}

table, input {
 margin: 5px;
}

input[type=text] {
 width: 120px;
}

table {
  width: 550px;
}

table,tr,th,td {
  font-size: 14px;
  list-style-type: none;
  border-radius: 3px;
  border: 1px solid #000;
  padding: 5px;
}

td {
  background: #eeeff0;
  padding-left: 12px;
}

 jQuery

$(function(){
  // 表示対象の年月を取得
  var now_date  = new Date();
  var now_month = now_date.getFullYear()+ '/' +(now_date.getMonth()+1);
  $("#target_month").append(now_month);
  // ローカルストレージから表を作成
  bulidTable();
  // 画面表示時に価格の合計値を計算
  sum();
  // 挿入した行のボタンイベントをイベントハンドラへ登録する
  createDeleteEvent(); 


  /********************
  共通関数
  ********************/
  function removeLocalStorage(name){
    if(isBlank(name)) {
      alert("error!!");
      return false;
    }
    // ローカルストレージから削除
    localStorage.removeItem(name);
  }
  
  function removeLocalStorageAll(){
    // ★ローカルストレージをすべてクリア
    localStorage.clear();
  }

  function getLocalstorageItem(name){
    if(isBlank(name)) retun;
    return localStorage.getItem(name);
  }

  function saveLocalstorage(name, data){
    if(isBlank(name) || isBlank(data)) {
      alert("error!!");
      return false;
    }

    // ローカルストレージに新規保存or上書き
    localStorage.setItem(name, data);
    return true;
  }

  //ローカルストレージ名生成
  function getLocalStorageName(ym = '') {
    var base_name = '_kakeibo';
    if(isBlank(ym)) {
      var target_month = $("#target_month").text();
      ym = target_month.replace( /\//g , "" );
    }
    return ym + base_name;
  }

  // テーブルを自動生成する
  function bulidTable(){
    var tableBody = "";
    // テーブルを初期化
    $("table tbody tr").remove();
    
    // ローカルストレージ名取得
    var localstorage_name = getLocalStorageName();
    var localSt = getLocalstorageItem(localstorage_name);
    // ローカルストレージのデータ取得
    // JSON形式から連想配列に変換
    var localStJSON = JSON.parse(localSt);

    $(localStJSON).map(function(index, line){
      tableBody += "<tr>";
      tableBody += "<td>" + line["date"] + "</td>";
      tableBody += "<td class='name'>" + line["name"] + "</td>";
      tableBody += "<td class='price'>" + line["price"] + "</td>";
      tableBody += '<td><input type="button" class="delete" value="削除"></td>';
      tableBody += "</tr>";
    });
    // テーブルを生成
    $('table tbody').append(tableBody);
  }

  // 空欄チェック
  function isBlank(data){ 
    if (data.length ==0 || data == ''){
      return true;
    } else {
      return false;
    }
  }

  // 合計値を求める
  function sum(){
    // 表の金額を取得する(tdの奇数列を取得)
    var pricelist = $("table td[class=price]").map(function(index, val){
      var price = parseInt($(val).text());
      if(price >= 0) {
        return price;
      } else {
        return null;
      }
    });
    // 価格の合計を求める
    var total = 0;
    pricelist.each(function(index, val){
      total = total + val;
    });
    $(".sum_price").text("合計:"+total+"円");
  }

  // テーブル情報を読み込みJSON形式変換して返す
  function getJsonFromTable() {
    var counter = 0;
    var line    = [];
    $("table tbody tr").map(function(index, val){
      line[counter] = {"date":$(val).children().eq(0).text()
                  , "name":$(val).children().eq(1).text()
                  , "price":$(val).children().eq(2).text()};
      counter += 1;
    });
    return line;
  }
  
  function createDeleteEvent() {
    $(document).on("click", ".delete", function(event) {
      var target = $(event.target);
      target.parents("tr").remove();
      // 合計値を再計算
      sum();
      var line = getJsonFromTable();
      // 連想配列からJSON形式に変換
      var mainJSON = JSON.stringify(line);
      // ローカルストレージに保存
      saveLocalstorage(getLocalStorageName(), mainJSON);
    });
  }

  /********************
  各種イベント処理
  ********************/
  // 前月リンク押下時の処理
  $("#get_before_month").click(function(){
    var target_month_str = $("#target_month").text();
    var target_month_array = target_month_str.split("/");
    var last_date = new Date(target_month_array[0], target_month_array[1]-2, 1);
    var last_month = last_date.getFullYear()+ '/' +(last_date.getMonth()+1);
    var last_ym    = last_date.getFullYear().toString() + (last_date.getMonth()+1).toString();
    $("#target_month").text(last_month);
   // テーブルフォームの再作成
   bulidTable();
    // 合計金額の再計算
  sum();
    // 挿入した行のボタンイベントをイベントハンドラへ登録する
    createDeleteEvent(); 
  });

  // 翌月リンク押下時の処理
  $("#get_next_month").click(function(){
    var target_month_str = $("#target_month").text();
    var target_month_array = target_month_str.split("/");
    var next_date = new Date(target_month_array[0], target_month_array[1], 1);
    var next_month = next_date.getFullYear()+ '/' +(next_date.getMonth()+1);
    var next_ym    = next_date.getFullYear().toString() + (next_date.getMonth()+1).toString();
    $("#target_month").text(next_month);
   // テーブルフォームの再作成
    bulidTable();
    // 合計金額の再計算
  sum();
    createDeleteEvent(); 
  });

  // addボタン押下時の処理
  $("#add").click(function(){
    var name = $("#product_name").val();
    var price = $("#product_price").val();
    var date  = new Date();
    var str_date = date.getFullYear()+ '/' +(date.getMonth()+1)+ '/' +date.getDate();

    // 空欄チェック
    if(isBlank(name) || isBlank(price)) {
      alert('空欄の項目があります。');
      return;
    }
    // 数値チェック
    if (!$.isNumeric(price)) {
      alert('価格は数値で入力してください。');
      return;
    }

    // 行を追加
    $('table').append('<tr><td>'+ str_date +'</td>'
                +'<td class="name">'+ name +'</td>'
                +'<td class="price">'+ price +'</td>'
                +'<td><input type="button" class="delete" value="削除"></td>'
                +'</tr>');

    //ローカルストレージに保存
    var product = {"date":str_date, "name":name, "price":price};
    //既存のローカルストレージの値を取得
    var mainArray    = [];
    var localStJSON = getLocalstorageItem(getLocalStorageName());
    if(localStJSON != null && localStJSON != "") {
      // JSON形式から連想配列に変換
      var mainArray = JSON.parse(localStJSON);
    }

    mainArray.push(product);

    // 連想配列からJSON形式に変換
    var mainJSON = JSON.stringify(mainArray);
    // ローカルストレージに保存
    saveLocalstorage(getLocalStorageName(), mainJSON);

    // 合計値を再計算
    sum();

    // 挿入した行のボタンイベントをイベントハンドラへ登録する
    createDeleteEvent();
  });

  // clearボタン押下時の処理
  $("#clear").click(function(){
   if(!confirm('当月分のデータを削除します。よろしいですか?')){
      return false;
    }else{
      removeLocalStorage(getLocalStorageName());
      $("table tbody tr").remove();
      sum();
    }
  });
});

 

 

まとめ

以上でjQueryとLocalStorageで作った簡易家計簿ツールの説明は終わりです。

今後もjQueryだけに限らず、フロントサイドの技術の勉強を継続し、やれることをグングン増やしていきたいです。

⁽⁽٩(๑˃̶͈̀ ᗨ ˂̶͈́)۶⁾⁾ 

 

■今年にjQueryを勉強した内容



投稿日:2019-12-14    更新日:2019-12-30

[スポンサーリンク]

[スポンサーリンク]

  
サイト内検索
プロフィール

プロフィール

[Name : POCO(@PocoIt2019)]
都内で社内SEをしているおじさん。
仕事で得られる知識だけでは限界を感じ、 WEBの勉強がてらITブログを開始。
サーバからWEBサイトまでフルスクラッチで開発しました。
現在は勉強のモチベーションを保つために活用中。
興味があることを雑記的に書いていきます。

[スポンサーリンク]

カテゴリ


タグ

[スポンサーリンク]

最近の記事