Created
February 3, 2016 15:27
-
-
Save ccapndave/a7b032e8d7a21e289a45 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Form.Form (selectField, selectCountryField, dateOfBirthField) where | |
import Html exposing (..) | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (..) | |
import List.Extra exposing (zip) | |
import Date exposing (Date) | |
import Date.Core exposing (monthList) | |
import Date.Utils exposing (dateFromFields) | |
import Json.Decode as JD | |
import Task exposing (Task) | |
type alias SelectFieldOpts valueType actionType = | |
{ label : String | |
, value : valueType | |
, action : actionType } | |
selectField : Signal.Address actionType -> valueType -> List (SelectFieldOpts valueType actionType) -> Html | |
selectField address currentValue opts = | |
let | |
-- Build a list of a numerical key matched with the settings for each option | |
ids = List.map toString [0..(List.length opts)] | |
idAndOpts = zip ids opts | |
-- Given an id, this returns the action for that id | |
getActionForId id = | |
let | |
selectFieldOpts = case (List.filter (\(listId, _) -> listId == id) idAndOpts |> List.head) of | |
Just opt -> opt |> snd | |
Nothing -> Debug.crash "Somehow an option without a matching id was selected (this should be impossible!)" | |
in | |
selectFieldOpts.action | |
isSelected opt = | |
currentValue == opt.value | |
valueDecoder : JD.Decoder String | |
valueDecoder = | |
JD.at ["target", "value"] JD.string | |
makeOption (id, opt) = | |
option [ value id | |
, selected (isSelected opt) | |
] [ text opt.label ] | |
in | |
select [ on "change" valueDecoder (\id -> Signal.message address (getActionForId id)) ] (List.map makeOption idAndOpts) | |
selectCountryField : Signal.Address a -> String -> (String -> a) -> Html | |
selectCountryField address currentCountry action = | |
let | |
countries = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas" ,"Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia & Herzegovina","Botswana","Brazil","British Virgin Islands" ,"Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Cape Verde","Cayman Islands","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica" ,"Cote D Ivoire","Croatia","Cruise Ship","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea" ,"Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana" ,"Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India" ,"Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kuwait","Kyrgyz Republic","Laos","Latvia" ,"Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Mauritania" ,"Mauritius","Mexico","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Namibia","Nepal","Netherlands","Netherlands Antilles","New Caledonia" ,"New Zealand","Nicaragua","Niger","Nigeria","Norway","Oman","Pakistan","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal" ,"Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre & Miquelon","Samoa","San Marino","Satellite","Saudi Arabia","Senegal","Serbia","Seychelles" ,"Sierra Leone","Singapore","Slovakia","Slovenia","South Africa","South Korea","Spain","Sri Lanka","St Kitts & Nevis","St Lucia","St Vincent","St. Lucia","Sudan" ,"Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad & Tobago","Tunisia" ,"Turkey","Turkmenistan","Turks & Caicos","Uganda","Ukraine","United Arab Emirates","United Kingdom","Uruguay","Uzbekistan","Venezuela","Vietnam","Virgin Islands (US)" ,"Yemen","Zambia","Zimbabwe"] | |
opts = List.map (\country -> { label = country, value = country, action = action country }) countries | |
in | |
selectField address currentCountry opts | |
type DateOfBirthAction = Noop | ChangeDay Int | ChangeMonth Date.Month | ChangeYear Int | |
dateOfBirthField : Signal.Address a -> Date -> (Date -> a) -> Html | |
dateOfBirthField address currentDate action = | |
let | |
mailbox : Signal.Mailbox DateOfBirthAction | |
mailbox = Signal.mailbox Noop | |
-- So now I need to somehow turn the Signal from this mailbox into a date and send it out on address as action. | |
-- I think maybe I can use forwardTo. Maybe I need map too? Actually I think this is a case for foldp. But how? | |
-- Maybe the problem is that this foldp is disconnected from any other foldp, and it should integrate address/action | |
-- or something. I kind of need something like 'on', but that is native | |
--date : Signal Date | |
date = | |
let | |
dateUpdate : DateOfBirthAction -> Date -> Date | |
dateUpdate action date = case action of | |
ChangeDay day -> dateFromFields day (Date.month date) (Date.year date) 0 0 0 0 | |
ChangeMonth month -> dateFromFields (Date.day date) month (Date.year date) 0 0 0 0 | |
ChangeYear year -> dateFromFields (Date.day date) (Date.month date) year 0 0 0 0 | |
otherwise -> date | |
sendDate : Date -> Signal.Message | |
sendDate date = | |
Signal.message address (action date) | |
date : Signal Date | |
date = Signal.foldp (dateUpdate >> sendDate) currentDate mailbox.signal | |
in | |
-- the thing I want to send to 'address' is 'action latestSignalInDate' | |
1 | |
dateSelect = selectField | |
mailbox.address | |
(Date.day currentDate) | |
(List.map (\day -> { label = toString day, value = day, action = ChangeDay day }) [1..31]) | |
monthSelect = selectField | |
mailbox.address | |
(Date.month currentDate) | |
(List.map (\month -> { label = toString month, value = month, action = ChangeMonth month }) monthList) | |
yearSelect = selectField | |
mailbox.address | |
(Date.day currentDate) | |
(List.map (\year -> { label = toString year, value = year, action = ChangeYear year }) [1935..2015]) -- TODO: up to the current year? | |
in | |
div [] | |
[ dateSelect | |
, monthSelect | |
, yearSelect ] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment