cl-ds / data /repos /cl-forms /src /fields /date.lisp
j14i's picture
3375 CL macro transformation examples from 85 libraries
43203b4 verified
(in-package :forms)
(defparameter +default-date-format+
local-time:+iso-8601-date-format+)
(defclass date-form-field (form-field)
((date-min :initarg :date-min
:accessor date-min
:initform nil)
(date-max :initarg :date-max
:accessor date-max
:initform nil)
(date-format :initarg :date-format
:accessor date-format
:initform +default-date-format+)
(widget :initarg :widget
:accessor field-widget
:initform nil))
(:default-initargs
:placeholder "YYYY-MM-DD")
(:documentation "A date input field"))
(defclass date-validator (clavier:validator)
((date-format :initarg :date-format
:accessor date-format
:initform +default-date-format+))
(:metaclass c2mop:funcallable-standard-class)
(:default-initargs
:message (lambda (validator object)
(declare (ignorable validator object))
"The date is invalid"))
(:documentation "A date validator. TODO: should perhaps be part of clavier validators"))
(defmethod clavier::%validate ((validator date-validator) object &rest args)
(declare (ignore args))
(and
(local-time:parse-timestring object
:fail-on-error nil
:date-separator #\-
:allow-missing-time-part t)
t))
;;(clavier:validate (make-instance 'date-validator) "2003-10-10")
(defmethod validate-form-field ((form-field date-form-field))
(let ((validator (clavier:fn (lambda (date)
(typep date 'local-time:timestamp))
(or (field-invalid-message form-field)
"The date is invalid"))))
(multiple-value-bind (valid-p error)
(funcall validator
(field-value form-field))
(multiple-value-bind (valid-constraints-p errors)
(call-next-method)
(values (and valid-p valid-constraints-p)
(if error (cons error errors)
errors))))))
(defmethod field-read-from-request ((field date-form-field) form parameters)
(let ((value (cdr (assoc (field-request-name field form) parameters :test #'string=))))
(setf (field-value field)
(or
(and value
(local-time:parse-timestring
value
:date-separator #\-
:allow-missing-time-part t
:fail-on-error nil))
(if (string= value "")
nil
value)))))
(defmethod format-field-value ((field date-form-field) value &optional (stream *standard-output*))
(if (typep value 'local-time:timestamp)
(local-time:format-timestring stream value :format (date-format field))
(call-next-method)))
(defmethod make-form-field ((field-type (eql :date)) &rest args)
(apply #'make-instance 'date-form-field args))