Во-первых, мы хотим иметь возможность пометить каждый фокусируемый элемент в группе некоторым атрибутом, поэтому, когда мы переключаем элементы, мы узнаем, находимся ли мы в одной группе или нет. Это может быть достигнуто с помощью атрибутов данных.
groupIdAttribute groupId =
Html.Attributes.attribute "data-group-id" groupId
Далее, нам нужно декодировать полезную нагрузку события для события onBlur
, чтобы увидеть, отличается ли target
от relatedTarget
(то, что получит фокус). И сообщить об изменении. (обратите внимание, что здесь мы ссылаемся на data-group-id
по пути "dataset", "groupId"
)
decodeGroupIdChanged msg =
Json.Decode.oneOf
[ Json.Decode.map2
(\a b ->
if a /= b then
Just a
else
Nothing
)
(Json.Decode.at [ "target", "dataset", "groupId" ] Json.Decode.string)
(Json.Decode.at [ "relatedTarget", "dataset", "groupId" ] Json.Decode.string)
, Json.Decode.at [ "target", "dataset", "groupId" ] Json.Decode.string
|> Json.Decode.andThen (\a -> Json.Decode.succeed (Just a))
]
|> Json.Decode.andThen
(\maybeChanged ->
case maybeChanged of
Just a ->
Json.Decode.succeed (msg a)
Nothing ->
Json.Decode.fail "no change"
)
Теперь мы можем создать onGroupLoss
слушателя:
onGroupFocusLoss msg =
Html.Events.on "blur" (decodeGroupIdChanged msg)
И вот так:
input [onGroupFocusLoss GroupFocusLoss, groupIdAttribute "a"]
Вот пример (обратите внимание, что он построен с elm-ui, поэтому есть немного дополнительного кода.)
https://ellie -app.com / 3nkBCXJqjQTa1