From db345eed55a049b540f30802e77db33705349945 Mon Sep 17 00:00:00 2001 From: Sarah Vaupel Date: Wed, 14 Aug 2019 13:23:05 +0200 Subject: [PATCH] feat(datepicker): format according to input type; position datepicker Format dates and times according to the type of the input element; position the datepicker at the right by default and at the bottom for horizontal mass-inputs --- frontend/src/utils/form/datepicker.js | 24 +++++++++++++++++++----- src/Handler/Exam/Form.hs | 4 ++-- src/Utils/Form.hs | 10 ++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/frontend/src/utils/form/datepicker.js b/frontend/src/utils/form/datepicker.js index 49fcf2025..929fd222c 100644 --- a/frontend/src/utils/form/datepicker.js +++ b/frontend/src/utils/form/datepicker.js @@ -2,7 +2,14 @@ import datetime from 'tail.datetime'; import dateFormat from 'dateformat'; import { Utility } from '../../core/utility'; -const FORM_DATE_FORMAT = 'yyyy-mm-dd"T"HH:MM:ss'; +// formats for displaying all dates and/or times +const FORM_DATE_FORMAT_DATE = 'yyyy-mm-dd'; +const FORM_DATE_FORMAT_TIME = 'HH:MM:ss'; +const FORM_DATE_FORMAT = { + 'date': FORM_DATE_FORMAT_DATE, + 'time': FORM_DATE_FORMAT_TIME, + 'datetime-local': `${FORM_DATE_FORMAT_DATE}"T"${FORM_DATE_FORMAT_TIME}`, +}; const DATEPICKER_UTIL_SELECTOR = 'input[type="date"], input[type="time"], input[type="datetime-local"]'; @@ -54,6 +61,7 @@ export class Datepicker { datepickerInstance; _element; + elementType; constructor(element) { if (!element) { @@ -71,17 +79,23 @@ export class Datepicker { this._element = element; + // store the previously set type to select the input format + this.elementType = this._element.getAttribute('type'); + // get all relevant config options for this datepicker type const datepickerGlobalConfig = DATEPICKER_CONFIG['global']; - const datepickerConfig = DATEPICKER_CONFIG[this._element.getAttribute('type')]; + const datepickerConfig = DATEPICKER_CONFIG[this.elementType]; + + // manually set the type attribute to text because datepicker handles displaying the date + this._element.setAttribute('type', 'text'); // additional position config (optional data-datepicker-position attribute in html) that can specialize the global config - const datepickerPosition = this._element.dataSet.datepickerPosition; + const datepickerPosition = this._element.dataset.datepickerPosition; if (datepickerPosition) { datepickerGlobalConfig.position = datepickerPosition; } - if (!datepickerConfig) { + if (!datepickerConfig || !FORM_DATE_FORMAT[this.elementType]) { throw new Error('Datepicker utility called on unsupported element!'); } @@ -129,7 +143,7 @@ export class Datepicker { */ formatElementValue() { if (!this.datepickerInstance.select || !this._element.value) return; - this._element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT); + this._element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT[this.elementType]); } /** diff --git a/src/Handler/Exam/Form.hs b/src/Handler/Exam/Form.hs index 1020c6f28..bcbde196b 100644 --- a/src/Handler/Exam/Form.hs +++ b/src/Handler/Exam/Form.hs @@ -164,8 +164,8 @@ examOccurrenceForm prev = wFormToAForm $ do (eofNameRes, eofNameView) <- mpreq ciField ("" & addName (nudge "name")) (eofName <$> mPrev) (eofRoomRes, eofRoomView) <- mpreq textField ("" & addName (nudge "room")) (eofRoom <$> mPrev) (eofCapacityRes, eofCapacityView) <- mpreq (natFieldI MsgExamRoomCapacityNegative) ("" & addName (nudge "capacity")) (eofCapacity <$> mPrev) - (eofStartRes, eofStartView) <- mpreq utcTimeField ("" & addName (nudge "start")) (eofStart <$> mPrev) - (eofEndRes, eofEndView) <- mopt utcTimeField ("" & addName (nudge "end")) (eofEnd <$> mPrev) + (eofStartRes, eofStartView) <- mpreq utcTimeField ("" & addName (nudge "start") & addDatepickerPositionAttr DPBottom) (eofStart <$> mPrev) + (eofEndRes, eofEndView) <- mopt utcTimeField ("" & addName (nudge "end") & addDatepickerPositionAttr DPBottom) (eofEnd <$> mPrev) (eofDescRes, eofDescView) <- mopt htmlFieldSmall ("" & addName (nudge "description")) (eofDescription <$> mPrev) return ( ExamOccurrenceForm diff --git a/src/Utils/Form.hs b/src/Utils/Form.hs index c54ed44b3..38998d929 100644 --- a/src/Utils/Form.hs +++ b/src/Utils/Form.hs @@ -107,6 +107,16 @@ addAttrs attr valus fs = fs { fsAttrs = insertAttr attr valu $ fsAttrs fs } where valu = T.intercalate " " valus +data DatepickerPosition = DPLeft | DPRight | DPTop | DPBottom deriving (Eq,Ord,Enum,Bounded,Read,Show) + +instance Universe DatepickerPosition +instance Finite DatepickerPosition + +nullaryPathPiece ''DatepickerPosition $ camelToPathPiece' 1 + +addDatepickerPositionAttr :: DatepickerPosition -> FieldSettings site -> FieldSettings site +addDatepickerPositionAttr = addAttr "data-datepicker-position" . toPathPiece + addPlaceholder :: Text -> FieldSettings site -> FieldSettings site addPlaceholder placeholder fs = fs { fsAttrs = (placeholderAttr, placeholder) : filter ((/= placeholderAttr) . fst) (fsAttrs fs) } where