intra-mart Accel Platform UIデザインガイドライン(PC版) 第6版 2022-12-01

6.6. 国際化情報入力項目

本章では、国際化入力について、記載します。

6.6.1. 国際化情報の入力・登録・更新について

ここでは入力・登録・更新する場合の国際化情報についてを説明します。
intra-mart Accel Platform でもこの処理例を利用しています。

6.6.1.1. 入力項目の表示に関して

6.6.1.1.1. 国際化入力項目の仕様

  • 国際化入力項目が必須入力の場合、標準表示名 とシステムにインストールしているロケール分の入力項目を用意します。
例: 日本語ロケール、英語ロケールに対応する場合
標準表示名、日本語、英語の 3 つの入力項目が表示されます。

  • 項目の表示順
  • 標準表示名、テナントのデフォルトロケール、その他のロケールの順番に表示します。
  • テナントのデフォルトロケール以外の並び順は、 SystemLocale#getLocaleInfos() が返した順になります。
  • テナントのデフォルトロケールが設定されていない場合は、システムデフォルトのロケールになります。
  • 標準表示名 を必須項目とします。
  • 各ロケールは、任意入力項目とします。
  • 各ロケールが未入力の場合、標準表示名が、有効になります。

6.6.1.1.2. 入力項目が、「全て必須」 かつ 「項目数が少ない」場合

  • 標準表示名とシステムにインストールしているロケール分、入力項目をすべて表示します。
  • デフォルトロケール以外の言語ロケールを、あらかじめ隠しておくなどの処理は、一切しません。

6.6.1.1.3. 入力項目が、「一部必須」、または 「項目数が多い」 場合

標準表示名のみ表示し、サーバ側のロジックで各ロケールに何を登録するか決定します。

コラム

国際化情報の対応を行う場合は、表示する文字列をプロパティファイルで管理します。 入力項目と同様に、標準表示名とロケール毎に管理します。 詳細は、 スクリプト開発モデル プログラミングガイド多言語対応 を参照してください。

6.6.1.2. 画面からの入力、および、登録・更新処理に関して

  • 国際化入力項目が必須入力の場合、 標準表示名は必須入力各ロケールは任意入力 とします。
    任意入力の項目に何も入力されなかった場合は、標準表示名の項目値と同じ値が入力されたものとみなします。
  • 登録・更新時、任意項目が未入力の場合、標準表示名より該当する項目の内容をコピーします。
  • コピー処理は、サーバサイド JavaScript 側で行います。
    API 内部でコピーは、行ってはなりません。
  • 任意入力の国際化入力項目値を補完は、サーバサイド JavaScript 側で行います。

6.6.1.3. バリデーションチェック

  • 国際化入力項目等、動的に変化する項目に関しては、 クライアントサイド JavaScript とサーバサイド JavaScript で独自チェックします。
    それ以外の固定的な項目は、通常どおり JS Validation を利用したチェックをします。

6.6.1.4. 実装例

international

6.6.1.4.1. validator.js ( サーバサイド JavaScript )

  • バリデーションルールを記述します。
  • 国際化入力項目は required = true に設定しておきます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var init = {
    dataId : {
        caption: MessageManager.getMessage("CAP.UI.DEFAULT.LABEL"),
        required: true,
        maxlength: 256
    },
    dataName : {
        caption: MessageManager.getMessage("CAP.UI.FACILITY.CATEGORY.NAME"),
        maxlength: 256
    }
};

6.6.1.4.2. page.js(サーバサイド JavaScript )

テナントデフォルト言語、または、システムデフォルト言語が上に来るように調整します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var $result = {};

function init(request) {
    getLocaleInfo($result);
}

function getLocaleInfo(obj) {
    var tenantInfoManager = new TenantInfoManager();
    obj.defaultLocaleId = tenantInfoManager.getTenantInfo(true).data.locale;
    if (isBlank(obj.defaultLocaleId)) {
        obj.defaultLocaleId = SystemLocale.getDefaultLocaleInfo().data.locale;
    }
    obj.locales = [];
    var localeInfos = SystemLocale.getLocaleInfos().data;
    for (var i = 0; i < localeInfos.length; i++) {
        if (obj.defaultLocaleId == localeInfos[i].locale) obj.locales.push({
            id:localeInfos[i].locale,
            name:localeInfos[i].displayName
        });
    }
    for (var i = 0; i < localeInfos.length; i++) {
        if (obj.defaultLocaleId != localeInfos[i].locale) obj.locales.push({
            id:localeInfos[i].locale,
            name:localeInfos[i].displayName
        });
    }
}

6.6.1.4.3. page.html (クライアントサイド JavaScript、HTML)

