/*
* 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(" ") ++
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"))
}
/**
* Optional Joda date field.
*/
class OptionalJodaDateMidnightField[T <: Record[T]](rec: T) extends
OptionalDateTimeField(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: Box[AbstractDateTime]): Box[Calendar] =
set(dt map(_.toGregorianCalendar))
def date = get map(new DateMidnight(_))
override def toString = date map(AsDateMidnight(_)) getOrElse ""
override def asHtml = Text(toString)
override def toForm = Full(SHtml.text(toString,
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] = s match {
case null | "" => Empty
case s => tryo { fmt.parseDateTime(s).toDateMidnight }
}
}
// vim: set ts=2 sw=2 et: