lift-mapperのpaginateを使う

liftでページネートする方法。Lift-Wikiを補足する形ですが、snippetで繰り返す箇所/繰り返さない箇所が混在する場合の対処方法を紹介します。

[Lift-Wiki]Example: Paginating Mapper-based snippets with sortable headers

ソートヘッダー付のPaginateをサクッと作れるのですが、上記サンプルが中途半端なので補完してみます。

バージョンはLift1.1-M7です。まだAPI変わる可能性あるので、その辺りは注意してください。

■View

<lift:surround with="default" at="content">
<lift:userView.list>

 <nav:records/> <br/>
 <nav:first/> <nav:prev/> <nav:allpages> | </nav:allpages> <nav:next/> <nav:last/>

 <table>
  <tr>
   <th><sort:id><lift:loc>ID</lift:loc></sort:id></th>
   <th><sort:email><lift:loc>mail</lift:loc></sort:email></th>
   <th><sort:nickname><lift:loc>ニックネーム</lift:loc></sort:nickname></th>
  </tr>
  <f:users>
  <tr>
   <td><f:id /></td>
   <td><f:email /></td>
   <td><f:nickname /></td>
  </tr>
  </f:users>
 </table>

</lift:userView.list>
</lift:surround>

名前空間のnav/sortは決まっている値。

ポイントは、繰り返し表示する箇所(user行)を<f:items /> <f:users />で括っているところ。

■Snippet

import net.liftweb.mapper.view._

class UserView extends ModelSnippet[User] {

 //必須でoverride
 override val view = new ModelView( User, this )
 override def edit(xhtml: NodeSeq):NodeSeq = <h1>Edit</h1>

 val paginator =
 new Paginator(User, this, User.id,//初期ソートカラム
 "id" -> User.id, "email" -> User.email, "nickname" -> User.nickname )

 def list(xhtml: NodeSeq):NodeSeq = {

  //行繰り返し用のテンプレート<f:users></f:users>を切り出しておく
  val innerTemplate = ( xhtml \\ "users" first ).descendant(1)

  bind("f",
   paginator.paginate(xhtml), //xhtmlを->pagenate用テンプレートに変換
   "users" -> bindUsers(innerTemplate) //f:usersをrender
  )
 }

 private def bindUsers(xhtml: NodeSeq):NodeSeq = {
  paginator.page.flatMap( user => {
   bind("f", xhtml,
    "id" -> Text( user.id.toString ),
    "email" -> Text( user.email ),
    "nickname" -> Text( user.nickname ) )
  })
 }
}

snippet内で、繰り返す/繰り返さない箇所が混在するときは、ViewにしるしをつけてSnippet内で分解してやる。・・というのは自分はよく使ってる方法ですが、他にうまい方法ご存知の方はぜひ教えてください。


Paginatorにクエリを指定するには、

 Paginator#constantParams

ページの表示件数を指定するには、

 Paginator#num

に値を入れます。mapper.view.Paginatorのソースはとてもシンプルなので、継承して"流れるような"インターフェースにしたりも十分できそう。

さすがにRailsのpaginateほど美しくはないですが、満足です。


同じカテゴリのエントリ
1.Lift再入門 / 8.javascriptからsubmitできない / 7.Ajax Form / 6.Radio、Checkboxについて / 5.行列型の編集FORM / 4.サーバーサイドバリデーションとサーバサイド関数 / 3.ログインFORM - S.param使ったら負け / 2.Snippetメソッドとして許される型 / sbt0.12.xで依存jar抽出タスク / scala2.10+lift2.5+NetBeans7.2 / Scalaで入門関数プログラミング / reactive-webを試してみました / Lift2.2M1のテンプレート機能 / Scala Compiler Plugin / View Bound/Context Bound / ScalaZa01参加してきました / Akka Frameworkチュートリアルの次 / Akka Frameworkチュートリアルその2 / Akka Frameworkチュートリアル / LiftでJCaptcha / Url Rewrite Filter / sbt-android-plugin / Android SDK for Scala / 祝Lift2.0リリース / Liftの携帯対応まとめ / Scala2.8への移行 / Lift 2.0-scala280-SNAPSHOT/sbt0.7.1 / Scalaお絵かき環境 - Kojo / Lift+Quartzでバッチ / Scala&Liftを採用した理由 / Liftでdate_select系ヘルパーを作る / LiftでAjax / LiftのSubmitかしこい / lift-mapperのpaginateを使う / snippetをspecする / Lift Mapperを拡張する / LiftのDBをMySQLに / Liftプロジェクト環境を整える / Scala本読み比べてみました / NetBeans6.7&scala / じつはScalaはライトな言語 / Scalaバザ~ル / lift1.0所感 / specsを読む / implicit def / ScalaならNetBeansがサイコー / scala勉強会@東北がスタート / それでも俺はLiftをやるってのか / Scala&Liftセットアップ / ブログリニューアル /
コメント
ymnk
2009/12/08
わかり易い解説ありがとうございます。
一点だけ...

> ポイントは、繰り返し表示する箇所(user行)を
> <f:items />で括っているところ。

例にあわせるとすると、<f:items /> は <f:users />
のような気がしますが、どうでしょうか?

武田ソフト
2009/12/08
ご指摘ありがとうございますっ、修正しました。

コメントしてください

closed.