2017/02/20

jQueryでカンマ有り価格の差額を計算する





差額をフロント側で表示したいときってたまにあるんですよね。。

カンマがない価格だったら割と簡単にできると思うんですが、
カンマありの価格の差額を出すのが難しかったので、ここにメモっておきます。



動作サンプル

See the Pen jsでカンマ付きの価格の差額を計算する by takapen (@takapen) on CodePen.







HTMLサンプル

なんと円OFF!!!

10,000円 -> 1,000

なんと円OFF!!!

5,000,000円 -> 1,000






JavaScriptサンプル
$(function() {

 function addComma(str) {//カンマを入れる関数
  //var num = new String(str).replace(/,/g, "");//カンマをトル
  var num = new String(str);// すでにカンマはとってあるので今回はこれでok
  while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2")));//カンマを3ケタごとに入れる
  return num;
 };

 $(".sale").each(function(){

  var strTeika = $(this).find(".sale__teika").text();// 定価の価格を取得
  var strWaribiki = $(this).find(".sale__waribiki").text();// 割引後価格を取得

  //splitでカンマ区切りで価格を配列に分け、trimで配列を結合し文字列に。trim両端から空白を取り除いた文字列を返します。
  //場合によってはtrimはいらないかも。
  var numTeika = parseInt(strTeika.split(',').join('').trim());//定価のカンマをトル
  var numWaribiki = parseInt(strWaribiki.split(',').join('').trim());//割引後価格のカンマをトル

  var sumPrice = (numTeika - numWaribiki);// 定価引く割引価格
  var strSumPrice = addComma(sumPrice);// 差額の数値をaddComma関数に入れ、カンマ付きの文字列に。

  $(this).find(".sale__sagaku").text(strSumPrice);//要素を指定して、表示。

 });
  
});

















ちなみに
知り合いのプログラマさんから



「カンマしか入らない保証はないから、数字以外はすべてトルほうがいい。
parseIntは数字に変換できない場合はNaN返すから、if(isNaN()){}で例外処理入れたほうが影響受けにくい処理になる。」

上記のインプットをいただいたので下に2つサンプルを書いてみました。
こんな書き方でいいのかわからないけど..。






さらに追記。これを追加したサンプル2つをみたプログラマさんから


「isNaN()した時に数値じゃなくて全部数値にするなら最初からした方がいい。

if ( isNaN( numTeika ) ) {
var numTeika = ‘変な値が入っています’;
} 的なこと。」



こんなイメージだったみたいです。




JavaScriptサンプル 2
「カンマしか入らない想定なのに、カンマ以外の文字列が入ったときの例外処理をif文で」
$(function() {

  function addComma(str) {
    var num = new String(str);
    while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2")));
    return num;
  };

  $(".sale").each(function(){

    var strTeika = $(this).find(".sale__teika").text();
    var strWaribiki = $(this).find(".sale__waribiki").text();

    var numTeika = parseInt(strTeika.split(',').join('').trim());
    var numWaribiki = parseInt(strWaribiki.split(',').join('').trim());

    // カンマしか入らないはずなのに、カンマ以外の文字列が入ったときの例外処理
    if ( isNaN( numTeika ) ) {
      var numTeika = parseInt(strTeika.replace(/[^0-9]/g,""));
    }
    if ( isNaN( numWaribiki ) ) {
      var numWaribiki = parseInt(strWaribiki.replace(/[^0-9]/g,""));
    }

    var sumPrice = (numTeika - numWaribiki);
    var strSumPrice = addComma(sumPrice);

    $(this).find(".sale__sagaku").text(strSumPrice);

  });
  
});






JavaScriptサンプル 3
「価格の中にカンマ以外が入る場合」
$(function() {

  function addComma(str) {
    var num = new String(str);
    while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2")));
    return num;
  };

  $(".sale").each(function(){

    var strTeika = $(this).find(".sale__teika").text();
    var strWaribiki = $(this).find(".sale__waribiki").text();

    // replaceで数字のみを抽出
    var numTeika = parseInt(strTeika.replace(/[^0-9]/g,""));
    var numWaribiki = parseInt(strWaribiki.replace(/[^0-9]/g,""));

    var sumPrice = (numTeika - numWaribiki);
    var strSumPrice = addComma(sumPrice);

    $(this).find(".sale__sagaku").text(strSumPrice);

  });
  
});





さらにアドバイスいただきました。ありがとうございます。

サンプル3で言うと、
「カンマをトル処理」と、「差額を計算する処理」は、関数化したほうがいいよね。

// カンマとる処理
function removeComma(str) {
  return str.replace(/[^0-9]/g,"");
}

// 差額を計算する処理
// 変な値はややこしいので0に変換する
function calc_sagaku(val1, val2) {
  val1 = ( isNaN( parseInt(val1) ) )? 0: parseInt(val1);
  val2 = ( isNaN( parseInt(val2) ) )? 0: parseInt(val2);
  return (val1 - val2);
}

と、js書いてくれました。
なので、それを踏まえてサンプル4を書いてみました。





JavaScriptサンプル 4
「関数化した場合」
$(function() {

  // カンマをとる処理
  function removeComma(str) {
    return str.replace(/[^0-9]/g,"");
  }

  // 差額を計算する処理
  // 変な値はややこしいので0に変換する
  function calc_sagaku(val1, val2) {
    val1 = ( isNaN( parseInt(val1) ) )? 0: parseInt(val1);
    val2 = ( isNaN( parseInt(val2) ) )? 0: parseInt(val2);
    return (val1 - val2);
  }

  // カンマを入れる処理
  function addComma(str) {
    var num = new String(str);
    while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2")));
    return num;
  };


  $(".sale").each(function(){
 
    var strTeika = $(this).find(".sale__teika").text();
    var strWaribiki = $(this).find(".sale__waribiki").text();

    // カンマをとる処理
    var numTeika = removeComma(strTeika);
    var numWaribiki = removeComma(strWaribiki);

    // 差額を計算する処理
    var sumPrice = calc_sagaku(numTeika, numWaribiki);

    // カンマを入れる処理
    var strSumPrice = addComma(sumPrice);
 
    $(this).find(".sale__sagaku").text(strSumPrice);
 
  });
   
});


すごい。