Accountレコードのページングクエリ、ページにジャンプを実現したいと思います。
ページングクエリ:データベースから取得したレコードの数によって、実際のページング処理します。
ページにジャンプ:好きなページをジャンプできるということです。例えば、3ページに行きたい、3を入れって、GoToボタンを押下すると、3ページに行きました。
以下の通りです。
ボタン:First、Previous、Next、Last、GoTo
ジャンプボックス:Jump to page
最終的な画面イメージ
ページ1:First、Previousクリックできない。
「Next」をクリックする
「Last」をクリックする、Next、Lastクリックできない。
「Previous」をクリックする
Jump to page: 3を入力する、GoToボタンを押下し、3ページに行きますね。
もし、Jump to page: 数字以外を入力したら、どうなっているのか?
最初的にJavaScriptで制限いたします、もう一回GoToボタンを押下すると、Apexで制限いたします。(すべてApexで制限もできる)
例えば、「zchao」を入力する場合、見てみましょう!
確定ボタンを押下し、直接、もう一回GoToボタン
Visualforce1.vfp
<apex:page controller="Apex1" showHeader="false" docType="html-5.0">
<script>
function doDeleteJs(accid) {
if (window.confirm("削除してよろしいでしょうか。")) {
doDeleteFn(accid);
}
}
function doEditJs(accid) {
var uuu="./EditAccountList_PAGE?core.apexpages.request.devconsole=1&Id="+accid;
window.location.href =uuu;
}
function isNumber(num){
if(isNaN(num)){
//alert(num);
//alert(isNaN('we')); //true
//alert(isNaN(123)); //false
alert("数字を入力してください!");
return;
}
}
</script>
<style type="text/css">
/* footer右へ表示*/
.footer{
text-align: right;
}
</style>
<apex:sectionHeader subtitle="Account表示一覧" title="Account"/>
<!-- <apex:include pageName="NewAccountList_PAGE"/> -->
<!-- <apex:include pageName="AddAccountPage"/> -->
<apex:form id="formId2">
<apex:pageMessages id="message2"/>
<apex:pageBlock title="Add Account">
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}" reRender="pageBlockTable,ttttt,formId2" />
<apex:commandButton value="Cancel" action="{!cancel}" reRender="pageBlockTable,formId2,pb2" />
</apex:pageBlockButtons>
<apex:pageBlockSection title="Account Details" columns="1" id="pb2">
<apex:inputField value="{!act.name}" />
<apex:inputField value="{!act.Type}"/>
<apex:inputField value="{!act.Industry}"/>
<apex:inputField value="{!act.Phone}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
<apex:form id="formId">
<apex:pageMessages id="message"/>
<apex:actionFunction name="doDeleteFn" action="{!doDelete}" reRender="formId" >
<apex:param name="id" value="" />
</apex:actionFunction>
<apex:pageBlock >
<apex:outputText value="検索条件: " > </apex:outputText>
<br/><br/>
<apex:inputText value="{!strCondName}" id="in">取引先名:</apex:inputText>
<apex:inputText value="{!strCondType}" id="ou">種別:</apex:inputText>
<br/> <br/>
<apex:commandButton value="曖昧検索" action="{!search}" reRender="formId,in,qqq,ppp,ooo,ou"/>
<apex:commandButton value="精確検索" action="{!exactSearch}" reRender="formId,in,qqq,ppp,ooo,ou"/>
<apex:commandButton value="クリア" action="{!clear}" reRender="formId,in,qqq,ppp,ooo,ou" />
</apex:pageBlock>
<apex:pageBlock title="検索結果(共{!count_size}レコード)" rendered="{!resultFlag}" id="qqq">
<apex:pageblockTable value="{!accResult}" var="a" id="ppp">
<apex:column value="{!a.Name}" />
<apex:column value="{!a.Type}" />
<apex:column value="{!a.Industry}" />
<apex:column value="{!a.Phone}" />
</apex:pageblockTable>
</apex:pageBlock>
<apex:pageBlock >
<apex:pageBlockButtons location="bottom" style="text-align: center;">
<!-- ボタン表示 -->
<apex:outputPanel id="buttons">
<apex:commandButton action="{!First}" title="First" value="First" disabled="{!disablePrevious}" reRender="formId,message,showpanel,buttons,pageBlockTable,foo"/>
<apex:commandButton action="{!Previous}" title="Previous" value="Previous" disabled="{!disablePrevious}" reRender="formId,message,showpanel,buttons,pageBlockTable,foo"/>
<apex:commandButton action="{!Next}" title="Next" value="Next" disabled="{!disableNext}" reRender="formId,message,showpanel,buttons,pageBlockTable,foo"/>
<apex:commandButton action="{!End}" title="End" value="Last" disabled="{!disableNext}" reRender="formId,message,showpanel,buttons,pageBlockTable,foo"/>
<apex:inputText value="{!gotoPage}" id="goto" onchange="isNumber(value)" size="3" >Jump to page:</apex:inputText>
<apex:commandButton action="{!gotoPage}" title="GoTo" value="GoTo" reRender="formId,message,showpanel,buttons,pageBlockTable,foo,"/>
</apex:outputPanel>
</apex:pageBlockButtons>
<apex:outputPanel id="showpanel">
<apex:pageBlockTable value="{!accounts}" var="acc" footerClass="footer" id="pageBlockTable">
<apex:column headerValue="Action" width="70px">
<apex:commandLink value="" onclick="doEditJs('{!acc.Id}');" style="color:#015ba7;" id="edit" reRender="formId,message,showpanel,buttons,pageBlockTable,foo">
Edit
</apex:commandLink>
|
<apex:commandLink value="" onclick="doDeleteJs('{!acc.Id}');" style="color:#015ba7;" id="del" reRender="formId,message,showpanel,buttons,pageBlockTable,foo">
Del
</apex:commandLink>
</apex:column>
<apex:column headerValue="取引先名" >
<apex:outputlink value="https://ap2.salesforce.com/{!acc.id}" target="_blank" >{!acc.Name}</apex:outputlink>
</apex:column>
<apex:column value="{!acc.Type}" />
<apex:column value="{!acc.Industry}" />
<apex:column value="{!acc.Phone}" />
<apex:facet name="footer">{!pageNumber}/{!totalPages}ページ 共{!total_size}レコード</apex:facet>
</apex:pageBlockTable>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>
説明:
①<apex:commandButton action=”{!First}” title=”First” value=”First” disabled=”{!disablePrevious}” reRender=”formId,message,showpanel,buttons,pageBlockTable,foo”/>、ほかボタンと同じです。
action=”{!First}”:Apexの「First」メソッドを呼び出し。
disabled=”{!disablePrevious}”:この<apex:commandButton>、クリックできるかどうか制限できる。True:クリックできない。False:クリックできる。
https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_commandButton.htm
reRender=”formId,message,showpanel,buttons,pageBlockTable,foo”:リフレッシュしたいところです。
②<apex:inputText value=”{!gotoPage}” id=”goto” onchange=”isNumber(value)” size=”3″ >Jump to page:</apex:inputText>
onchange=”isNumber(value)”:入力したValueをJSのisNumberメソッドに渡して、数字かどうか確認できます。
<apex:inputText>を変わる場合があれば、onchange=”isNumber(value)”を呼び出します。
③function isNumber(num){
if(isNaN(num)){
//alert(num);
//alert(isNaN(‘we’)); //true
//alert(isNaN(123)); //false
alert(“数字を入力してください!”);
return;
}
②value=”{!gotoPage}”の値を取得し、isNaN(num)、数字の場合return false、数字以外場合return true。
④<apex:commandButton action=”{!gotoPage}” title=”GoTo” value=”GoTo” reRender=”formId,message,showpanel,buttons,pageBlockTable,foo,”/>
action=”{!gotoPage}”:Apexの「gotoPage」メソッドを呼び出し。
⑤<apex:facet name=”footer”>{!pageNumber}/{!totalPages}ページ 共{!total_size}レコード</apex:facet>
pageNumber:現在のページ番号を計算する、ApexのgetPageNumber()の値を表示されること。
accounts = [select Name,Type,Industry,phone from Account limit :LIST_SIZE offset :counter ];
pageNumber=counter/LIST_SIZE + 1;
accounts = [select Name,Type,Industry,phone from Account limit :10 offset :10 ];
10/10+1 = 2, 11~20 第二页
20/10+1 = 3, 21~30 第三页
25/10+1 = 3, 26~36 第三页(25/10=2)
totalPages:総ページ数を計算する、ApexのgetTotalPages()の値を表示されること。
if (math.mod(total_size, LIST_SIZE ) > 0) {
return total_size/LIST_SIZE + 1;
} else {
return (total_size/LIST_SIZE ) ;
}
Math クラス:
total_size:Accountレコードの数ですね。下で説明します。
Apex1.apxc
public with sharing class Apex1 {
public List<Account> accounts; //Account情報
public Account act{get;set;} //新規Account情報用
public list<Account> accResult {get;set;} //検索結果
public string strCondName {get;set;} //検索取引先名
public string strCondType {get;set;} //検索種別
public boolean resultFlag {get;set;} //検索結果表示フラグ
//ページングパラメータ
public Integer counter=0; //オフセット(偏移量)
public static Integer LIST_SIZE = 10; //ページあたりのレコード数を表示
public Integer total_size; //レコードの総数
public String gotoPage {get;set;} //ページにジャンプ
//ページにジャンプ メソッド
public PageReference gotoPage() {
try{
//gotoPageを入力しない場合
if(gotoPage==null || gotoPage == '' || String.isBlank(gotoPage)){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '値を入力してください。'));
return null;
}
// 0<gotoPage<=ページの総数
if(0<integer.valueOf(gotoPage) && integer.valueOf(gotoPage)<=(getTotalPages())){
//跳转的页面 主要通过偏移量来决定 跳转的页面的记录为每页第一个记录即可
//比如总共 55个Account记录,每页10个,分为5页
//第一页 1~10, 偏移量offset:0 (1-1)*10 (gotoPage)-1)*LIST_SIZE
//第二页 11~20, 偏移量offset:10 (2-1)*10 (gotoPage)-1)*LIST_SIZE
//第三页 21~30, 偏移量offset:20 (3-1)*10 (gotoPage)-1)*LIST_SIZE
//第四页 31~40, 偏移量offset:30 (4-1)*10 (gotoPage)-1)*LIST_SIZE
//第五页 41~50, 偏移量offset:40 (5-1)*10 (gotoPage)-1)*LIST_SIZE
//第六页 51~55, 偏移量offset:50 (6-1)*10 (gotoPage)-1)*LIST_SIZE
counter=(integer.valueOf(gotoPage)-1)*LIST_SIZE;
//if(0<gotoPage && gotoPage<=(getTotalPages())){
//counter=(gotoPage-1)*LIST_SIZE;
return null;
}else {
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '適切な値の範囲を入力してください。(0< Page <='+getTotalPages()+')'));
return null;
}
}catch(Exception e) {
ApexPages.addMessages(e);
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '数字を入力してください!'));
return null;
}
}
public Integer count_size; //検索レコードの総数
//画面に検索レコードの総数を返す
public Integer getCount_size() {
return count_size;
}
//コンストラクター
public Apex1() {
act = new Account(); //デフォルト New Accountオブジェクト
resultFlag = false; //デフォルト 検索結果一覧非表示
total_size = [select count() from Account];
gotoPage=null;
}
//変数 accounts のgetメソッド
public List<Account> getAccounts() {
try {
// limit :10 offset :5 11~15
// limit :10 offset :10 11~20
// limit :10 offset :20 11~30
// limit :20 offset :5 21~25
accounts= [select Id,Name,Type,Industry,phone from Account order by createddate desc limit :LIST_SIZE offset :counter];// limit x,y
return accounts;
} catch (Exception e) {
ApexPages.addMessages(e);
return null;
}
}
//精確検索
public void exactSearch(){
List<Account> exactSearchSOQL;
exactSearchSOQL = [select name,id,Type,Industry,phone from Account where name=:strCondName and type=:strCondType limit 100];
//入力した取引先名と種別との条件 判断 空でない && サイズ2を超える
if(!String.isBlank(strCondName) && !String.isBlank(strCondType) && strCondName.length()>=2 && strCondType.length()>=2){
if(exactSearchSOQL.size()!=0 ){
//検索結果一覧表示
resultFlag = true;
accResult = exactSearchSOQL;
//検索レコードの総数を取得
count_size = [select count() from Account where name like:strCondName and type like:strCondType limit 100];
}else {
//system.debug('123=='+exactSearchSOQL);
//検索するレコード存在しない
resultFlag = false;
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
}
} else{
//system.debug('yyyyy='+strCondName);
//一つ空の場合
if(String.isBlank(strCondName)|| String.isBlank(strCondType) ){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '【取引先名】と【種別】を入力してください !'));
return;
}
//一つサイズ 2を超えない場合、および データベースと同じレコード名
if(strCondName.length()<2 || strCondType.length()<2){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索語には【取引先名】と【種別 】各2 文字以上を指定する必要があります!'));
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件は完全に等しい【取引先名】と等しい【種別】を入力してください!'));
}
}
}
//曖昧検索
public void search(){
// flag = false;
//String strCondName2 = ApexPages.currentPage().getParameters().get('strCondName');
//system.debug('99999='+strCondName);
//if(strCondName!=null || !strCondName.equals('') || strCondName!=''){
//system.debug('qqqqq='+strCondName);
//sql injection 1' or '1' = '1';-- %
//string searchQuery='select name,id,Type,Industry,phone from Account where name like \'%'+strCondName+'%\' Limit 100';
//strCondName = strCondName;
List<Account> searchSOQL;
//曖昧検索 定義
String searchName ='%'+strCondName+'%';
String searchType ='%'+strCondType+'%';
// String searchName2 = ''+ strCondName+ '';
searchSOQL = [select name,id,Type,Industry,phone from Account where name like:searchName and type like:searchType limit 100];
//system.debug('232323==='+searchSOQL);
//考えるプロセス
//String soql = 'select name,id,Type,Industry,phone from Account where name like \'%%\' Limit 100';
//SQLインジェクション=SQL Injection 対策
//String soql = 'select name,id,Type,Industry,phone from Account where name like'+'\''+ string.escapeSingleQuotes('%'+strCondName+'%')+'\'';
//system.debug('aaaaa='+soql);
//system.debug('bbbbb='+strCondName);
//system.debug(strCondName.containsAny('%'));
//system.debug('length==='+strCondName.length());
//入力した取引先名と種別との条件 判断 空でない && %を含まない && サイズ2を超える
if((!String.isBlank(strCondName) && !strCondName.containsAny('%') && strCondName.length()>=2) && (!String.isBlank(strCondType) && !strCondType.containsAny('%')&& strCondType.length()>=2)){
//if(searchQuery!=soql){
//system.debug('6666='+strCondName);
//if(Database.query(soql).size()!=0){
if(searchSOQL.size()!=0){
//検索結果一覧表示
resultFlag = true;
accResult = searchSOQL;
//検索レコードの総数を取得
count_size = [select count() from Account where name like:searchName and type like:searchType limit 100];
}else {
//flag = true;
resultFlag = false;
//error = 'no found data';
//system.debug('3343434==='+sq.size());
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
//system.debug('flag'+flag);
}
}else{
//system.debug('yyyyy='+strCondName);
//不満足条件な検索 メッセージ提示
if(String.isBlank(strCondName) || String.isBlank(strCondType)){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '【取引先名】と【種別】を入力してください !'));
return;
}
else if(strCondName.containsAny('%') || strCondType.containsAny('%')){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '「%」以外のキーワードを入力してください !'));
return;
}
else if(strCondName.length()==1 || strCondType.length()==1){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索語【取引先名】か【種別】には 2 文字以上を指定する必要があります!'));
return;
}
else{
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
return;
}
}
}
//検索したレコードをクリア
public void clear(){
//検索結果一覧非表示
resultFlag = false;
//system.debug('111='+prds);
if(accResult!=null){
// system.debug('222='+prds);
//レコードをクリア
accResult.clear();
//入力欄もクリア
strCondName = '';
strCondType = '';
}else{
strCondName = '';
strCondType = '';
// error = '';
}
}
//キャンセル操作、何もない、画面をリフレッシュ
public PageReference cancel() {
return null;
}
//保存ボタン押下する、呼び出しメソッド
public PageReference save() {
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO, '保存しました。'));
//system.debug('act name:' + act.name + ' = ' + act.accountNumber);
upsert act;
return null;
}
//Account削除メソッド
public void doDelete() {
SavePoint sp = Database.setSavepoint(); //トランザクションの制御
try {
String sfid = ApexPages.currentPage().getParameters().get('id'); //Visualforce1.vfpからのidを取得
List<Account> deleteList= [select Id from Account where Id=:sfid]; //データベースと合わせて
if (deleteList.size() == 0) {
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, 'すでに削除されました。'));
} else {
delete deleteList;
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO, '削除しました。'));
accounts = [select Name,Type,Industry,phone from Account limit :LIST_SIZE offset :counter]; //レコード更新
}
} catch(exception ex) {
system.debug('Error:'+ex.getMessage());
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, ex.getMessage()));
Database.rollback(sp); //savepoint の生成時点と同じ状況にデータベースを復元
}
}
//変数 DisablePrevious のgetメソッド
//前のページのボタンがクリック可能かどうかを制御
public Boolean getDisablePrevious() {
if (counter>0)
return false;
else
return true;
}
//変数 DisableNext のgetメソッド
//次のページのボタンがクリック可能かどうかを制御
public Boolean getDisableNext() {
if (counter + LIST_SIZE < total_size)
return false;
else
return true;
}
//変数 Total_size のgetメソッド
//Total_sizeの値を返す
public Integer getTotal_size() {
return total_size;
}
//変数 PageNumber のgetメソッド
//現在のページ番号を計算する
public Integer getPageNumber() {
return counter/LIST_SIZE + 1;
}
//変数 TotalPages のgetメソッド
//総ページ数を計算する
public Integer getTotalPages() {
if (math.mod(total_size, LIST_SIZE ) > 0) {
return total_size/LIST_SIZE + 1;
} else {
return (total_size/LIST_SIZE ) ;
}
//Integer t=total_size/LIST_SIZE;
//return math.ceil(t);
}
//Firstページ
public PageReference First() {
counter = 0;
return null;
}
//前ページ
public PageReference Previous() {
counter -= LIST_SIZE ;
return null;
}
//次ページ
public PageReference Next() {
counter += LIST_SIZE ;
return null;
}
//Lastページ
public PageReference End() {
//counter = total_size - math.mod(total_size, LIST_SIZE );
//Integer xx=total_size-LIST_SIZE;isDivisibility(xx,10)
if(math.mod(total_size-LIST_SIZE,LIST_SIZE)==0){
//system.debug('UUUUUU='+(total_size-LIST_SIZE)/10);
counter = total_size-LIST_SIZE;
return null;
}
//************************************
//10,20,30 总条数s 每页显示x 偏移量y 最后一页 y=(s-x) //
// 20条数据,每页显示10条,最后一页的偏移量为20-10=10, 11~20 //
// 30条数据,每页显示10条,最后一页的偏移量为30-10=20, 21~30 //
//12,15,18,22,25 总条数s 每页显示x 偏移量y 最后一页 y=(s-mod(s,x)) //
// 35条数据,每页显示10条,最后一页的偏移量为35-mod(35/10)=30,31~35 //
// 38条数据,每页显示10条,最后一页的偏移量为38-mod(38/10)=30,31~38 //
// 42条数据,每页显示10条,最后一页的偏移量为42-mod(42/10)=40,41~42 //
//************************************
else{
//system.debug('MMMMM='+(total_size-LIST_SIZE)/10);
counter = total_size - math.mod(total_size, LIST_SIZE );
return null;
}
}
}
説明:
写真通りです。
この三つの変数は一番重要なんですね。理解するのは、問題ありません。
counter:オフセット(offset)(偏移量)という名前、毎回実際レコードの数ですが、SOQLのlimitと一緒に使います。
accounts = [select Name,Type,Industry,phone from Account limit :LIST_SIZE offset :counter];
LIST_SIZE = 10; ページあたり10レコードを表示されること、例えば、offset :counter、counter=10、
accounts = [select Name,Type,Industry,phone from Account limit :10 offset :10];
取得したレコード:11~20。
total_size:コンストラクターのなかに、total_size = [select count() from Account];
AccountのレコードIDがいくつあれば、count() はいくつ返します。
②First():
counter = 0; 10
③Previous():
counter -= LIST_SIZE ; 10-10
④Next():
counter += LIST_SIZE ; 10+10
⑤End():分为能被偏移量整除和不能被偏移量整除两种情况
⑥gotoPage():也是通过偏移量控制。
以上となります。
何か問題がございましたら、コメントを頂れば幸せです。
Latest posts by zchao (see all)
- Auraでアクションボタン作成して画面のチェックボックス項目一括処理 - 2021年4月12日
- デフォルト項目値を含むレコード作成実例説明(defaultFieldValues) - 2021年1月9日
- Salesforce のノーコード・ローコード開発 - 2020年12月31日
转载请注明:zchao博客之家 » Apex+VisualforceでAccountオブジェクトのCRUDとページングクエリーページングクエリ、ページにジャンプ(007)