Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

PrimeFacesのDataTableを探る ~ チェックボックスによる複数選択 ~

久しぶりにDataTableネタです。一応、PrimeFacesのDataTableをシリーズモノにしてて過去のはこちらです↓

今日紹介するのは以下のような画面です。と先に具体的イメージから(^^;

サンプルで作った画面

DataTableの各行にチェックボックスが付きます

f:id:kikutaro777:20130501182845j:plain

複数選択できます

f:id:kikutaro777:20130501182907j:plain

ただしチェックボックスのカラムでクリックしないと駄目そうです(^^;
他のカラムで選択すると、その行だけ選択されます(他のは選択解除される)

ページをまたいで選択してもOK

上記の状態でページ番号3を選択して、そのままチェックを入れていきます。

f:id:kikutaro777:20130501183005j:plain

1ページ目の選択はそのままになっているはずです。次で確認してみます。

一覧表示件数を変えてみる

一覧表示件数が5件になっているので、15件にしてみます。

f:id:kikutaro777:20130501183028j:plain

1ページ目と3ページ目で選択したものがちゃんと選択状態のままです

カラムのチェックボックスで全選択

このDataTable定義を使うと、カラムがチェックボックスに自動でなります。
最初、何これ…と思うのですが、全選択・全解除の機能を持っています(^^;

f:id:kikutaro777:20130501183035j:plain

カラムのチェックボックスを外すと全解除されます

f:id:kikutaro777:20130501183041j:plain

業務系システムだと「わかりにくい」とか言われそうですが…(^^;

全選択はページ内のみに適用

1ページ目で全選択しても

f:id:kikutaro777:20130501183048j:plain

2ページ目は選択されません

f:id:kikutaro777:20130501183056j:plain

選択状態をプログラムで確認するためにボタン設ける

f:id:kikutaro777:20130501183228j:plain

最初に選択した状態(ページまたいでIDが2,4,11,13を選択)でデバッグモードにしてみてみると

f:id:kikutaro777:20130501183254j:plain

選択されたリストにちゃんと入ってます(^^)

実装

おそらくですが、自前でチェックボックスを設けても同等のことはできると思います。
ただ、PrimeFaces側で、このようなDataTableを作りやすくするためのデータモデルが設けられており、上記はより簡単に実装できます。

まず一覧に表示するためのデータ格納クラスを設けます。

  • JSFのListDataModelクラスを継承して
  • PrimeFacesのSelectableDataModelインタフェースを実装

するだけでOKです。

以下のような感じです。

package jp.co.hoge.selectable;

import java.util.List;
import javax.faces.model.ListDataModel;
import jp.co.hoge.entity.Book;
import org.primefaces.model.SelectableDataModel;

public class BookDataModel extends ListDataModel<Book> implements SelectableDataModel<Book>{
  
    public BookDataModel(List<Book> data){
        super(data);
    }
    
    @Override
    public Object getRowKey(Book book) {
        return book.getId();
    }

    @Override
    public Book getRowData(String rowKey) {
        List<Book> books = (List<Book>) getWrappedData();
        
        //ここではサンプルなのでベタにループして探索してます
        for(Book book : books){
            if(book.getId().equals(rowKey)){
                return book;
            }
        }
        return null;
    }
}

このクラスが定義できれば半分終わったようなもので、あとはBackingBeanで

package jp.co.hoge.bean;

import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import jp.co.hoge.db.BookFacade;
import jp.co.hoge.entity.Book;
import jp.co.hoge.selectable.BookDataModel;

@ManagedBean
@ViewScoped
public class SelectableBookBean {
    
    //一覧データ
    private BookDataModel booksModel;

    //チェックで選択されたBookリスト
    private List<Book> selectedBooks;

    //書籍データをDBから取得するためのEJB    
    @EJB
    BookFacade bookFacade;

    /**
     * コンストラクタ
     */
    @PostConstruct
    public void init(){
        //表示データ取得
        booksModel = new BookDataModel(bookFacade.findAll());
    }

    // setter, getterは省略
}

書籍リストをそのままBookDataModelに渡してしまいます。上記はエラー考えない雑な例ですが(^^;
あとは、一覧で選択された項目を覚えるためのリストを定義するだけ。

画面は以下のような定義です。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-

transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>PrimeFacesのDataTableチェックボックスでの複数選択</title>
    </h:head>
    <h:body>
        <h:form id="dtSelectableFrm">

            <!-- valueにモデルを指定し、selectionで選択されたリストを指定します -->
            <p:dataTable id="dtSelectable" var="book" 
        value="#{selectableBookBean.booksModel}" 
        sortMode="multiple" paginator="true" rows="5" 
        rowsPerPageTemplate="5,10,15"
                paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} 
          {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                pageLinks="5" 
        selection="#{selectableBookBean.selectedBooks}">

                <!-- チェックボックスを定義するのではなく、モード指定するのみ-->
                <!-- なお single と指定すればラジオボタンになります -->                
                <p:column selectionMode="multiple" />

        <!-- IDのカラム -->
                <p:column id="colId" headerText="ID">
                    <p:outputLabel value="#{book.id}" />
                </p:column>

                <!-- タイトルのカラム -->
                <p:column id="colTitle" headerText="タイトル">
                    <p:outputLabel value="#{book.title}" />
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>
</html>

結構簡単です!

ちなみに実際に色々触りたい方は以下のshowcaseでどうぞm(_ _)m
http://www.primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村