LoginSignup
3
3

More than 3 years have passed since last update.

Visualforceで(jQuery、Bootstrap)modalでちょっとしたリッチなUIを実現(いまさら感)

Last updated at Posted at 2016-09-05

概要

 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">&times;</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全体が再描画の対象にならないように前後のコードを確認することで思わぬ穴にハマらずに済みます

以上

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3