Изменение данных отправки формы перед отправкой в ​​stringRead

У меня есть форма пищеварительных функторов, которая выглядит следующим образом:

dateTimeForm :: Monad m => Maybe LocalTime -> Form Text m LocalTime
dateTimeForm t = LocalTime
    <$> "date" .: stringRead "Must be a valid date" (localDay <$> t)
    <*> "time" .: stringRead "Must be a valid time" (localTimeOfDay <$> t)

Элементы ввода, которые я использую для этой формы: <input type="date" /> а также <input type="time" />, Это очень хорошо работает для части даты в этой форме, но не так хорошо для части времени. Браузеры, которые поддерживают элемент ввода времени, отправляют только часы и минуты (например, "18:00"), но TimeOfDay требует часов, минут и секунд. Это приводит к сбою stringRead, и Digrench Functors сообщает об ошибке пользователю ("Должно быть допустимое время").

Я попытался обойти это примерно так, но если пользователь отправляет неверное время, он больше не получит привлекательную ошибку от пищеварительных функторов (Prelude.read: no parse).

dateTimeForm :: Monad m => Maybe LocalTime -> Form Text m LocalTime
dateTimeForm t = toLocalTime
    <$> "date" .: stringRead "Must be a valid date" (localDay <$> t)
    <*> "time" .: string (show . localTimeOfDay <$> t)
    where
        toLocalTime d x = LocalTime d $ read $ if length x == 8 then x else x <> ":00"

1 ответ

Решение

Я думаю, что я искал это validate функция и небольшая помощь от maybeRead, Это похоже на работу:

dateTimeForm :: Monad m => Maybe LocalTime -> Form Text m LocalTime
dateTimeForm t = LocalTime
    <$> "date" .: stringRead "Must be a valid date" (localDay <$> t)
    <*> "time" .: validate validTime (string (show . localTimeOfDay <$> t))
    where
        -- the time input element only submits hours and minutes ("18:00"), which is 5 characters long
        validTime x = case maybeRead (if length x == 5 then x <> ":00" else x) of
            Just x' -> Success x'
            _ -> Error "Must be a valid time"
Другие вопросы по тегам