Salesforce の pageBlockTable のヘッダー行クリックでソートする方法
仕事で Salesforce を使ったシステムを開発していて
「一つの画面に複数の表を表示する」
という機能の実装時にハマったのでメモ。
ちなみに、以下は作りたかったの画面の例。
(一日の気温を、一時間毎の表・一日の平均の2つ表示してみたい)
2つの表は pageBlockTable でよいのだけれど、問題はソート機能。
Salesforce のオブジェクトのビューでは、表のヘッダー行クリックでソートができる。
ただし pageBlockTable を使った表には、その機能はない。
(同じことをやろうとすると、ソート機能を実装し直さなければいけないっぽい)
簡単に同様のことをやれないか、ググッてみると以下の記事を発見!!
要は、DataTables という jQuery のプラグインが良さげらしい。
Client-side sorting and pagination of an apex:pageBlockTable
これを基に、冒頭の例の画面を作ってみよう。
まずは、気温オブジェクトを作る。
次に、DataTables の Getting started を参考に、Visualforce page, component, Apex を作成。
「一つの画面に複数の表を表示する」
という機能の実装時にハマったのでメモ。
ちなみに、以下は作りたかったの画面の例。
(一日の気温を、一時間毎の表・一日の平均の2つ表示してみたい)
2つの表は pageBlockTable でよいのだけれど、問題はソート機能。
Salesforce のオブジェクトのビューでは、表のヘッダー行クリックでソートができる。
ただし pageBlockTable を使った表には、その機能はない。
(同じことをやろうとすると、ソート機能を実装し直さなければいけないっぽい)
簡単に同様のことをやれないか、ググッてみると以下の記事を発見!!
要は、DataTables という jQuery のプラグインが良さげらしい。
これを基に、冒頭の例の画面を作ってみよう。
まずは、気温オブジェクトを作る。
テストデータは、気象庁のページを元に、手入力でポチポチ入れる。
次に、DataTables の Getting started を参考に、Visualforce page, component, Apex を作成。
(VF page は VF component を呼び出すのみ)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<apex:component controller="TemperatureController"> | |
<apex:pageBlock ><h1>一時間毎の気温</h1> | |
<apex:pageBlockSection columns="1"> | |
<apex:pageBlockTable value="{!tempera_list_by_time}" var="t" styleClass="dataTable"> | |
<apex:column value="{!t.City__c}"/> | |
<apex:column value="{!t.DateTime__c}"/> | |
<apex:column value="{!t.Temperature__c}"/> | |
</apex:pageBlockTable> | |
</apex:pageBlockSection> | |
</apex:pageBlock> | |
<apex:pageBlock ><h1>一日の平均気温</h1> | |
<apex:pageBlockSection columns="1"> | |
<apex:pageBlockTable value="{!tempera_list_by_date}" var="t2" styleClass="dataTable2"> | |
<apex:column value="{!t2.City__c}"/> | |
<apex:column> | |
<apex:facet name="header">{!$ObjectType.Temperature__c.Fields['DateTime__c'].Label}</apex:facet> | |
<apex:outputText value="{0, date, yyyy'/'MM'/'dd}"> | |
<apex:param value="{!t2.DateTime__c}"/> | |
</apex:outputText> | |
</apex:column> | |
<apex:column value="{!t2.Temperature__c}"/> | |
</apex:pageBlockTable> | |
</apex:pageBlockSection> | |
</apex:pageBlock> | |
<link class="component" href="//cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css" /> | |
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> | |
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script> | |
<script type="text/javascript" language="javascript"> | |
var j$ = jQuery.noConflict(); | |
j$('table.dataTable').dataTable({ | |
sPaginationType: "full_numbers" | |
}); | |
j$('table.dataTable2').dataTable({ | |
sPaginationType: "full_numbers" | |
}); | |
</script> | |
</apex:component> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<apex:page tabStyle="Temperature__c"> | |
<c:temperature ></c:temperature> | |
</apex:page> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global with sharing class TemperatureController { | |
public List<Temperature__c> tempera_list_by_time {get; set;} | |
public List<Temperature__c> tempera_list_by_date {get; set;} | |
global TemperatureController() { | |
this.tempera_list_by_time = [SELECT City__c, DateTime__c, Temperature__c | |
FROM Temperature__c]; | |
DateTime dt = this.tempera_list_by_time[0].DateTime__c; | |
AggregateResult[] results = [SELECT City__c, AVG(Temperature__c) AVG_TEMPERA | |
FROM Temperature__c | |
GROUP BY City__c | |
]; | |
this.tempera_list_by_date = new List<Temperature__c>(); | |
for(AggregateResult result : results) { | |
Temperature__c temperature = new Temperature__c(); | |
temperature.City__c = (String)result.get('City__c'); | |
temperature.DateTime__c = dt.addHours(9); | |
temperature.Temperature__c = Integer.valueOf(result.get('AVG_TEMPERA')); | |
this.tempera_list_by_date.add(temperature); | |
} | |
} | |
} |
- ページング
- 検索
- ソート
機能を表に付けることができた。
気をつけなければいけないのは、このページング・検索・ソート機能は都度 SOQL をクエリするのではなく、初めに取得したレコードの表示順を変えているという点。
なぜかというと、SOQLは確かガバナ制限で5万件までしか結果を取得できなかったはず。
なので、例えば5万1件あるレコードに対して、表のヘッダー行クリックで ASC -> DESC のようにソートした時、5万件目のレコードが一番上に表示されることになってしまう。(本来、5万1件目が一番上に表示されてほしい)
まあ、直近5万件も一気に取得することはないと思う。。。
なので、これで十分という気がしている。
コメント
コメントを投稿