バリデーションルール、メッセージの読み込みと動的バリデーションの設定をします。
サーバ側に国際化項目を送る場合は、ベースとなる値(デフォルト言語)と、全言語分を個別で送ります。
これにより、デフォルト言語の必須と長さを自動でチェックできます。
<imart type="head">
  <script src="ui/libs/jquery-validation-1.9.0/jquery.validate.js"></script>
  <imart type="imuiValidationRule" rule="sample/validator#init" rulesName="validateRules" messagesName="validateMessages" />

  <script type="text/javascript">
    jQuery(function() {
      // 生成されたテキストボックスに name 属性を付与します
      jQuery("#input_form [name=dataNames] input").each(function() {
        var newName = "dataName_" + jQuery(this).attr("locale");
        var caption = jQuery(this).parent().prev().text();
        jQuery(this).attr("name", newName);
        // 付与した name 属性に対するバリデーションを追加します
        validateRules[newName] = {caption:caption,__caption__:caption,maxlength: 256};
      });

      jQuery("#submit-button").click(function() {
        // クライアントサイドのバリデーションチェックを行います
        if (imuiValidate("#input_form", validateRules, validateMessages)) {
          var names = {};
          jQuery("#input_form [name=dataNames] input").each(function() {
            names[jQuery(this).attr("locale")] = jQuery(this).val();
          });

          jQuery.ajax({
            type: "POST",
            url: "sample/ajax",
            dataType: "json",
            data: {
              dataId: jQuery("#input_form [name=dataId]").val(),
              dataName: jQuery("#input_form [name=dataNames] input:first").val(),
              dataNames: ImJson.toJSONString(names)
            },
            success: function(result) {
              if (result.error) {
                imuiShowErrorMessage(result.errorMessage, result.detailMessages);
                return;
              } else {
                imuiShowSuccessMessage(result.successMessage);
              }
            },
            error: function(request, textStatus, errorThrown) {
              imuiShowErrorMessage(request.statusText + "(" + request.status + ")", "");
            }
          });
        }
      });
    });
  </script>

</imart>

<form id="input_form" onsubmit="return false;" class="imui-form-container">
  <table class="imui-form">
    <tbody>
      <tr>
        <th class="wd-20"><label><imart type="message" id="CAP.UI.FACILITY.CATEGORY.NAME" escapeXml="true" escapeJs="false" /></label></th>
        <td>
          <table class="imui-form" >
            <tbody>
              <tr>
                <th class="wd-20"><label class="imui-required" data-locale="<imart type="string" value=$bind.defaultLocaleId escapeXml="true" escapeJs="false" />"><imart type="message" id="CAP.UI.DEFAULT.LABEL" escapeXml="true" escapeJs="false" /></label></th>
                <td><imart type="imuiTextbox" name="dataId" style="width: 400px;"/></td>
              </tr>
              <tr>
                <td colspan="2"><imart type="message" id="CAP.UI.DESCRIPTION.LOCALE.SETTING" escapeXml="true" escapeJs="false" /></td>
              </tr>
            </tbody>
          </table>
          <table class="imui-form" name="dataNames">
            <tbody>
              <imart type="repeat" list=$result.locales item="record">
                <tr>
                  <th class="wd-20"><label><imart type="string" value=record.name /></label></th>
                  <td><imart type="imuiTextbox" locale=record.id style="width: 400px;" /></td>
                </tr>
              </imart>
            </tbody>
          </table>
        </td>
      </tr>
    </tbody>
  </table>
  <div class="imui-operation-parts">
    <imart type="imuiButton" id="submit-button" value="%CAP.UI.ACT.REGISTRATION" class="imui-large-button" />
  </div>
</form>

6.6.1.4.4. ajax.js (サーバサイド JavaScript )

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
 * @param request
 * @validate sample/validator#init
 * @onerror handleErrors
 */
function init(request) {
    // 国際化項目のみ追加チェック(必須チェック済なので長さチェックのみ)
    var dataNames = isBlank(request.dataNames) ? {} : ImJson.parseJSON(request.dataNames);
    for (var localeId in dataNames) {
        var dataName = dataNames[localeId];
        var result = {};
            if (isString(dataName) && dataName.length > 256) {
            // バリデーションエラー
            result = {
                error: true,
                successMessage: "",
                errorMessage: MessageManager.getMessage('MSG.E.IWP.ASYNC.TASKQUE.ADD.SERIESQUEUE.INPUT'),
                detailMessages: MessageManager.getMessage("MSG.W.IWP.JSSP.VALIDATION.MAXLENGTH", MessageManager.getMessage("CAP.UI.FACILITY.CATEGORY.NAME"), "256")
            };
            sendJSONString(result, result.errorMessage, result.detailMessages);
            return;
        }
    }
    result.error = false;
    sendJSONString(result, MessageManager.getMessage('CAP.UI.SUCCESS.MESSAGE'));
}

function handleErrors(request, validationErrors) {
    let result = {
        error: true,
        successMessage: '',
        errorMessage: MessageManager.getMessage('MSG.E.IWP.ASYNC.TASKQUE.ADD.SERIESQUEUE.INPUT'),
        detailMessages: validationErrors.getMessages()
    };
    sendJSONString(result, result.errorMessage, result.detailMessages);
}

function sendJSONString(result, message, detailMessages) {
    message = (message == null) ? '' : message;
    detailMessages = (detailMessages == null) ? '' : detailMessages;

    var response = Web.getHTTPResponse();
    response.setContentType('application/json; charset=utf-8');
    response.sendMessageBodyString(ImJson.toJSONString({
        error: result.error,
        successMessage: result.error ? '' : message,
        errorMessage: result.error ? message : '',
        detailMessages: result.error ? detailMessages : ''
    }));
}