JodaTime field
authorTomas Zeman <tzeman@volny.cz>
Mon, 02 Apr 2012 22:26:55 +0200
changeset 24 149113e059bd
parent 23 16066379860c
child 25 c1fcdb1a39c3
JodaTime field
src/main/scala/net/tz/lift/model/JodaTimeField.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/net/tz/lift/model/JodaTimeField.scala	Mon Apr 02 22:26:55 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012 Tomas Zeman <tzeman@volny.cz>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.tz.lift.model
+
+import java.util.Calendar
+import net.liftweb.common._
+import net.liftweb.http._
+import net.liftweb.record._
+import net.liftweb.record.field._
+import net.liftweb.util._
+import net.liftweb.util.Helpers._
+import org.joda.time.{DateTime, DateMidnight}
+import org.joda.time.base.AbstractDateTime
+import org.joda.time.format.DateTimeFormat
+import scala.xml.{Elem, Text, Unparsed}
+
+/**
+ * Joda date time field. Renders view in Czech format; renders form as 3 text
+ * fields w/ css classes: <code>date</code>, <code>hour</code>,
+ * <code>minute</code> to be rendered via CSS (date picker etc.).
+ */
+class JodaDateTimeField[T <: Record[T]](rec: T) extends DateTimeField(rec) {
+  override def setFromAny(in: Any): Box[Calendar] = in match {
+    case dt: AbstractDateTime => setBox(Full(dt.toGregorianCalendar))
+    case x => super.setFromAny(x)
+  }
+
+  def set(dt: AbstractDateTime): Calendar = set(dt.toGregorianCalendar)
+
+  def dateTime = new DateTime(get)
+
+  private def mdt = dateTime.toMutableDateTime
+
+  override def asHtml = Text(AsDateTime(dateTime))
+  override def toForm = Full(
+    SHtml.text(AsDateMidnight(dateTime.toDateMidnight), { s =>
+      val v = mdt
+      AsDateMidnight(s) foreach { in =>
+        v.setYear(in.getYear)
+        v.setMonthOfYear(in.getMonthOfYear)
+        v.setDayOfMonth(in.getDayOfMonth)
+      }
+      set(v.toGregorianCalendar) }, "class" -> "date") ++ Unparsed("&nbsp;") ++
+    SHtml.selectObj[Int]((0 to 23) map { v => (v, "%02d".format(v)) },
+      Full(dateTime.getHourOfDay), { h =>
+      val v = mdt
+      v.setHourOfDay(h)
+      set(v.toGregorianCalendar) }, "class" -> "hour") ++ Text(":") ++
+    SHtml.selectObj[Int](Range(0, 60, minuteStep) map { v =>
+      (v, "%02d".format(v)) },
+      Full(dateTime.getMinuteOfHour / minuteStep * minuteStep), { m =>
+      val v = mdt
+      v.setMinuteOfHour(m)
+      set(v.toGregorianCalendar) }, "class" -> "minute")
+  )
+
+  val minuteStep: Int = 5
+}
+
+/**
+ * Joda date field.
+ */
+class JodaDateMidnightField[T <: Record[T]](rec: T) extends DateTimeField(rec) {
+  override def setFromAny(in: Any): Box[Calendar] = in match {
+    case dt: AbstractDateTime => setBox(Full(dt.toGregorianCalendar))
+    case x => super.setFromAny(x)
+  }
+
+  def set(dt: AbstractDateTime): Calendar = set(dt.toGregorianCalendar)
+
+  def date = new DateMidnight(get)
+
+  override def asHtml = Text(AsDateMidnight(date))
+  override def toForm = Full(SHtml.text(AsDateMidnight(date),
+    s => setBox(AsDateMidnight(s) map {_.toGregorianCalendar}),
+    "class" -> "date"))
+}
+
+/**
+ * Joda date-time converters.
+ */
+object AsDateTime {
+  val fmt = DateTimeFormat.forPattern("dd.MM.yyyy HH:mm")
+
+  def apply(d: DateTime): String = fmt.print(d)
+  def apply(s: String): Box[DateTime] = tryo { fmt.parseDateTime(s) }
+}
+
+/**
+ * Joda date converters.
+ */
+object AsDateMidnight {
+  val fmt = DateTimeFormat.forPattern("dd.MM.yyyy")
+
+  def apply(d: DateMidnight): String = fmt.print(d)
+  def apply(s: String): Box[DateMidnight] = tryo {
+    fmt.parseDateTime(s).toDateMidnight }
+}
+
+// vim: set ts=2 sw=2 et: