From 5b6d4a9dec6322a6187d226be3ef46418c092a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Thu, 8 Feb 2018 12:11:53 +0200 Subject: [PATCH 1/6] Allow newer version of elm-date-extra --- tests/elm-package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/elm-package.json b/tests/elm-package.json index a6f5a1f..488d1c0 100644 --- a/tests/elm-package.json +++ b/tests/elm-package.json @@ -13,7 +13,7 @@ "elm-lang/core": "5.0.0 <= v < 6.0.0", "elm-lang/html": "2.0.0 <= v < 3.0.0", "elm-lang/svg": "2.0.0 <= v < 3.0.0", - "rluiten/elm-date-extra": "8.1.2 <= v < 9.0.0" + "rluiten/elm-date-extra": "8.1.2 <= v < 10.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" } From 1cbf9fdb1b6af9dada58cb9a5c983d45b16d40e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Thu, 8 Feb 2018 13:55:20 +0200 Subject: [PATCH 2/6] Add support for week numbers --- src/DatePickerPanel.elm | 155 +++++++------- src/DateTimePicker.elm | 302 ++++++++++++++-------------- src/DateTimePicker/Config.elm | 6 + src/DateTimePicker/DateUtils.elm | 59 ++++-- src/DateTimePicker/SharedStyles.elm | 1 + tests/DateUtilsTests.elm | 73 ++++--- 6 files changed, 322 insertions(+), 274 deletions(-) diff --git a/src/DatePickerPanel.elm b/src/DatePickerPanel.elm index 8b18c86..f088a85 100644 --- a/src/DatePickerPanel.elm +++ b/src/DatePickerPanel.elm @@ -25,6 +25,7 @@ type alias Config otherConfig msg = | onChange : State -> Maybe Date -> msg , nameOfDays : NameOfDays , firstDayOfWeek : Date.Day + , weekNumbers : Bool , allowYearNavigation : Bool , titleFormatter : Date -> String , footerFormatter : Date -> String @@ -46,11 +47,11 @@ gotoNextMonth (InternalState state) = updatedTitleDate = Maybe.map (Date.Extra.Duration.add Date.Extra.Duration.Month 1) state.titleDate in - InternalState - { state - | event = "next" - , titleDate = updatedTitleDate - } + InternalState + { state + | event = "next" + , titleDate = updatedTitleDate + } gotoNextYear : State -> State @@ -59,11 +60,11 @@ gotoNextYear (InternalState state) = updatedTitleDate = Maybe.map (Date.Extra.Duration.add Date.Extra.Duration.Year 1) state.titleDate in - InternalState - { state - | event = "nextYear" - , titleDate = updatedTitleDate - } + InternalState + { state + | event = "nextYear" + , titleDate = updatedTitleDate + } gotoPreviousMonth : State -> State @@ -72,11 +73,11 @@ gotoPreviousMonth (InternalState state) = updatedTitleDate = Maybe.map (Date.Extra.Duration.add Date.Extra.Duration.Month -1) state.titleDate in - InternalState - { state - | event = "previous" - , titleDate = updatedTitleDate - } + InternalState + { state + | event = "previous" + , titleDate = updatedTitleDate + } gotoPreviousYear : State -> State @@ -85,11 +86,11 @@ gotoPreviousYear (InternalState state) = updatedTitleDate = Maybe.map (Date.Extra.Duration.add Date.Extra.Duration.Year -1) state.titleDate in - InternalState - { state - | event = "previousYear" - , titleDate = updatedTitleDate - } + InternalState + { state + | event = "previousYear" + , titleDate = updatedTitleDate + } @@ -124,15 +125,15 @@ title config ((InternalState stateValue) as state) currentDate = date = stateValue.titleDate in - span - [ config.class [ Title ] - , onMouseDownPreventDefault <| config.onChange (switchMode state) currentDate - ] - [ date - |> Maybe.map config.titleFormatter - |> Maybe.withDefault "N/A" - |> text - ] + span + [ config.class [ Title ] + , onMouseDownPreventDefault <| config.onChange (switchMode state) currentDate + ] + [ date + |> Maybe.map config.titleFormatter + |> Maybe.withDefault "N/A" + |> text + ] previousYearButton : Config (CssConfig a msg CssClasses) msg -> State -> Maybe Date.Date -> Html msg @@ -208,7 +209,7 @@ calendar config (InternalState state) currentDate = year = Date.year titleDate - days = + daysAndWeeks = DateTimePicker.DateUtils.generateCalendar config.firstDayOfWeek month year header = @@ -233,46 +234,54 @@ calendar config (InternalState state) currentDate = selectedDate = DateTimePicker.DateUtils.toDate year month day in - td - [ config.class - (case day.monthType of - DateTimePicker.DateUtils.Previous -> - [ PreviousMonth ] - - DateTimePicker.DateUtils.Current -> - CurrentMonth - :: (if isHighlighted day then - [ SelectedDate ] - else if isToday day then - [ Today ] - else - [] - ) - - DateTimePicker.DateUtils.Next -> - [ NextMonth ] - ) - , Html.Attributes.attribute "role" "button" - , Html.Attributes.attribute "aria-label" (Date.Extra.Format.format Date.Extra.Config.Config_en_us.config "%e, %A %B %Y" selectedDate) - , onMouseDownPreventDefault <| dateClickHandler config (InternalState state) year month day - , onTouchStartPreventDefault <| dateClickHandler config (InternalState state) year month day - ] - [ text <| toString day.day ] - - toWeekRow week = - tr [] (List.map toCell week) + td + [ config.class + (case day.monthType of + DateTimePicker.DateUtils.Previous -> + [ PreviousMonth ] + + DateTimePicker.DateUtils.Current -> + CurrentMonth + :: (if isHighlighted day then + [ SelectedDate ] + else if isToday day then + [ Today ] + else + [] + ) + + DateTimePicker.DateUtils.Next -> + [ NextMonth ] + ) + , Html.Attributes.attribute "role" "button" + , Html.Attributes.attribute "aria-label" (Date.Extra.Format.format Date.Extra.Config.Config_en_us.config "%e, %A %B %Y" selectedDate) + , onMouseDownPreventDefault <| dateClickHandler config (InternalState state) year month day + , onTouchStartPreventDefault <| dateClickHandler config (InternalState state) year month day + ] + [ text <| toString day.day ] + + weekNumberCell weekNumber = + td [ config.class [ WeekNumber ] ] + [ text (toString weekNumber) ] + + toWeekRow ( weekNumber, week ) = + if config.weekNumbers then + tr [] (weekNumberCell weekNumber :: List.map toCell week) + else + tr [] (List.map toCell week) body = tbody [ config.class [ Days ] ] - (days + (daysAndWeeks.days |> List.Extra.groupsOf 7 + |> List.Extra.zip daysAndWeeks.weeks |> List.map toWeekRow ) in - table [ config.class [ Calendar ] ] - [ header - , body - ] + table [ config.class [ Calendar ] ] + [ header + , body + ] dayNames : Config a msg -> List (Html msg) @@ -291,9 +300,9 @@ dayNames config = shiftAmount = DateTimePicker.DateUtils.dayToInt Date.Sun config.firstDayOfWeek in - days - |> List.Extra.splitAt shiftAmount - |> (\( head, tail ) -> tail ++ head) + days + |> List.Extra.splitAt shiftAmount + |> (\( head, tail ) -> tail ++ head) dateClickHandler : Config a msg -> InternalState -> Int -> Date.Month -> DateTimePicker.DateUtils.Day -> msg @@ -319,12 +328,12 @@ dateClickHandler config (InternalState state) year month day = Nothing } in - case day.monthType of - DateTimePicker.DateUtils.Previous -> - config.onChange (gotoPreviousMonth updatedState) selectedDate + case day.monthType of + DateTimePicker.DateUtils.Previous -> + config.onChange (gotoPreviousMonth updatedState) selectedDate - DateTimePicker.DateUtils.Next -> - config.onChange (gotoNextMonth updatedState) selectedDate + DateTimePicker.DateUtils.Next -> + config.onChange (gotoNextMonth updatedState) selectedDate - DateTimePicker.DateUtils.Current -> - config.onChange updatedState selectedDate + DateTimePicker.DateUtils.Current -> + config.onChange updatedState selectedDate diff --git a/src/DateTimePicker.elm b/src/DateTimePicker.elm index 8a90ae7..09e3079 100644 --- a/src/DateTimePicker.elm +++ b/src/DateTimePicker.elm @@ -93,9 +93,9 @@ initialCmd onChange (InternalState state) = , titleDate = Just <| Date.Extra.Core.toFirstOfMonth now } in - Task.perform - ((setDate >> onChange |> flip) Nothing) - Date.now + Task.perform + ((setDate >> onChange |> flip) Nothing) + Date.now @@ -136,10 +136,10 @@ type alias Model = { datePickerState : DateTimePicker.State, value : Maybe Date default = DateTimePicker.defaultConfig DatePickerChanged in - { default - | firstDayOfWeek = Date.Mon - , autoClose = True - } + { default + | firstDayOfWeek = Date.Mon + , autoClose = True + } view = DateTimePicker.datePickerWithConfig @@ -207,10 +207,10 @@ type alias Model = { dateTimePickerState : DateTimePicker.State, value : Maybe D default = DateTimePicker.defaultDateTimePickerConfig DatePickerChanged in - { default - | firstDayOfWeek = Date.Mon - , autoClose = True - } + { default + | firstDayOfWeek = Date.Mon + , autoClose = True + } view = DateTimePicker.dateTimePickerWithConfig @@ -237,9 +237,9 @@ type alias Model = { timePickerState : DateTimePicker.State, value : Maybe Date default = DateTimePicker.defaultTimePickerConfig TimePickerChanged in - { default - | autoClose = True - } + { default + | autoClose = True + } view = DateTimePicker.timePickerWithConfig @@ -285,15 +285,15 @@ view pickerType attributes ((InternalState stateValue) as state) currentDate = Html.text "" ] in - case pickerType of - DateType config -> - html config (config.class [ DatePicker ]) + case pickerType of + DateType config -> + html config (config.class [ DatePicker ]) - DateTimeType config -> - html config (config.class [ DatePicker, TimePicker ]) + DateTimeType config -> + html config (config.class [ DatePicker, TimePicker ]) - TimeType config -> - html config (config.class [ TimePicker ]) + TimeType config -> + html config (config.class [ TimePicker ]) @@ -316,62 +316,64 @@ dialog pickerType (InternalState state) currentDate = Digital -> attributes config in - case pickerType of - DateType config -> - div (attributes config) - [ DatePickerPanel.view - { onChange = config.onChange - , nameOfDays = config.nameOfDays - , firstDayOfWeek = config.firstDayOfWeek - , allowYearNavigation = config.allowYearNavigation - , titleFormatter = config.i18n.titleFormatter - , footerFormatter = config.i18n.footerFormatter - , class = config.class - } - (InternalState state) - currentDate - ] - - TimeType config -> - let - dialog = - case config.timePickerType of - Digital -> - DigitalTimePickerPanel.view - - Analog -> - AnalogTimePickerPanel.view - in - div (withTimeAttributes config config.timePickerType) - [ dialog - { onChange = config.onChange - , titleFormatter = config.i18n.timeTitleFormatter - , class = config.class - } - (InternalState state) - currentDate - ] - - DateTimeType config -> - div (withTimeAttributes config config.timePickerType) - (MultiPanel.view - { onChange = config.onChange - , nameOfDays = config.nameOfDays - , firstDayOfWeek = config.firstDayOfWeek - , allowYearNavigation = config.allowYearNavigation - , titleFormatter = config.i18n.titleFormatter - , footerFormatter = config.i18n.footerFormatter - , class = config.class - } - ( config.timePickerType - , { onChange = config.onChange - , titleFormatter = config.i18n.timeTitleFormatter - , class = config.class - } + case pickerType of + DateType config -> + div (attributes config) + [ DatePickerPanel.view + { onChange = config.onChange + , nameOfDays = config.nameOfDays + , firstDayOfWeek = config.firstDayOfWeek + , weekNumbers = config.weekNumbers + , allowYearNavigation = config.allowYearNavigation + , titleFormatter = config.i18n.titleFormatter + , footerFormatter = config.i18n.footerFormatter + , class = config.class + } + (InternalState state) + currentDate + ] + + TimeType config -> + let + dialog = + case config.timePickerType of + Digital -> + DigitalTimePickerPanel.view + + Analog -> + AnalogTimePickerPanel.view + in + div (withTimeAttributes config config.timePickerType) + [ dialog + { onChange = config.onChange + , titleFormatter = config.i18n.timeTitleFormatter + , class = config.class + } + (InternalState state) + currentDate + ] + + DateTimeType config -> + div (withTimeAttributes config config.timePickerType) + (MultiPanel.view + { onChange = config.onChange + , nameOfDays = config.nameOfDays + , firstDayOfWeek = config.firstDayOfWeek + , weekNumbers = config.weekNumbers + , allowYearNavigation = config.allowYearNavigation + , titleFormatter = config.i18n.titleFormatter + , footerFormatter = config.i18n.footerFormatter + , class = config.class + } + ( config.timePickerType + , { onChange = config.onChange + , titleFormatter = config.i18n.timeTitleFormatter + , class = config.class + } + ) + (InternalState state) + currentDate ) - (InternalState state) - currentDate - ) @@ -384,54 +386,54 @@ inputChangeHandler config (InternalState state) currentDate maybeDate = (InternalState initialStateValue) = initialState in - case maybeDate of - Just date -> - let - updateTime time = - { time - | hour = Date.hour date |> DateTimePicker.DateUtils.fromMillitaryHour |> Just - , minute = Just (Date.minute date) - , amPm = Date.hour date |> DateTimePicker.DateUtils.fromMillitaryAmPm |> Just - } - - updatedValue = - { state - | date = Just date - , time = updateTime state.time - , inputFocused = False - , event = "inputChangeHandler" - } - in - config.onChange (InternalState updatedValue) maybeDate - - Nothing -> - let - ( updatedTime, updatedActiveTimeIndicator, updatedDate ) = - case currentDate of - Just _ -> - ( { hour = Nothing, minute = Nothing, amPm = Nothing } - , Just DateTimePicker.Internal.HourIndicator - , Nothing - ) - - Nothing -> - ( state.time - , state.activeTimeIndicator - , state.date - ) - - updatedValue = - { state - | date = updatedDate - , time = updatedTime - , hourPickerStart = initialStateValue.hourPickerStart - , minutePickerStart = initialStateValue.minutePickerStart - , inputFocused = False - , event = "inputChangeHandler" - , activeTimeIndicator = updatedActiveTimeIndicator - } - in - config.onChange (InternalState updatedValue) maybeDate + case maybeDate of + Just date -> + let + updateTime time = + { time + | hour = Date.hour date |> DateTimePicker.DateUtils.fromMillitaryHour |> Just + , minute = Just (Date.minute date) + , amPm = Date.hour date |> DateTimePicker.DateUtils.fromMillitaryAmPm |> Just + } + + updatedValue = + { state + | date = Just date + , time = updateTime state.time + , inputFocused = False + , event = "inputChangeHandler" + } + in + config.onChange (InternalState updatedValue) maybeDate + + Nothing -> + let + ( updatedTime, updatedActiveTimeIndicator, updatedDate ) = + case currentDate of + Just _ -> + ( { hour = Nothing, minute = Nothing, amPm = Nothing } + , Just DateTimePicker.Internal.HourIndicator + , Nothing + ) + + Nothing -> + ( state.time + , state.activeTimeIndicator + , state.date + ) + + updatedValue = + { state + | date = updatedDate + , time = updatedTime + , hourPickerStart = initialStateValue.hourPickerStart + , minutePickerStart = initialStateValue.minutePickerStart + , inputFocused = False + , event = "inputChangeHandler" + , activeTimeIndicator = updatedActiveTimeIndicator + } + in + config.onChange (InternalState updatedValue) maybeDate datePickerFocused : Type msg CssClasses -> Config a msg -> State -> Maybe Date.Date -> msg @@ -452,25 +454,25 @@ datePickerFocused pickerType config (InternalState state) currentDate = , amPm = currentDate |> Maybe.map (Date.hour >> DateTimePicker.DateUtils.fromMillitaryAmPm) } in - config.onChange - (InternalState - { state - | inputFocused = True - , event = "onFocus" - , titleDate = updatedTitleDate - , date = currentDate - , forceClose = False - , time = updateTime state.time - , activeTimeIndicator = - case pickerType of - TimeType _ -> - Just DateTimePicker.Internal.HourIndicator - - _ -> - Nothing - } - ) - currentDate + config.onChange + (InternalState + { state + | inputFocused = True + , event = "onFocus" + , titleDate = updatedTitleDate + , date = currentDate + , forceClose = False + , time = updateTime state.time + , activeTimeIndicator = + case pickerType of + TimeType _ -> + Just DateTimePicker.Internal.HourIndicator + + _ -> + Nothing + } + ) + currentDate onChangeHandler : Type msg className -> State -> Maybe Date.Date -> msg @@ -487,12 +489,12 @@ onChangeHandler pickerType ((InternalState stateValue) as state) currentDate = _ -> config.onChange state Nothing in - case pickerType of - DateType config -> - justDateHandler config + case pickerType of + DateType config -> + justDateHandler config - DateTimeType config -> - withTimeHandler config + DateTimeType config -> + withTimeHandler config - TimeType config -> - withTimeHandler config + TimeType config -> + withTimeHandler config diff --git a/src/DateTimePicker/Config.elm b/src/DateTimePicker/Config.elm index 266390e..53db817 100644 --- a/src/DateTimePicker/Config.elm +++ b/src/DateTimePicker/Config.elm @@ -103,6 +103,7 @@ type alias I18n = - `nameOfDays` is the configuration for name of days in a week. - `firstDayOfWeek` is the first day of the week. + - `weekNumbers` show/hide week numbers - `titleFormatter` is the Date to String formatter for the dialog's title. - `footerFormatter` is the Date to String formatter for the dialog's footer. - `allowYearNavigation` show/hide year navigation button. @@ -112,6 +113,7 @@ type alias DatePickerConfig otherConfig = { otherConfig | nameOfDays : NameOfDays , firstDayOfWeek : Date.Day + , weekNumbers : Bool , allowYearNavigation : Bool } @@ -242,6 +244,7 @@ type TimePickerType - `autoClose` Default: True - `nameOfDays` see `NameOfDays` for the default values. - `firstDayOfWeek` Default: Sunday. + - `weekNumbers` Default: False - `allowYearNavigation` Default : True -} @@ -251,6 +254,7 @@ defaultDatePickerConfig onChange = , autoClose = True , nameOfDays = defaultNameOfDays , firstDayOfWeek = Date.Sun + , weekNumbers = False , allowYearNavigation = True , i18n = defaultDateI18n , usePicker = True @@ -289,6 +293,7 @@ defaultTimePickerConfig onChange = - `autoClose` Default: False - `nameOfDays` see `NameOfDays` for the default values. - `firstDayOfWeek` Default: Sunday. + - `weekNumbers` Default: False. - `titleFormatter` Default: `"%B %Y"` - `fullDateFormatter` Default: `"%A, %B %d, %Y"` - `timeFormatter` Default: `"%I:%M %p"` @@ -302,6 +307,7 @@ defaultDateTimePickerConfig onChange = , autoClose = False , nameOfDays = defaultNameOfDays , firstDayOfWeek = Date.Sun + , weekNumbers = False , timePickerType = Analog , allowYearNavigation = True , i18n = defaultDateTimeI18n diff --git a/src/DateTimePicker/DateUtils.elm b/src/DateTimePicker/DateUtils.elm index 3c91b27..d0f4d42 100644 --- a/src/DateTimePicker/DateUtils.elm +++ b/src/DateTimePicker/DateUtils.elm @@ -16,6 +16,7 @@ module DateTimePicker.DateUtils import Date import Date.Extra.Core import Date.Extra.Create +import Date.Extra.Utils import String @@ -45,27 +46,27 @@ dayToInt startOfWeek day = Date.Sat -> 6 in - case startOfWeek of - Date.Sun -> - base + case startOfWeek of + Date.Sun -> + base - Date.Mon -> - (base - 1) % 7 + Date.Mon -> + (base - 1) % 7 - Date.Tue -> - (base - 2) % 7 + Date.Tue -> + (base - 2) % 7 - Date.Wed -> - (base - 3) % 7 + Date.Wed -> + (base - 3) % 7 - Date.Thu -> - (base - 4) % 7 + Date.Thu -> + (base - 4) % 7 - Date.Fri -> - (base - 5) % 7 + Date.Fri -> + (base - 5) % 7 - Date.Sat -> - (base - 6) % 7 + Date.Sat -> + (base - 6) % 7 calculateNumberOfDaysForPreviousMonth : Int -> Int @@ -86,7 +87,7 @@ type MonthType | Next -generateCalendar : Date.Day -> Date.Month -> Int -> List Day +generateCalendar : Date.Day -> Date.Month -> Int -> { days : List Day, weeks : List Int } generateCalendar firstDayOfWeek month year = let firstDateOfMonth = @@ -117,8 +118,28 @@ generateCalendar firstDayOfWeek month year = nextMonth = List.range 1 14 |> List.map (Day Next) + + days = + List.take 42 <| previousMonth ++ currentMonth ++ nextMonth + + weekIfMonday date = + case Date.dayOfWeek date of + Date.Mon -> + let + ( _, week, _ ) = + Date.Extra.Utils.isoWeek date + in + Just week + + _ -> + Nothing + + weeks = + days + |> List.map (\day -> toDateTime year month day 0 0) + |> List.filterMap weekIfMonday in - List.take 42 <| previousMonth ++ currentMonth ++ nextMonth + { days = days, weeks = weeks } toDateTime : Int -> Date.Month -> Day -> Int -> Int -> Date.Date @@ -133,7 +154,7 @@ toDateTime year month day hour minute = Date.Extra.Create.dateFromFields year month day.day hour minute 0 0 |> Date.Extra.Core.lastOfPrevMonthDate in - Date.Extra.Create.dateFromFields (Date.year previousMonth) (Date.month previousMonth) day.day hour minute 0 0 + Date.Extra.Create.dateFromFields (Date.year previousMonth) (Date.month previousMonth) day.day hour minute 0 0 Next -> let @@ -141,7 +162,7 @@ toDateTime year month day hour minute = Date.Extra.Create.dateFromFields year month day.day hour minute 0 0 |> Date.Extra.Core.firstOfNextMonthDate in - Date.Extra.Create.dateFromFields (Date.year nextMonth) (Date.month nextMonth) day.day hour minute 0 0 + Date.Extra.Create.dateFromFields (Date.year nextMonth) (Date.month nextMonth) day.day hour minute 0 0 toDate : Int -> Date.Month -> Day -> Date.Date diff --git a/src/DateTimePicker/SharedStyles.elm b/src/DateTimePicker/SharedStyles.elm index 4f4fce1..8e72ae5 100644 --- a/src/DateTimePicker/SharedStyles.elm +++ b/src/DateTimePicker/SharedStyles.elm @@ -17,6 +17,7 @@ type CssClasses | DaysOfWeek | PreviousMonth | CurrentMonth + | WeekNumber | Header | Body | NextMonth diff --git a/tests/DateUtilsTests.elm b/tests/DateUtilsTests.elm index 956cbe0..ebe08ad 100644 --- a/tests/DateUtilsTests.elm +++ b/tests/DateUtilsTests.elm @@ -59,20 +59,29 @@ generateCalendarTest = next = DateUtils.Day DateUtils.Next in - describe "DateUtil.generateCalendar" - [ test "generateCalendar for February 2016 (leap) should return a list of date" <| - \() -> - DateUtils.generateCalendar Date.Sun Date.Feb 2016 - |> Expect.equal ([ previous 31 ] ++ (List.range 1 29 |> List.map current) ++ (List.range 1 12 |> List.map next)) - , test "generateCalendar for February 2015 should return a list of date" <| - \() -> - DateUtils.generateCalendar Date.Sun Date.Feb 2015 - |> Expect.equal ((List.range 25 31 |> List.map previous) ++ (List.range 1 28 |> List.map current) ++ (List.range 1 7 |> List.map next)) - , test "generateCalendar for January 2099 should return a list of date" <| - \() -> - DateUtils.generateCalendar Date.Sun Date.Jan 2099 - |> Expect.equal ((List.range 28 31 |> List.map previous) ++ (List.range 1 31 |> List.map current) ++ (List.range 1 7 |> List.map next)) - ] + describe "DateUtil.generateCalendar" + [ test "generateCalendar for February 2016 (leap) should return a list of date" <| + \() -> + DateUtils.generateCalendar Date.Sun Date.Feb 2016 + |> Expect.equal + { days = [ previous 31 ] ++ (List.range 1 29 |> List.map current) ++ (List.range 1 12 |> List.map next) + , weeks = List.range 5 10 + } + , test "generateCalendar for February 2015 should return a list of date" <| + \() -> + DateUtils.generateCalendar Date.Sun Date.Feb 2015 + |> Expect.equal + { days = (List.range 25 31 |> List.map previous) ++ (List.range 1 28 |> List.map current) ++ (List.range 1 7 |> List.map next) + , weeks = List.range 5 10 + } + , test "generateCalendar for January 2099 should return a list of date" <| + \() -> + DateUtils.generateCalendar Date.Sun Date.Jan 2099 + |> Expect.equal + { days = (List.range 28 31 |> List.map previous) ++ (List.range 1 31 |> List.map current) ++ (List.range 1 7 |> List.map next) + , weeks = List.range 1 6 + } + ] toDateTest : Test @@ -121,24 +130,24 @@ setTimeTest = date = Date.Extra.Create.dateFromFields 2017 Date.Jan 1 0 0 0 0 in - describe "DateUtils.setTime" - [ test "setTime for 12:00 AM should return the right time" <| - \() -> - DateUtils.setTime date 12 0 "AM" - |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 0 0 0 0) - , test "setTime for 12:00 PM should return the right time" <| - \() -> - DateUtils.setTime date 12 0 "PM" - |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 12 0 0 0) - , test "setTime for 3:15 PM should return the right time" <| - \() -> - DateUtils.setTime date 3 15 "PM" - |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 15 15 0 0) - , test "setTime for 3:15 AM should return the right time" <| - \() -> - DateUtils.setTime date 3 15 "AM" - |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 3 15 0 0) - ] + describe "DateUtils.setTime" + [ test "setTime for 12:00 AM should return the right time" <| + \() -> + DateUtils.setTime date 12 0 "AM" + |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 0 0 0 0) + , test "setTime for 12:00 PM should return the right time" <| + \() -> + DateUtils.setTime date 12 0 "PM" + |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 12 0 0 0) + , test "setTime for 3:15 PM should return the right time" <| + \() -> + DateUtils.setTime date 3 15 "PM" + |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 15 15 0 0) + , test "setTime for 3:15 AM should return the right time" <| + \() -> + DateUtils.setTime date 3 15 "AM" + |> Expect.equal (Date.Extra.Create.dateFromFields 2017 Date.Jan 1 3 15 0 0) + ] paddingTest : Test From d887b091d0a72d36143e84e4baa8bef898b89c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Thu, 8 Feb 2018 14:05:26 +0200 Subject: [PATCH 3/6] Insert empty column to header when showing week numbers --- src/DatePickerPanel.elm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/DatePickerPanel.elm b/src/DatePickerPanel.elm index f088a85..99753f7 100644 --- a/src/DatePickerPanel.elm +++ b/src/DatePickerPanel.elm @@ -299,10 +299,17 @@ dayNames config = shiftAmount = DateTimePicker.DateUtils.dayToInt Date.Sun config.firstDayOfWeek + + insertWeekNumberColumn list = + if config.weekNumbers then + th [] [] :: list + else + list in days |> List.Extra.splitAt shiftAmount |> (\( head, tail ) -> tail ++ head) + |> insertWeekNumberColumn dateClickHandler : Config a msg -> InternalState -> Int -> Date.Month -> DateTimePicker.DateUtils.Day -> msg From e14a566c77c9c37365720f123bb8e55ee69fbd38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Thu, 8 Feb 2018 14:23:36 +0200 Subject: [PATCH 4/6] Add W in front of week number and do not use toString --- elm-package.json | 1 + src/DatePickerPanel.elm | 3 ++- tests/elm-package.json | 8 ++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/elm-package.json b/elm-package.json index b7665f8..9c653ea 100644 --- a/elm-package.json +++ b/elm-package.json @@ -14,6 +14,7 @@ "dependencies": { "abadi199/dateparser": "1.0.0 <= v < 2.0.0", "elm-community/list-extra": "4.0.0 <= v < 8.0.0", + "elm-community/string-extra": "1.4.0 <= v < 2.0.0", "elm-lang/core": "5.0.0 <= v < 6.0.0", "elm-lang/html": "2.0.0 <= v < 3.0.0", "elm-lang/svg": "2.0.0 <= v < 3.0.0", diff --git a/src/DatePickerPanel.elm b/src/DatePickerPanel.elm index 99753f7..2d4d1ba 100644 --- a/src/DatePickerPanel.elm +++ b/src/DatePickerPanel.elm @@ -14,6 +14,7 @@ import DateTimePicker.Svg import Html exposing (..) import Html.Attributes exposing (value) import List.Extra +import String.Extra type alias State = @@ -262,7 +263,7 @@ calendar config (InternalState state) currentDate = weekNumberCell weekNumber = td [ config.class [ WeekNumber ] ] - [ text (toString weekNumber) ] + [ text ("W" ++ String.Extra.fromInt weekNumber) ] toWeekRow ( weekNumber, week ) = if config.weekNumbers then diff --git a/tests/elm-package.json b/tests/elm-package.json index 488d1c0..560f310 100644 --- a/tests/elm-package.json +++ b/tests/elm-package.json @@ -3,17 +3,21 @@ "summary": "Test for DatePicker", "repository": "https://github.com/abadi199/datepicker.git", "license": "Apache 2.0", - "source-directories": [".", "../src"], + "source-directories": [ + ".", + "../src" + ], "exposed-modules": [], "dependencies": { "abadi199/dateparser": "1.0.0 <= v < 2.0.0", "eeue56/elm-html-test": "5.0.1 <= v < 6.0.0", "elm-community/elm-test": "4.1.1 <= v < 5.0.0", "elm-community/list-extra": "4.0.0 <= v < 8.0.0", + "elm-community/string-extra": "1.4.0 <= v < 2.0.0", "elm-lang/core": "5.0.0 <= v < 6.0.0", "elm-lang/html": "2.0.0 <= v < 3.0.0", "elm-lang/svg": "2.0.0 <= v < 3.0.0", "rluiten/elm-date-extra": "8.1.2 <= v < 10.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" -} +} \ No newline at end of file From 5cb826940b17b84a7093ebc01c129a042c0df3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Thu, 8 Feb 2018 14:37:08 +0200 Subject: [PATCH 5/6] Make week number prefix configurable --- src/DatePickerPanel.elm | 3 ++- src/DateTimePicker.elm | 2 ++ src/DateTimePicker/Config.elm | 6 ++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/DatePickerPanel.elm b/src/DatePickerPanel.elm index 2d4d1ba..21c69fd 100644 --- a/src/DatePickerPanel.elm +++ b/src/DatePickerPanel.elm @@ -27,6 +27,7 @@ type alias Config otherConfig msg = , nameOfDays : NameOfDays , firstDayOfWeek : Date.Day , weekNumbers : Bool + , weekNumberPrefix : String , allowYearNavigation : Bool , titleFormatter : Date -> String , footerFormatter : Date -> String @@ -263,7 +264,7 @@ calendar config (InternalState state) currentDate = weekNumberCell weekNumber = td [ config.class [ WeekNumber ] ] - [ text ("W" ++ String.Extra.fromInt weekNumber) ] + [ text (config.weekNumberPrefix ++ String.Extra.fromInt weekNumber) ] toWeekRow ( weekNumber, week ) = if config.weekNumbers then diff --git a/src/DateTimePicker.elm b/src/DateTimePicker.elm index 09e3079..69e4e8e 100644 --- a/src/DateTimePicker.elm +++ b/src/DateTimePicker.elm @@ -324,6 +324,7 @@ dialog pickerType (InternalState state) currentDate = , nameOfDays = config.nameOfDays , firstDayOfWeek = config.firstDayOfWeek , weekNumbers = config.weekNumbers + , weekNumberPrefix = config.weekNumberPrefix , allowYearNavigation = config.allowYearNavigation , titleFormatter = config.i18n.titleFormatter , footerFormatter = config.i18n.footerFormatter @@ -360,6 +361,7 @@ dialog pickerType (InternalState state) currentDate = , nameOfDays = config.nameOfDays , firstDayOfWeek = config.firstDayOfWeek , weekNumbers = config.weekNumbers + , weekNumberPrefix = config.weekNumberPrefix , allowYearNavigation = config.allowYearNavigation , titleFormatter = config.i18n.titleFormatter , footerFormatter = config.i18n.footerFormatter diff --git a/src/DateTimePicker/Config.elm b/src/DateTimePicker/Config.elm index 53db817..039b7d0 100644 --- a/src/DateTimePicker/Config.elm +++ b/src/DateTimePicker/Config.elm @@ -104,6 +104,7 @@ type alias I18n = - `nameOfDays` is the configuration for name of days in a week. - `firstDayOfWeek` is the first day of the week. - `weekNumbers` show/hide week numbers + - `weekNumberPrefix` string to prepend to each week number. - `titleFormatter` is the Date to String formatter for the dialog's title. - `footerFormatter` is the Date to String formatter for the dialog's footer. - `allowYearNavigation` show/hide year navigation button. @@ -114,6 +115,7 @@ type alias DatePickerConfig otherConfig = | nameOfDays : NameOfDays , firstDayOfWeek : Date.Day , weekNumbers : Bool + , weekNumberPrefix : String , allowYearNavigation : Bool } @@ -245,6 +247,7 @@ type TimePickerType - `nameOfDays` see `NameOfDays` for the default values. - `firstDayOfWeek` Default: Sunday. - `weekNumbers` Default: False + - `weekNumberPrefix` Default: "W" - `allowYearNavigation` Default : True -} @@ -255,6 +258,7 @@ defaultDatePickerConfig onChange = , nameOfDays = defaultNameOfDays , firstDayOfWeek = Date.Sun , weekNumbers = False + , weekNumberPrefix = "W" , allowYearNavigation = True , i18n = defaultDateI18n , usePicker = True @@ -294,6 +298,7 @@ defaultTimePickerConfig onChange = - `nameOfDays` see `NameOfDays` for the default values. - `firstDayOfWeek` Default: Sunday. - `weekNumbers` Default: False. + - `weekNumberPrefix` Default: "W" - `titleFormatter` Default: `"%B %Y"` - `fullDateFormatter` Default: `"%A, %B %d, %Y"` - `timeFormatter` Default: `"%I:%M %p"` @@ -308,6 +313,7 @@ defaultDateTimePickerConfig onChange = , nameOfDays = defaultNameOfDays , firstDayOfWeek = Date.Sun , weekNumbers = False + , weekNumberPrefix = "W" , timePickerType = Analog , allowYearNavigation = True , i18n = defaultDateTimeI18n From ad196eeb32d8860e15bfb8522fcaf0f2bf55d907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Set=C3=A4l=C3=A4?= Date: Tue, 8 May 2018 17:17:39 +0300 Subject: [PATCH 6/6] Increase version range of list-extra dependency --- tests/elm-package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/elm-package.json b/tests/elm-package.json index 560f310..b1a8dd5 100644 --- a/tests/elm-package.json +++ b/tests/elm-package.json @@ -20,4 +20,4 @@ "rluiten/elm-date-extra": "8.1.2 <= v < 10.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" -} \ No newline at end of file +}