Visualforceのレコード保存処理時、標準バリデーションエラーを回避して任意のactionを実行させる
19257 ワード
目的・目標
- Visualforceのページメッセージを処理ごとに毎回クリアしたい
- 確認画面、完了画面のないVisualforceページで編集画面のみで
apex:pageMessages
を利用して視覚的に更新が完了・エラーした事を伝えたい
- 処理実行前にVisualforce画面の
apex:pageMessages
をクリアして任意の処理後に再度、完了・エラーを表示させたい
Before(保存1の処理)
Visualforceコード
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="保存1" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
動作画面
apex:pageMessages
を利用して視覚的に更新が完了・エラーした事を伝えたいapex:pageMessages
をクリアして任意の処理後に再度、完了・エラーを表示させたいVisualforceコード
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="保存1" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
動作画面
- 保存ボタンを押下したときロード画面が表示されているだけで更新されたのが認識しづらい
Try(保存2の処理)
Visualforceコード
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1B" action="{!clearVfMsg}" oncomplete="return false;" reRender="container" />
<apex:commandButton value="保存2" onclick="save1B();" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
動作画面
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1B" action="{!clearVfMsg}" oncomplete="return false;" reRender="container" />
<apex:commandButton value="保存2" onclick="save1B();" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
改善
-
immediate="true"
をapex:actionFunction
につけることで保存ボタン押下時にデータ型、桁数(Salesforce標準)、必須項目(Salesforce標準)のバリデーションエラーが発生した場合にメッセージクリア処理が実行されないことを回避しました
問題
- メッセージクリア前にロード画面が入ってしまう
- ボタンを連打すると
apex:pageMessages
がバグで表示されない場合がある(キャプション 4回目の保存ボタン押下時)
After(保存3の処理)
Visualforceコード
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1C" action="{!clearVfMsg}" oncomplete="save2C();" reRender="container" immediate="true"/>
<apex:actionFunction name="save2C" action="{!save}" reRender="container" status="spinnerStatus"/>
<apex:commandButton value="保存3" onclick="save1C(); return false;"/>
</apex:pageBlockButtons>
動作画面
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1C" action="{!clearVfMsg}" oncomplete="save2C();" reRender="container" immediate="true"/>
<apex:actionFunction name="save2C" action="{!save}" reRender="container" status="spinnerStatus"/>
<apex:commandButton value="保存3" onclick="save1C(); return false;"/>
</apex:pageBlockButtons>
改善
- メッセージクリア後にロード画面が表示される
- ボタンを連打しても
apex:pageMessages
にバグが発生しない
学習したこと
-
immediate="true"
をapex:actionFunction
につけることで保存ボタン押下時にデータ型、桁数(Salesforce標準)、必須項目(Salesforce標準)のバリデーションエラーが発生する場合でも任意の処理を先に実行させる事ができる
-
apex:actionFunction
のoncomplete
を利用して処理をメソッドチェーンさせることができる
- メソッドチェーンさせることで任意の処理でロード画面などを実行させることができる
サンプルコード
Visualforceページ
<apex:page controller="VfTestCtrl" title="取引先責任者 編集" lightningStylesheets="true">
<style>
.spinnerBg{
width: 100%;
height: 100%;
position: absolute;
background-color: #000;
opacity: 0.2;
z-index: 999999;
}
.spinner{
width: 100%;
height: 100%;
position: absolute;
background-image: url("/img/loading32.gif");
background-size: 16px;
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
z-index: 9999999;
opacity: 1;
}
</style>
<apex:actionStatus id="spinnerStatus">
<apex:facet name="start">
<div class="spinnerBg"/>
<div class="spinner"/>
</apex:facet>
</apex:actionStatus>
<apex:form>
<apex:outputPanel id="container">
<apex:pageBlock title="取引先責任者 編集">
<div style="min-height: 120px">
<apex:pageMessages/>
</div>
<apex:pageBlockSection columns="1">
<apex:inputField value="{!con.TestNum__c}"/>
</apex:pageBlockSection>
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="保存1" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1B" action="{!clearVfMsg}" oncomplete="return false;" reRender="container" />
<apex:commandButton value="保存2" onclick="save1B();" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1C" action="{!clearVfMsg}" oncomplete="save2C();" reRender="container" immediate="true"/>
<apex:actionFunction name="save2C" action="{!save}" reRender="container" status="spinnerStatus"/>
<apex:commandButton value="保存3" onclick="save1C(); return false;"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:outputPanel>
</apex:form>
</apex:page>
VFコントローラ
public without sharing class VfTestCtrl {
public Contact con { get; set; }
private Id conId;
/** 画面表示メッセージ */
private static final String CONTACT_NOT_EXIST_MSG = '取引先責任者が存在しません。';
private static final String CONTACT_UPDATE_COMPLETE_MSG = '取引先責任者の更新が完了しました。';
public VfTestCtrl() {
this.conId = ApexPages.currentPage().getParameters().get('Id');
List<Contact> conList = queryContact(conId);
if (conList.isEmpty()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, CONTACT_NOT_EXIST_MSG));
return;
}
this.con = conList[0];
}
/** VFメッセージクリア処理 */
public void clearVfMsg() {
ApexPages.getMessages().clear();
}
/** 保存処理 */
public void save() {
List<Contact> conList = queryContact(conId);
if (conList.isEmpty()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, CONTACT_NOT_EXIST_MSG));
return;
}
update con;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, CONTACT_UPDATE_COMPLETE_MSG));
return;
}
/** 対象の取引先責任者を取得 */
private List<Contact> queryContact(Id contactId) {
return [
SELECT
Id,
TestNum__c
FROM
Contact
WHERE
Id = :contactId
];
}
}
immediate="true"
をapex:actionFunction
につけることで保存ボタン押下時にデータ型、桁数(Salesforce標準)、必須項目(Salesforce標準)のバリデーションエラーが発生する場合でも任意の処理を先に実行させる事ができる
apex:actionFunction
のoncomplete
を利用して処理をメソッドチェーンさせることができるVisualforceページ
<apex:page controller="VfTestCtrl" title="取引先責任者 編集" lightningStylesheets="true">
<style>
.spinnerBg{
width: 100%;
height: 100%;
position: absolute;
background-color: #000;
opacity: 0.2;
z-index: 999999;
}
.spinner{
width: 100%;
height: 100%;
position: absolute;
background-image: url("/img/loading32.gif");
background-size: 16px;
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
z-index: 9999999;
opacity: 1;
}
</style>
<apex:actionStatus id="spinnerStatus">
<apex:facet name="start">
<div class="spinnerBg"/>
<div class="spinner"/>
</apex:facet>
</apex:actionStatus>
<apex:form>
<apex:outputPanel id="container">
<apex:pageBlock title="取引先責任者 編集">
<div style="min-height: 120px">
<apex:pageMessages/>
</div>
<apex:pageBlockSection columns="1">
<apex:inputField value="{!con.TestNum__c}"/>
</apex:pageBlockSection>
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="保存1" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1B" action="{!clearVfMsg}" oncomplete="return false;" reRender="container" />
<apex:commandButton value="保存2" onclick="save1B();" action="{!save}" reRender="container" status="spinnerStatus"/>
</apex:pageBlockButtons>
<apex:pageBlockButtons location="bottom">
<apex:actionFunction name="save1C" action="{!clearVfMsg}" oncomplete="save2C();" reRender="container" immediate="true"/>
<apex:actionFunction name="save2C" action="{!save}" reRender="container" status="spinnerStatus"/>
<apex:commandButton value="保存3" onclick="save1C(); return false;"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:outputPanel>
</apex:form>
</apex:page>
VFコントローラ
public without sharing class VfTestCtrl {
public Contact con { get; set; }
private Id conId;
/** 画面表示メッセージ */
private static final String CONTACT_NOT_EXIST_MSG = '取引先責任者が存在しません。';
private static final String CONTACT_UPDATE_COMPLETE_MSG = '取引先責任者の更新が完了しました。';
public VfTestCtrl() {
this.conId = ApexPages.currentPage().getParameters().get('Id');
List<Contact> conList = queryContact(conId);
if (conList.isEmpty()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, CONTACT_NOT_EXIST_MSG));
return;
}
this.con = conList[0];
}
/** VFメッセージクリア処理 */
public void clearVfMsg() {
ApexPages.getMessages().clear();
}
/** 保存処理 */
public void save() {
List<Contact> conList = queryContact(conId);
if (conList.isEmpty()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, CONTACT_NOT_EXIST_MSG));
return;
}
update con;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, CONTACT_UPDATE_COMPLETE_MSG));
return;
}
/** 対象の取引先責任者を取得 */
private List<Contact> queryContact(Id contactId) {
return [
SELECT
Id,
TestNum__c
FROM
Contact
WHERE
Id = :contactId
];
}
}
Author And Source
この問題について(Visualforceのレコード保存処理時、標準バリデーションエラーを回避して任意のactionを実行させる), 我々は、より多くの情報をここで見つけました https://qiita.com/okei93/items/80a3e198162bd63878eb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .