+ Start a Discussion
k_ogawak_ogawa 

エラーメッセージについて

いつもお世話になっております。


apex:inputtextの項目下にエラーメッセージを表示させたいのですが、何か良い方法はありますか?
また、必須項目には項目横に赤い縦線を表示したいです。

ご存知の方がいらっしゃいましたら、ご連絡お待ちしております。

Best Answer chosen by k_ogawa
Shingo YamazakiShingo Yamazaki
inputtextで調べていたところ、次のような記事を見つけました。

https://developer.salesforce.com/forums/ForumsMain?id=906F000000096SiIAI

Visualforce

<apex:outputLabel value="Postcode"></apex:outputLabel>
<apex:inputText styleClass="{!classInputPostalCode}" value="{!postalCode}"/>
<apex:outputText value="{!errorMessage}" styleClass="errorMsg" rendered="{!LEN(errorMessage)>0}"/>

A (https://developer.salesforce.com/forums/ForumsMain?id=906F000000096SiIAI)pex
public String classInputPostalCode {get;set;}
public String postalCode {get;set;}
public String errorMessage {get;set;}

public void validate() {
  // ここに処理が入る。エラーの場合、error = trueにしておく
  if (error) {
    classInputPostalCode = 'error';  // put the errorclass, red borders
    errorMessage = 'Postal code not found';
  } else {
    classInputPostalCode = '';
    errorMessage = '';
  }
}

リンク先には明記されていませんでしたが、おそらく処理の最中にエラーと判断された場合
Boolean型の変数errorをtrueにしておき、
1. <inputText>のstyleClassに"error"を指定
2. errorMessageに何かしら文字列をセットすると、エラーメッセージ表示用の<outputText>のrenderedがtrueとなって表示される
という処理が実行されるようです。
赤い縦線は表示できているとのことですので、エラーメッセージはこちらが参考になるかもしれません。

また、DatePickerの件は、いただいたコードでこちらでうまく表示することができず
原因がまだわかっておりません。すみません。

と、ここまで書いて改めて思ったのですが、
ダミーのSObjectの日付項目を使ってinputFieldを定義する、というのが一番簡単な方法なのかもしれません。

「ダミーのSObject」は上のコメントでいうMyObj__cに相当するもので、
処理に直接は関係しませんが表示に必要なので便宜的に用意するものです。
(DatePickerを使いたいのであれば、MyObj__c.dummyDate__cのような日付項目を用意すればいいかと)

ただ、ページに関係のないカスタムオブジェクトが存在するのも少し違和感があるので
その場合はなんとか自前で実装するしかなさそうですね。。。

All Answers

Shingo YamazakiShingo Yamazaki
k_ogawaさん

こんにちは。
山﨑と申します。

表示させたいエラーは入力規則でも実装可能なものでしょうか?
その場合、入力規則のオプションで項目横に表示する設定にしていれば
自作したVisualforceページでも正しい箇所にエラーが表示されるかと思います。

ただし、入力規則エラーを自分でハンドリングする必要がありますのでご注意ください。
実装に関しての具体的な方法についてはこちらを参照いただければ。

http://dackdive.hateblo.jp/entry/2014/08/31/100000

k_ogawak_ogawa
山﨑 様
いつもお世話になっております。

エラーを表示させたい画面は、入力規則では実装できなさそうでした。
このような場合、どのように設定すればよろしいのでしょうか?

Shingo YamazakiShingo Yamazaki
それでは、SObject.field.addErrorを使う方法ではいかがでしょう。
以下、簡単なサンプルです。

Apex
public class CustomErrorController {
    
    public MyObj__c obj {get; set;}
    
    public CustomErrorController() {
        this.obj = new MyObj__c();
    }
    
    
    public PageReference validate() {
        this.obj.text__c.addError('これはエラーメッセージです');
        return null;
    }
}


Visualforce
<apex:page controller="CustomErrorController">
    <apex:form>
        <apex:pageBlock title="My Content" mode="edit">
            <apex:pageBlockButtons>
                <apex:commandButton action="{!validate}" value="validate"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="My Content Section" columns="2">
                <apex:inputField value="{!obj.text__c}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

サンプルでは、「validate」ボタンを押した時に実行されるvalidate()メソッド内で
[SObject].[フィールド].addError([エラーメッセージ])
というメソッドを使っています。

ボタンの実行結果はこのようになります。

User-added image

k_ogawak_ogawa
出力イメージはまさにこれです!

ただ、的外れなことを言うかもしれないのですが、
public MyObj__c obj {get; set;}
上記の部分に関してですが、オブジェクトを設定していない(表現が正しいかわからないのですが)為、
GetSetするオブジェクトがないのですが、その場合はどのようにすればよいのでしょうか?


赤い縦線に関しては以下のように実装できました。

<apex:pageBlockSectionItem >
<apex:outputLabel value="開始日"/>
<apex:outputPanel >
<div class="requiredInput">
<div class="requiredBlock"></div>
<apex:inputtext id="startDate" value="{!startdatetext}" label="開始日" required="true" size="12"
  onfocus="javascript:DatePicker.pickDate(true, '{!$Component.startDate}', false)" />
</div>
</apex:outputPanel>
</apex:pageBlockSectionItem>
<apex:outputLink value="javascript:DatePicker.insertDate('{!startDate}', '{!$Component.startDate}', true);" style="position: relative; left: 300px; top: -24px;">
  {!startDate}
</apex:outputLink>

しかし、新たな問題が生まれてしまいました。
apex:outputLinkの部分をクリックしてもpex:inputtextに値が入らなくなってしまいました。
恐らくjavascript:DatePickerの部分が動作していないのかな?とも思うのですが、原因がわかりません。
もしよろしければ添削をお願いできないでしょうか?

いろいろお願いしてしまいすみません。
Shingo YamazakiShingo Yamazaki
k_ogawaさん

すみません、<apex:inputField>と見間違えておりました。。。
おっしゃる通り、特定のSObjectを対象としたページでなく
通常のinputTextを使う場合はご提案した方法では無理そうですね。

DatePickerの問題につきましては、開発者コンソールを見る限り
javascriptのエラーが発生しているようです。
こちら、正常に動いていた時のコードはございますでしょうか?
そことの差分から何か原因がわかるかもしれません。
k_ogawak_ogawa
あ、やはりそうなのですね!
inputTextを使うとなるとやはりメッセージを出すのは難しいのでしょうか?

赤線の部分に関して、正常時のコードは以下になります。

<apex:inputtext id="startDate" value="{!startdatetext}" label="開始日" required="true" size="12"
 onfocus="javascript:DatePicker.pickDate(true, '{!$Component.startDate}', false)" />
<apex:outputLink value="javascript:DatePicker.insertDate('{!startDate}', '{!$Component.startDate}', true);" style="position: relative; left: 18px; top: 0px;">
 {!startDate}
</apex:outputLink>

以下の部分を</apex:outputLink>まで含めることで動くには動いたのですが、原因がわかりません。。。
</div>
</apex:outputPanel>
</apex:pageBlockSectionItem>
Shingo YamazakiShingo Yamazaki
inputtextで調べていたところ、次のような記事を見つけました。

https://developer.salesforce.com/forums/ForumsMain?id=906F000000096SiIAI

Visualforce

<apex:outputLabel value="Postcode"></apex:outputLabel>
<apex:inputText styleClass="{!classInputPostalCode}" value="{!postalCode}"/>
<apex:outputText value="{!errorMessage}" styleClass="errorMsg" rendered="{!LEN(errorMessage)>0}"/>

A (https://developer.salesforce.com/forums/ForumsMain?id=906F000000096SiIAI)pex
public String classInputPostalCode {get;set;}
public String postalCode {get;set;}
public String errorMessage {get;set;}

public void validate() {
  // ここに処理が入る。エラーの場合、error = trueにしておく
  if (error) {
    classInputPostalCode = 'error';  // put the errorclass, red borders
    errorMessage = 'Postal code not found';
  } else {
    classInputPostalCode = '';
    errorMessage = '';
  }
}

リンク先には明記されていませんでしたが、おそらく処理の最中にエラーと判断された場合
Boolean型の変数errorをtrueにしておき、
1. <inputText>のstyleClassに"error"を指定
2. errorMessageに何かしら文字列をセットすると、エラーメッセージ表示用の<outputText>のrenderedがtrueとなって表示される
という処理が実行されるようです。
赤い縦線は表示できているとのことですので、エラーメッセージはこちらが参考になるかもしれません。

また、DatePickerの件は、いただいたコードでこちらでうまく表示することができず
原因がまだわかっておりません。すみません。

と、ここまで書いて改めて思ったのですが、
ダミーのSObjectの日付項目を使ってinputFieldを定義する、というのが一番簡単な方法なのかもしれません。

「ダミーのSObject」は上のコメントでいうMyObj__cに相当するもので、
処理に直接は関係しませんが表示に必要なので便宜的に用意するものです。
(DatePickerを使いたいのであれば、MyObj__c.dummyDate__cのような日付項目を用意すればいいかと)

ただ、ページに関係のないカスタムオブジェクトが存在するのも少し違和感があるので
その場合はなんとか自前で実装するしかなさそうですね。。。
This was selected as the best answer
k_ogawak_ogawa
頂いたサンプルを実装してみたところ動きました!
本来でしたら、自分で探さなければならないところを記事まで探して頂き本当にありがとうございます。

DataPickerの件については
apex側で、

// 変数
private string StartDate {get; set;}
private Date StartDateText {get; set;}

public BrandInsertController (ApexPages.StandardController controller) {
    this.StartDate = Datetime.now().format('yyyy/MM/dd', 'JST');
}

/** 開始日 */
public void setStartDate(string d){
this.StartDate = d;
}
public string getStartDate(){
return this.StartDate;
}

public void setStartDateText(Date d){
    this.StartDateText = d;
}
public Date getStartDateText(){
    return this.StartDateText;
}


このようにコーディングしているのですが、お役に立ちますでしょうか?
また、なぜかページ更新されると日付が「Thu Sep 11 00:00:00 GMT 2014」
のようになってしまいます。


「ダミーのSObject」に関してなのですが、
本当に初心者の質問で申し訳ないのですが、
ダミーのSObjectはapex上で設定するものなのでしょうか?
それともsalseforceの設定画面から新規オブジェクトを作成するのでしょうか?

質問だらけで申し訳ありません。。。
Shingo YamazakiShingo Yamazaki
DatePickerの件、追加の情報ありがとうございます!
手元の環境で確認してみます。

また、「ダミーのSObject」については、
おっしゃる通りSalesforceの設定画面から新規オブジェクトを作成します。
そのため、不要なオブジェクトが増えるのに抵抗のある方にはおすすめできない方法ですね。。。

また、inputFieldにDate型として表示させることができさえすれば良いことを考えると、
カスタムオブジェクトとして別にしなくとも標準SObjectの項目でなんとかなるとも思います。
(むしろ、誤って削除することがないのでこちらのほうがいいのかも...)

http://blog.enxoo.com/en/2013/03/native-datepicker-calendar-pop-up-for-inputtext-on-your-visualforce-page/

上記のサイトではContact.BirthDate(取引先責任者の「誕生日」項目)を使ってますね。


k_ogawak_ogawa
お時間のあるときに是非ご確認よろしくお願いいたします。

頂いたサイト拝見しました。
こんなに簡単にできるのですね。。。

ダミーのSObjectの使い方を知らないだけで複雑な方法をとっていたような気がします。
勉強になります。

Shingo YamazakiShingo Yamazaki
ですよね。私もこのような使い方は知りませんでした。

当初の質問内容に関しまして、他にお困りの点はございますでしょうか?
解決されたようでしたら、ベストアンサーを選択の上本件クローズしていただけますと幸いです。
k_ogawak_ogawa
山﨑 様

エラー内容に関しましてはクリアできましたので、クローズとさせて頂きます。
いつもお時間を割いていただき、本当にありがとうございます。

今後ともどうぞよろしくお願い致します。