概要
Visualforceの標準コンポーネント(<apex:inputfield>など)を使って、Apexコントローラとのデータバインドをお任せしつつ、インターフェイスだけをリッチにする。下記のサンプルはBootstrapになっていますが、jquery uiやLightning Design Systemでも同様な実装が可能
コード
ポイント
- bootstrapのcssがきちんと適用できるようにstandardStylesheetsはfalseにしています
standardStylesheetsをfalseにできない場合は、bootstrap.cssのセレクターの詳細度をあげる
例)lessやSassでbootstrap.cssのすべてのセレクターの先頭に.user-contentsを付与する.user-contents { @import (less) url("bootstrap.css"); }
- standardStylesheetsをfalseにできない場合は、bootstrap.cssにprefixを適用してあげましょう
- 標準コンポーネントのstyleClass属性にcssフレームワーク用識別子を付与することで、標準コンポーネントも見栄え良くなる
- visualforceとcontrollerのデータバインディングは標準コンポーネントでしているため、別途実装は不要(手間いらず)
- modalの保存後に「取引先リスト」と「modal」の再描画(reRender)することで、ページ遷移が発生しない
(保存後にmodalが自動で閉じる処理は入れてない)
text.vfp
<apex:page controller="TestPageController" standardStylesheets="false" showHeader="false">
<!-- 各種css/jsの読み込み -->
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"/>
<!-- modal表示ボタン -->
<input type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#newAccountModal" value="新規取引先"/>
<!-- データ確認用のリスト -->
<apex:pageBlock id="accountList" title="取引先リスト">
<apex:pageBlockTable value="{!accs}" var="acc" styleClass="table table-striped">
<apex:column value="{!acc.name}"/>
<apex:column value="{!acc.Site}"/>
<apex:column value="{!acc.Phone}"/>
<apex:column value="{!acc.Fax}"/>
</apex:pageBlockTable>
</apex:pageBlock>
<!-- modal本体 -->
<div class="modal fade" id="newAccountModal" tabindex="-1" role="dialog">
<apex:form id="addNewAccount">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">新規取引先</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="newAccountName">取引先名</label>
<apex:inputField value="{!newAcc.name}" styleClass="form-control"/>
</div>
<div class="form-group">
<label for="newAccountUrl">URL</label>
<apex:inputField value="{!newAcc.Site}" styleClass="form-control"/>
</div>
<div class="form-group">
<label for="newAccountName">電話</label>
<apex:inputField value="{!newAcc.Phone}" styleClass="form-control"/>
</div>
<div class="form-group">
<label for="newAccountName">Fax</label>
<apex:inputField value="{!newAcc.Fax}" styleClass="form-control"/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">キャンセル</button>
<apex:commandButton action="{!saveNewAcc}" reRender="accountList, addNewAccount" value="保存" styleClass="btn btn-primary" id="saveNewAcc"/>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</apex:form>
</div><!-- /.modal -->
</apex:page>
TestPageController.apxc
public with sharing class TestPageController{
//確認用のリスト表示用
public List<Account> accs {
get{
//リスト用
this.accs = [Select Id, Name, Site, Phone, Fax from Account Order by CreatedDate desc Limit 10];
return this.accs;
}
set;
}
//新規Account用
public Account newAcc {
get {
if(this.newAcc == null) {
this.newAcc = new Account();
}
return this.newAcc;
}
set;
}
//保存ボタン
public void saveNewAcc() {
insert this.newAcc;
this.newAcc = new Account();
}
}
ちょっとしたハマりポイント
今回のサンプルではmodalで保存処理後にmodal自身の再描画を行っていますが、タグ構成が以下のようになっていると思わぬ動きします
text.vfp
<!-- 正しい -->
<div class="modal fade" id="newAccountModal" tabindex="-1" role="dialog">
<apex:form id="addNewAccount">
↓
<!-- 誤り -->
<apex:form id="addNewAccount">
<div class="modal fade" id="newAccountModal" tabindex="-1" role="dialog">
modalで保存後modal 内 の表示要素(<apex:form id="addNewAccount">)を再描画したいが、上記の誤りのコードのようにmodal全体が再描画対象となり、modalが消える現象が発生します
なので、modal全体が再描画の対象にならないように前後のコードを確認することで思わぬ穴にハマらずに済みます
以上