Skip to content

Instantly share code, notes, and snippets.

@datakurre
Last active May 12, 2016 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save datakurre/3e4a71eb47894ba26219f0bb4e3d51d6 to your computer and use it in GitHub Desktop.
Save datakurre/3e4a71eb47894ba26219f0bb4e3d51d6 to your computer and use it in GitHub Desktop.
Creative Commons license chooser widget in Elm
.license-selector label {
padding: 0 1em 0 5px;
}
import { LicenseSelector } from './LicenseSelector';
import Registry from 'pat-registry';
Registry.register({
name: 'license-selector',
trigger: '.pat-license-selector',
init ($el) {
// Get the form input element and hide it
const el = $el.hide().get(0);
// Create container for the widget
const container = document.createElement('div');
el.parentNode.insertBefore(container, el);
container.className = 'license-selector';
// Wire up the widget
const widget = LicenseSelector.embed(container);
widget.ports.outbound.subscribe((value) => $el.val(value));
setTimeout(() => widget.ports.inbound.send($el.val()));
}
});
port module LicenseSelector exposing (..)
import Html exposing (Html, button, div, img, input, label, p, text)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck)
import String
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ derivates : Derivates
, commercial : Commercial
}
type Derivates
= AllowDerivates
| NoDerivates
| DerivatesSharedAlike
type Commercial
= AllowCommercialUse
| NoCommercialUse
init : (Model, Cmd Msg)
init =
(Model AllowDerivates AllowCommercialUse, Cmd.none)
-- UPDATE
type Msg
= DoAllowDerivates
| DisallowDerivates
| RequireDerivatesSharedAlike
| DoAllowCommercialUse
| DisallowCommercialUse
| ReadInbound (String)
port outbound : String -> Cmd msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
DoAllowDerivates ->
( { model | derivates = AllowDerivates }
, outbound (serialize { model | derivates = AllowDerivates })
)
DisallowDerivates ->
( { model | derivates = NoDerivates }
, outbound (serialize { model | derivates = NoDerivates })
)
RequireDerivatesSharedAlike ->
( { model | derivates = DerivatesSharedAlike }
, outbound (serialize { model | derivates = DerivatesSharedAlike })
)
DoAllowCommercialUse ->
( { model | commercial = AllowCommercialUse }
, outbound (serialize { model | commercial = AllowCommercialUse })
)
DisallowCommercialUse ->
( { model | commercial = NoCommercialUse }
, outbound (serialize { model | commercial = NoCommercialUse })
)
ReadInbound serialized ->
( deserialize serialized, Cmd.none )
deserialize : String -> Model
deserialize serialized =
Model (
if String.contains "-nd" serialized then NoDerivates
else if String.contains "-sa" serialized then DerivatesSharedAlike
else AllowDerivates
) (
if String.contains "-nc" serialized then NoCommercialUse
else AllowCommercialUse
)
serialize : Model -> String
serialize model =
"by" ++ (
case model.commercial of
AllowCommercialUse -> ""
NoCommercialUse -> "-nc") ++ (
case model.derivates of
AllowDerivates -> ""
NoDerivates -> "-nd"
DerivatesSharedAlike -> "-sa")
-- SUBSCRIPTIONS
port inbound : (String -> msg) -> Sub msg
subscriptions : Model -> Sub Msg
subscriptions model =
inbound ReadInbound
-- VIEW
view : Model -> Html Msg
view model =
let
allowDerivates =
model.derivates == AllowDerivates
noDerivates =
model.derivates == NoDerivates
derivatesSharedAlike =
model.derivates == DerivatesSharedAlike
allowCommercialUse =
model.commercial == AllowCommercialUse
noCommercialUse =
model.commercial == NoCommercialUse
in
div []
[ div []
[ p [] [ text "Allow adaptations of your work to be shared?" ]
, input [ type' "radio"
, id "allowDerivates"
, checked allowDerivates
, onCheck (\_ -> DoAllowDerivates)
] [text "Yes" ]
, label [ for "allowDerivates" ] [ text "Yes" ]
, input [ type' "radio"
, id "noDerivates"
, checked noDerivates
, onCheck (\_ -> DisallowDerivates)
] [ text "No" ]
, label [ for "noDerivates" ] [ text "No" ]
, input [ type' "radio"
, id "derivatesSharedAlike"
, checked derivatesSharedAlike
, onCheck (\_ -> RequireDerivatesSharedAlike)
] [ text "Alike" ]
, label [ for "derivatesSharedAlike" ] [ text "Yes, as long as others share alike" ]
]
, div []
[ p [] [ text "Allow commercial uses of your work?" ]
, input [ type' "radio"
, id "allowCommercialUse"
, checked allowCommercialUse
, onCheck (\_ -> DoAllowCommercialUse)
] [ text "Yes" ]
, label [ for "allowCommercialUse" ] [ text "Yes" ]
, input [ type' "radio"
, id "noCommercialUse"
, checked noCommercialUse
, onCheck (\_ -> DisallowCommercialUse)
] [ text "No" ]
, label [ for "noCommercialUse" ] [ text "No" ]
]
, p []
[ img [ src ("https://i.creativecommons.org/l/"
++ (serialize model) ++ "/4.0/88x31.png") ] []
]
]
@datakurre
Copy link
Author

@zemm This is pretty verbose. Request for refactoring this to look nicer :)

@datakurre
Copy link
Author

@zemm Of course, I can refactor radio input rendering into a reused function, but how about types, their values and naming of everything? (Not quite satisfied with this first try.)

@zemm
Copy link

zemm commented May 12, 2016

My first rusty refactoring thoughts https://gist.github.com/zemm/14e15fddcaf66da7c040e7b16400d64c ... Couple more thoughts, but need more practice and time to play around

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment