force.comでフォーム的な画面を作ることはよくあると思いますが
その際にapex:inputFieldとかでVFを組んでると、必須項目の制約とかメールアドレスの形式チェックとか
Salesforceのシステムバリデーションが効いてくれる上に
型に合わせてhtmlを生成してくれるから日付型とか使うときに便利だったりします。
が、apex:inputFieldでシステムが出すバリデーションは”エラー: 値を入力してください”
というように決められた文言でしか出すことができずエラーを出す位置も決まってしまうため
Salesforceのオペレータ側ではなく対顧客に対するフォームを作成するときには
デザイン・UI的にちょっと難が…。
そこでapex:messageというのを使ってみようと思ったけど、
色々と苦戦した挙句、挙動が?だったので、ちょっと書いてみる。
パターン1. apex:inputFieldのみ
検証用VFページ↓<apex:form>
<apex:inputField value="{!acc.Name}"/>
<apex:commandButton value="空送信"/>
</apex:form>
以下のように固定のエラーメッセージが出る。
このメッセージを自由に変更して、自由な位置に出力したい!というのが今回の趣旨。
パターン2. apex:inputField + apex:message/
では実際にmessageタグを使ってみる。検証用VF↓
<apex:form>
<apex:inputField id="Field" value="{!acc.Name}"/>
<apex:message for="Field"/>
<apex:commandButton value="空送信"/>
</apex:form>
こうすると、inputFieldタグが出すエラーメッセージと
messageタグが出すエラーメッセージで2重に出力されちゃう。
パターン3. apex:inputField + apex:message/ + commandButtonのimmediate
SalesforceのSystemバリデーションを走らせないで送信したらどうなるかを検証。<apex:form >
<apex:inputField id="Field" value="{!acc.Name}"/>
<apex:message for="Field"/>
<apex:commandButton immediate="true" value="空送信" />
</apex:form>
結果、commandButtonのactionで何もしていないせいか何も出力されず…。
パターン4. apex:inputField + + immediate + action指定
実際にアクションでインサートしてエラーをキャッチしてページにエラーメッセージを出してみる。
検証用VF↓
<apex:form >
<apex:pageMessages />
<apex:inputField id="Field" value="{!acc.Name}"/>
<apex:message for="Field"/>
<apex:commandButton immediate="true" value="インサート" action="{!testMessage}"/>
</apex:form>
検証用Apexクラス↓
public class TestStudy {
public Account acc {get; set;}
public PageReference testMessage() {
try {
insert acc;
} catch (Exception ex) {
acc.addError(ex);
ApexPages.addMessages(ex);
}
return null;
}
}
inputField, messageタグの方にはエラーメッセージは表示されず。
addError(ex)とaddMessages(ex)の2つのエラーメッセージが出力されているように見えるけど
DML Exceptionが発生した時点でSalesforceが自動的に
ApexPages.addMessages(ex)をやっているっぽく、addMessages消しても同じ出力結果に。
パターン5. apex:inputField + + immediate + action指定2
項目に直接addErrorしてみる。
検証用VF↓
<apex:form >
<apex:inputField id="Field" value="{!acc.Name}"/>
<apex:message for="Field"/>
<apex:commandButton immediate="true" value="インサート" action="{!testMessage}"/>
</apex:form>
検証用クラス↓
public class TestStudy {
public Account acc {get; set;}
public PageReference testMessage() {
try {
insert acc;
} catch (Exception ex) {
acc.Name.addError(ex);
}
return null;
}
}
お、うまくいってる!と、思いきや、生成されたhtmlタグをよく見てみると…。
inputFieldのエラーメッセージは出力されているけど、
messageの方にはエラーメッセージが出力されてないorz
ということで、apex:messageの利用方法がよくわからないっす…。
apex:inputTextには使えないみたいだし。
対顧客用のフォーム画面を作成する場合には、エラーメッセージ用のプロパティを用意した方が懸命かもしれないっす。
”自前でやった方が早いし確実”っていうのはforce.comにはよくあることです!!w