[Visualforce] 必須チェックのエラー文言をカスタマイズする

前記事の続きで、apex:inputField を使わない場合のバリデーションエラーの表示方法を調べたメモ。
結局標準の表示では対応してくれないようなので、自前で実装することになった。

前回までで作成した状態はこちら。

1
2
3
4
5
6
7
8
9
<apex:pageBlockSectionItem >
  <apex:outputLabel value="都道府県" for="prefcbx"/>
  <apex:outputPanel styleClass="requiredInput" layout="block">
      <apex:outputPanel styleClass="requiredBlock" layout="block"/>
      <apex:selectList value="{!pref__c}" id="prefcbx" size="1" required="true">
          <apex:selectOptions value="{!options}"/>
      </apex:selectList>
  </apex:outputPanel>
</apex:pageBlockSectionItem>

apex:message

このまま空で送信しても内部的にはエラーとなり送信出来ないのだが、エラーの内容が表示されない。
そこで、<apex:message>を追加するとエラーは出るようになった。

1
<apex:message for="prefcbx" styleClass="errorMsg" />

表示は以下。

問題点は以下。

  • エラー文言が英語
  • 選択リストのボックスがエラー表示になってない(赤枠がない)

required=true

この英語のエラーをローカライズして表示させる方法がわからなかった。(langオプションを設定しても違うようだった)
なので、apex内で指定したエラー文言を表示させてやることに。

<apex:inputField>タグなどに、required=trueをつけると必須のチェックを自動で行ってくれるようになるのだが、このチェックはformactionで指定したメソッドなどの送信処理が走る前にチェックがされてしまうよう。
そのため、入力が空だった場合にはこのエラー文言を表示する、などカスタマイズしようにもすることが出来なかった。

よって、requiredを外してやる。
そうすると、必須のエラーも自分で検知してやらないといけなくなる。

1
2
3
if(String.isBlank(pref__c)){
  //必須エラー
}

そしてrequired=trueを外してしまうと、必須の赤い線がapex:inputFieldタグで表示されなくなってしまうため、全ての項目の必須表示を自前で実装してやる必要がある。

addError()

ちなみに、sObjectにaddError()メソッドでエラーを追加してやると追加した文言がエラーとして表示されるようになる。
ただしこれも上記required=trueが入っているとapexの処理が通らないため、requiredオプションは外しておく。

1
pref__c.addError('入力して下さい。');

上記のように追加すると、以下のように表示がされる。

エラー: 入力して下さい。

apex:outputText

よって、普通のテキスト表示である、apex:outputTextを利用してエラーの有無で出し分けをしてやる。
さらに、選択リストの部分には、errorクラスをつけてやることでエラー表示の赤枠を出してやることが出来るため、エラー時のみ、クラスをerrorとしてやることにする。

1
2
3
4
5
6
7
8
9
public String errorMessage{get;set;}
public String errorClass{get;set;}

public PageReference save(){
  if(String.isBlank(town.addr1_1name__c)){
      errorMessage = '都道府県を入力して下さい';
      errorClass = 'error';
  }
}

これでようやく以下のように目的通りの表示が出来た。

結果

最終的に標準と全く同じように必須のエラーを表示してやるように調整した場合、以下のようになった。

apex

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
public with sharing class CusotmSelectList_Sample {
  public CustomObject__c object{get;set;}
  public String errorMessage{get;set;}
  public String errorClass{get;set;}
  
  public CusotmSelectList_Sample(ApexPages.StandardController controller) {
      object = new CustomObject__c();
  }
  
  /**
   * カスタム設定から都道府県のリストを取得する
   * @type List<SelectOption>
   */
  public List<SelectOption> getOptions() {
    Map<String, Prefectures__c> prefs = Prefectures__c.getAll();
    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption('', '--なし--'));
    for(String key : prefs.keySet()){
        Prefectures__c pref_obj = prefs.get(key);
        options.add(new SelectOption(pref_obj.Label__c, pref_obj.Label__c));
    }
    return options;
  }
  
  public PageReference save(){
      if(String.isBlank(object.pref__c)){
          errorMessage = '<strong>エラー:</strong> 値を入力してください';
          errorClass = 'error';
          return null;
      }
      
      insert object; //エラーがなければ保存
      return null; //完了画面とかに遷移させる
  }
}

VF Page

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
<apex:page showHeader="true" sidebar="true" title="作成" standardController="CustomObject__c" extensions="CusotmSelectList_Sample">
  <apex:sectionHeader title="レコードの作成" />
  <apex:form>
      <apex:pageBlock title="" mode="edit">
      
          <apex:pageBlockButtons>
              <apex:commandButton action="{!save}" value="保存"/>
          </apex:pageBlockButtons>
          
          <apex:pageBlockSection title="内容" columns="1">
              <apex:pageBlockSectionItem >
              <apex:outputLabel value="都道府県" for="prefcbx"/>
              <apex:outputPanel styleClass="requiredInput" layout="block">
                  <apex:outputPanel styleClass="requiredBlock" layout="block"/>
                  <apex:selectList value="{!object.pref__c}" id="prefcbx" size="1" styleClass="{!errorClass}">
                  <apex:selectOptions value="{!options}"/>
                  </apex:selectList>
                      <br />
                      <apex:outputText value="{!errorMessage}" styleClass="errorMsg" rendered="{!LEN(errorMessage)>0}" escape="false"/>
              </apex:outputPanel>
              </apex:pageBlockSectionItem>
          </apex:pageBlockSection>
      
      </apex:pageBlock>
  </apex:form>
</apex:page>

結果

とりあえずこれで一つの項目で、必須表示〜エラー表示まで実装してやることが出来た。
ただし、複数項目で実現するためには項目の数だけエラー表示用の変数が必要になるため、クラスにするなど何かしら工夫しないとコードが冗長になりそう。
また、バリデーション用のコードもヘルパークラスに分けるなどした方がよいかもしれない。

参考

   このエントリーをはてなブックマークに追加