PanagiotisGeorgiadis / Elm-DatePicker

A DatePicker package created using Elm 0.19
https://package.elm-lang.org/packages/PanagiotisGeorgiadis/elm-datepicker/latest/
BSD 3-Clause "New" or "Revised" License
11 stars 2 forks source link

Set default date range from main.elm #5

Closed chapmanjacobd closed 4 years ago

chapmanjacobd commented 4 years ago

I saw PR #2 and I was wondering how to use this to set a date range on initialization ?

I'm thinking of somehow calling a function within my init function ?

right now I have

singleDateRangePicker =
                Just
                    { endDate =
                        DateTime
                            { date = Date { day = Day 28, month = Dec, year = Year 2019 }
                            , time =
                                Time
                                    { hours = Hour 0
                                    , milliseconds = Millisecond 0
                                    , minutes = Minute 0
                                    , seconds = Second 0
                                    }
                            }
                    , startDate =
                        DateTime
                            { date = Date { day = Day 20, month = Dec, year = Year 2019 }
                            , time =
                                Time
                                    { hours = Hour 0
                                    , milliseconds = Millisecond 0
                                    , minutes = Minute 0
                                    , seconds = Second 0
                                    }
                            }
                    }

in my init instead of singleDateRangePicker = Nothing but I'm not sure how to replace it so that it can get the current date.

my goal is to have the default date range set to two weeks from the date the user loads the web page with a default range of 8 days. how do you recommend doing this?

another idea that I had is to edit the init part of the other module that is in my project. it looks like this:

init : Posix -> Model
init todayPosix =
    let
        today =
            DateTime.fromPosix todayPosix

        -- Allow 6 months in advance and in the past selection.
        ( minDate, maxDate ) =
            let
                ( past, future ) =
                    ( DateTimeExtra.decrementMonths 1 today
                    , DateTimeExtra.incrementMonths 36 today
                    )
            in
            ( Maybe.withDefault past <| DateTime.setDay 1 past
            , Maybe.withDefault future <| DateTime.setDay (DateTime.lastDayOf future) future
            )

        calendarConfig =
            { today = today
            , primaryDate = Nothing
            , dateLimit = DateLimit { minDate = minDate, maxDate = maxDate }
            , dateRangeOffset = Just { minDateRangeLength = 1 }
            }

        -- The `timePickerConfig` is set to `Nothing` cause we don't want one.
        timePickerConfig =
            Nothing
    in
    { picker = DateRangePicker.initialise Single calendarConfig timePickerConfig
    , selectedRange = Nothing
    , isFocused = False
    }

but again, I'm not sure what I would need to change...

PanagiotisGeorgiadis commented 4 years ago

Hello @chapmanjacobd! I'll try addressing individual parts of you question and we can iterate on those if you'd like to. :) On some topics I may get into a bit of depth just for the future reader to have some context.

So first of all in order to get the current date of the user, you can use the Time.now function from the elm/time package. As you can see this function returns a Task which we'll have to map it to a Cmd in order to perform the side effect of getting the current date. An example of the above can be found in this init function.

As you can see on the example above we are setting our DatePicker = Nothing because without a valid DateTime we aren't able to initialise a DatePicker. This is done by design unless you'd like to provide the posix timestamp from the program's flags. I would advice against it though since my guess is that you are using Elm cause you'd like your code to be more reliable.

After getting the today posix you will create your constraints which if I am reading this correctly should be today - two weeks from now ( 14 days ). The way you would do this would be something like:

initDatePicker : Posix -> DateRangePicker.Model
initDatePicker todayPosix =
  let
    today =
      DateTime.fromPosix todayPosix -- Gets posix and transforms it to DateTime.

    dateLimit =
      { minDate = today
      , maxDate = DateTimeExtra.incrementDays 14 today
      }

    calendarConfig =
      { today = today
      , primaryDate = Nothing
      , dateLimit = dateLimit
      , dateRangeOffset = Just { minDateRangeLength = 8 } -- Minimum Date Range
      }

    timePickerConfig =
      Nothing

    dateRangePicker =
      DateRangePicker.initialise DateRangePicker.Single calendarConfig timePickerConfig
  in
  dateRangePicker

If you'd like to set the dateRange by default you'd have to edit the above code with the following:

initDatePicker todayPosix =
  today =
    DateTime.fromPosix todayPosix
  ...
  dateRangePicker = 
      DateRangePicker.initialise DateRangePicker.Single calendarConfig timePickerConfig
  in
  DateRangePicker.setDateRange
    { startDate: today
    , endDate: DateTimeExtra.incrementDays 8 today -- Default selected range of 8 days
    }
    dateRangePicker

The examples above are tackling the issue of adding DatePicker constrains ( two week constraint ) and adding a default selected range on initialisation.

I hope this is helpful but if not please leave another comment and I'll respond as soon as possible :)

chapmanjacobd commented 4 years ago
...
        pickerInit =
            DateRangePicker.initialise DateRangePicker.Types.Single calendarConfig timePickerConfig
    in
    { picker =
        DateRangePicker.setDateRange
            { startDate = DateTimeExtra.incrementDays 14 today, endDate = DateTimeExtra.incrementDays 22 today }
            pickerInit
    , selectedRange = Nothing
    , isFocused = False
    }

This is amazing! Thanks. It looks like it is correctly initializing the date in the model (you can see the dates selected on page load) but the textbox is blank until a user selects a set of dates. I would like the textbox to display the date range on page load

maybe it is because we're setting the date range but then we set selectedRange to Nothing right after. how can we prevent this?

chapmanjacobd commented 4 years ago

ahh I figured it out :D


        pickerInit =
            DateRangePicker.initialise DateRangePicker.Types.Single calendarConfig timePickerConfig

        defaultDateRange =
            { startDate = DateTimeExtra.incrementDays 14 today, endDate = DateTimeExtra.incrementDays 22 today }
    in
    { picker =
        DateRangePicker.setDateRange
            defaultDateRange
            pickerInit
    , selectedRange = (Just defaultDateRange)
    , isFocused = False
    }
PanagiotisGeorgiadis commented 4 years ago

Glad you figured it out @chapmanjacobd! 💯

Happy coding! 😃