API Docs for: 1.0.0
Show:

File: nablarch-widget-event-autosum\ui_public\js\nablarch\ui\AutoSum.js

/**
 * @module nablarch.ui
 */
define([
  "jquery"                         // jQueryライブラリ
  , "nablarch/ui/Widget"           // ウィジェットの共通基底クラス
  , "nablarch/util/BigDecimal"     // BigDecimalクラス
  , "nablarch/ui/readonly"         // readonly制御
  , "nablarch/ui/event"            // nablarchの動作に関連したイベントの定義
  , "sugar"                        // sugar.js
],

  function ($, Widget, BigDecimal, readonly) { "use strict";    
    /**
     * 自動集計機能
     * ============================================
     * 自動集計機能は、ユーザが入力した値をクライアントサイドで集計するためのUI機能である。
     *
     * 本機能では、テキストフィールドに入力された値を集計し合計欄に結果を出力する。
     * 集計処理が行われるタイミングは、集計対象のテキストフィールドからフォーカスが外れたタイミングである。
     *
     * ※集計対象の入力欄の値が入力されているが数値以外の場合には、集計処理を行うことができないため計算結果はNaN(Not A Number)となる。
     * また、有効桁(15桁)を超える場合にもNaN(Not A Number)となる。
     *
     * マークアップ仕様
     * ------------------------
     * 本機能を使用する場合以下のマーカCSSを使用する。
     *
     * 1. 合計値を出力する要素
     *
     *   マーカCSSとして `nablarch_AutoSum` を指定する。
     *   自動集計対象のテキストフィールドは、`-target` オプションで指定する。  
     *   (合計値は、テキストフィールド及びHTML要素のContent部に出力する事ができる。)
     *
     * 2. 自動集計対象の要素
     * 
     *   合計値を出力する要素の `-target` オプションで指定した値をマーカCSSとして指定する。
     *   
     *   **加算する場合:** `AutoSum_ + (-target オプションで指定した値)`  
     *   **減算する場合:** `AutoSum_ + (-target オプションで指定した値) + _negative`
     *
     * 使用例
     * ---------
     * 
     *   **HTML** 
     * 
     *     <!-- 合計値を出力するエリア -->
     *     <!-- 集計対象の入力フィールドは、class属性に「target1」が指定されたものとなる -->
     *     <span class="AutoSum -target target1"></span>
     *     <!-- 集計対象の入力フィールド -->
     *     <!-- 合計値出力エリアの「-target」で指定したクラス名を設定する。 -->
     *     <input name="form.amount1" class="AutoSum_target1" size="15" maxlength="10">
     *     <input name="form.amount2" class="AutoSum_target1" size="15" maxlength="10">
     *     <!-- 末尾に_negativeが付加されているので、この項目だけは集計時に減算される -->
     *     <input name="form.amount3" class="AutoSum_target1_negative" size="15" maxlength="10">
     *
     *
     *   **JSP**
     *   
     *   この実装例では、以下2種類の自動集計が行われる。  
     *   1. 金額1-1から金額1-3の合計が合計1に出力される。  
     *   2. 金額2-1と金額2-2の合計が合計2に出力される。  
     *   (金額2-2には、減算のマーカCSSが指定されているため、金額2-1から金額2-2を引いた値が出力される。)
     * 
     * 
     *     <div class="field">
     *       <label>金額1-1:</label>
     *       <n:text name="W99ZZ5.amount1_1" id="amount1_1" maxlength="20" cssClass="AutoSum_target1" />
     *       <n:error name="W99ZZ5.amount1_1" />
     *     </div>
     *
     *     <div class="field">
     *       <label>金額1-2:</label>
     *       <n:text name="W99ZZ5.amount1_2" id="amount1_2" maxlength="20" cssClass="AutoSum_target1" />
     *       <n:error name="W99ZZ5.amount1_2" />
     *     </div>
     *     
     *     <div class="field">
     *       <label>金額1-3:</label>
     *       <n:text name="W99ZZ5.amount1_3" id="amount1_3" maxlength="20" cssClass="AutoSum_target1" />
     *       <n:error name="W99ZZ5.amount1_3" />
     *     </div>
     *     
     *     <div class="field">
     *       <label>合計1:</label>
     *       <span class="nablarch_AutoSum -target target1" id="autoSum1"><n:write name="W99ZZ5.totalAmount1" valueFormat="decimal{#,###.##}" /></span>
     *     </div>
     *     
     *     <div class="field">
     *       <label>金額2-1:</label>
     *       <n:text name="W99ZZ5.amount2_1" id="amount2_1" maxlength="20" cssClass="AutoSum_target2" />
     *       <n:error name="W99ZZ5.amount2_1" />
     *     </div>
     *     
     *     <div class="field">
     *       <label>金額2-2:</label>
     *       <n:text name="W99ZZ5.amount2_2" id="amount2_2" maxlength="20" cssClass="AutoSum_target2_negative" />
     *       <n:error name="W99ZZ5.amount2_2" />
     *     </div>
     *     
     *     <div class="field">
     *       <label>合計2:</label>
     *       <n:text id="autoSum2" cssClass="nablarch_AutoSum -target target2" name="W99ZZ5.totalAmount2" valueFormat="decimal{#,###.##}" disabled="true" />
     *     </div>
     *
     * @class nablarch.ui.AutoSum
     * @author Hisaaki Sioiri
     * @since  1.2
     */
    AutoSum.prototype = Object.merge(new Widget(), {
      /**
       * コンストラクタ。
       * @method AutoSum
       * @constructor
       * @param {Element} element       集計結果を出力するエリアのDOMノード
       * @param {Object} opt オプションを格納したオブジェクト  
       *   **target:** (`String`) 集計対象の入力フィールドのクラス名
       * @returns {AutoSum} インスタンス
       */
      constructor: AutoSum,
      /**
       * 加算対象の入力フィールド
       * @property $target
       * @type jQuery
       */
      $target:null,
      /**
       * 減算対象の入力フィールド
       * @property $negativeTarget
       * @type jQuery
       */
      $negativeTarget:null,
      /**
       * 集計結果を出力する要素
       * @property $element
       * @type jQuery
       */
      $element:null,
      /**
       * 集計処理を行う。
       *
       * 集計対象の要素から値を取得し、合計値をカンマ編集し出力する。
       *
       * @method sum
       * @param {jQuery.Event} event イベント(使用しない)
       */
      sum:AutoSum_sum
    });

    /**
     * イベント定義
     * 
     *     AutoSum.event = {
     *       "$target focusout":"sum",
     *       "$negativeTarget focusout":"sum"
     *       "$target nablarch_value_change" : "sum",
     *       "$negativeTarget nablarch_value_change":"sum"
     *     };
     *    
     * @property event
     * @type Object
     * @static
     * @final
     * 
     */
    AutoSum.event = {
      "$target focusout":"sum",
      "$negativeTarget focusout":"sum",
      "$target nablarch_value_change" : "sum",
      "$negativeTarget nablarch_value_change":"sum"
    };

    /**
     * ウィジェット識別子
     * 
     * @property widgetType
     * @type String
     * @static
     * @final
     * @default  "nablarch_AutoSum"
     */
    AutoSum.widgetType = "nablarch_AutoSum";
    
    Widget.register(AutoSum);
    
    function AutoSum(element, option) {
      if (!element) {
        return this;
      }
      this.$target = $(":input.AutoSum_" + option.target).not(":disabled:not(." + readonly.markerCss + ")");
      this.$negativeTarget = $(":input.AutoSum_" + option.target + "_negative").not(":disabled:not(."+readonly.markerCss+")");
      this.constructor = AutoSum;
      Widget.call(this, element);
      this.$element = $(element);

      // 自動集計対象が存在している場合、画面表示時に自動集計を行う。
      // (確認画面では、サーバサイドで計算した値を出力することを想定し、クライアントサイドでの集計は行わない。)
      if (this.$target.length !== 0) {
        this.sum();
      }
    }

    function AutoSum_sum(event) {
      var total = new BigDecimal(0);
      // 加算項目
      this.$target.each(function () {
        var $this = $(this),
          val;
        val = $this.val().trim() || '0';
        if (isNumber(val)) {
          total = total.add(new BigDecimal(val.toNumber()));
        } else {
          total = BigDecimal.NaN;
        }
      });
      // 減算項目
      this.$negativeTarget.each(function () {
        var $this = $(this),
          val;
        val = $this.val().trim() || '0';
        if (isNumber(val)) {
          total = total.subtract(new BigDecimal(val.toNumber()));
        } else {
          total = BigDecimal.NaN;
        }
      });
      if (this.$element.is('input')) {
        this.$element.val(total.toNumber().format());
      } else {
        this.$element.text(total.toNumber().format());
      }

      function isNumber(value) {
        return value.match(/^-?\d{1,3}(,?\d{3})*(\.\d*)?$/)
      }
    }

    return AutoSum;
  }
);