DateSelect
import _root_.net.liftweb.http._
import _root_.net.liftweb.util._
import _root_.net.liftweb.common._
import _root_.scala.xml._
import _root_.java.text.SimpleDateFormat
import _root_.java.util.{Date,Calendar,GregorianCalendar}
import _root_.java.lang.Integer.parseInt //メソッド毎importできる
object DateSelect {
def apply(vars: AnyVar[String,_],name:String) = new DateSelect(vars,name)
val dummyYMD = "1970/01/01"
private val formatterYMD = new SimpleDateFormat("yyyy/MM/dd")
def parseYMD(ymd:String):Date
= synchronized{ formatterYMD.parse(ymd) }
def formatYMD(date:Date):String
= synchronized{ formatterYMD.format(date) }
def YMD2Calendar(ymd:String) = {
val cal = new GregorianCalendar
cal.setTime(DateSelect.parseYMD(ymd))
cal
}
def splitYMD(ymd:String):(String,String,String) = {
val cal = YMD2Calendar(ymd)
val y = cal.get(Calendar.YEAR).toString
val m = (cal.get(Calendar.MONTH)+1).toString
val d = cal.get(Calendar.DATE).toString
(y,m,d)
}
def toOpts(from:Int,to:Int,by:Int):Seq[(String,String)] =
(from to to by by).map( i => i.toString -> i.toString )
def toOpts(from:Int,to:Int):Seq[(String,String)] = toOpts(from,to,1)
def toDate(y:String,m:String,d:String)
= new GregorianCalendar(parseInt(y),parseInt(m)-1,parseInt(d)).getTime
}
class DateSelect(vars:AnyVar[String,_],name:String) {
def currentYMD = if( vars.is == DateSelect.dummyYMD ){
DateSelect.formatYMD(new Date)
} else vars.is
def date_html(attrs: (String, String)*): NodeSeq = {
//SELECTパラメータを受け取って組み立て、
//RequestVarへ入れるコールバック
//hidden要素にバインドする。
val callback = (s:String) => {
val passedDate = DateSelect.toDate(
S.param(name+"_y").open_!,
S.param(name+"_m").open_!,
S.param(name+"_d").open_! )
vars( DateSelect.formatYMD( passedDate ) )
}
val (y,m,d) = DateSelect.splitYMD(currentYMD)
SHtml.hidden( callback, currentYMD ) ++
SHtml.select( DateSelect.toOpts(2009, 2011), Full(y), null,
attrs ++ Seq(("name",name+"_y")): _*) ++
SHtml.select( DateSelect.toOpts(1, 12), Full(m), null,
attrs ++ Seq(("name",name+"_m")): _*) ++
SHtml.select( DateSelect.toOpts(1, 31), Full(d), null,
attrs ++ Seq(("name",name+"_d")): _*)
}
}
使い方
class ASnippet {
object startTime extends RequestVar[String](DateSelect.dummyYMD)
object endTime extends RequestVar[String](DateSelect.dummyYMD)
def addForm(xhtml: NodeSeq):NodeSeq = {
def doAdd(){
println("---startTime:" + startTime)
println("---endTime:" + endTime)
}
bind("e", xhtml,
"startTime" -> DateSelect(startTime,"startTime").date_html(),
"endTime" -> DateSelect(endTime,"endTime").date_html(),
"submit" -> SHtml.submit("送信", doAdd) )
}
}
特に難しいことはやってないですが、ポイントは、
・HIDDEN要素に、サーバサイドコールバックのトリガーを持たせる。
・SELECT要素は文字列の運搬だけを行う。name属性は上書き。
・RequestVarでもSessionVarでも使えるようにAnyVarを使う。
※値を入力できるSHtml.hiddenはLift1.0では使えないので、何か別の方法考える必要あります。
要点だけ絞ったコードを貼りました(コピペで使えるはずです)が、時間も設定できるようにするにはパターンを増やすだけ。完成品ができたら後でgistにでも貼っておきます。
DATE SELECTがないことに今頃気づいて「げげぇっ」って感じで、自分も困ってる人なので、他に良案・良実装があれば教えていただければ幸いです。