Permalink
Browse files

recaptcha webcomponent

  • Loading branch information...
bigardone committed Sep 9, 2018
1 parent 3149ea4 commit 4e9e88037ba7679e6b20fbb942b1b5379db6f418
View
@@ -3,7 +3,6 @@ module Main exposing (main)
import Html exposing (Html)
import Messages exposing (Msg(..))
import Model exposing (..)
import Ports
import Update exposing (update)
import View exposing (view)
@@ -20,9 +19,9 @@ main =
init : ( Model, Cmd Msg )
init =
initialModel ! [ Ports.initRecaptcha "recaptcha" ]
initialModel ! []
subscriptions : Model -> Sub Msg
subscriptions model =
Ports.setRecaptchaToken SetRecaptchaToken
Sub.none
View
@@ -1,4 +1,4 @@
module Model exposing (..)
module Model exposing (FormFields, Model, SubscribeForm(..), ValidationErrors, emptyFormFields, emptyValidationErrors, extractFormFields, extractValidationErrors, initialModel)
import Dict exposing (Dict)
View

This file was deleted.

Oops, something went wrong.
View
@@ -1,12 +1,11 @@
module Update exposing (update)
import Http exposing (Error(..))
import Json.Decode as Decode
import Commands as Commands
import Decoders exposing (validationErrorsDecoder)
import Http exposing (Error(..))
import Json.Decode as Decode
import Messages exposing (Msg(..))
import Model exposing (..)
import Ports
update : Msg -> Model -> ( Model, Cmd Msg )
@@ -18,33 +17,33 @@ update msg model =
formFields =
extractFormFields model.subscribeForm
in
case msg of
HandleFullNameInput value ->
{ model | subscribeForm = Editing { formFields | fullName = value } } ! []
case msg of
HandleFullNameInput value ->
{ model | subscribeForm = Editing { formFields | fullName = value } } ! []
HandleEmailInput value ->
{ model | subscribeForm = Editing { formFields | email = value } } ! []
HandleEmailInput value ->
{ model | subscribeForm = Editing { formFields | email = value } } ! []
HandleFormSubmit ->
let
newSubscribeForm =
Saving formFields
in
{ model | subscribeForm = newSubscribeForm } ! [ Commands.subscribe newSubscribeForm ]
HandleFormSubmit ->
let
newSubscribeForm =
Saving formFields
in
{ model | subscribeForm = newSubscribeForm } ! [ Commands.subscribe newSubscribeForm ]
SubscribeResponse (Ok result) ->
{ model | subscribeForm = Success } ! []
SubscribeResponse (Ok result) ->
{ model | subscribeForm = Success } ! []
SubscribeResponse (Err (BadStatus response)) ->
case Decode.decodeString validationErrorsDecoder response.body of
Ok validationErrors ->
{ model | subscribeForm = Invalid { formFields | recaptchaToken = Nothing } validationErrors } ! [ Ports.resetRecaptcha () ]
SubscribeResponse (Err (BadStatus response)) ->
case Decode.decodeString validationErrorsDecoder response.body of
Ok validationErrors ->
{ model | subscribeForm = Invalid { formFields | recaptchaToken = Nothing } validationErrors } ! []
Err error ->
{ model | subscribeForm = Errored { formFields | recaptchaToken = Nothing } "Oops! Something went wrong!" } ! [ Ports.resetRecaptcha () ]
Err error ->
{ model | subscribeForm = Errored { formFields | recaptchaToken = Nothing } "Oops! Something went wrong!" } ! []
SubscribeResponse (Err error) ->
{ model | subscribeForm = Errored { formFields | recaptchaToken = Nothing } "Oops! Something went wrong!" } ! [ Ports.resetRecaptcha () ]
SubscribeResponse (Err error) ->
{ model | subscribeForm = Errored { formFields | recaptchaToken = Nothing } "Oops! Something went wrong!" } ! []
SetRecaptchaToken token ->
{ model | subscribeForm = Editing { formFields | recaptchaToken = Just token } } ! []
SetRecaptchaToken token ->
{ model | subscribeForm = Editing { formFields | recaptchaToken = Just token } } ! []
View
@@ -4,6 +4,8 @@ import Dict exposing (Dict)
import Html exposing (Html, form)
import Html.Attributes as Html
import Html.Events as Html
import Json.Decode as Decode
import Json.Encode as Encode
import Messages exposing (Msg(..))
import Model exposing (..)
@@ -69,87 +71,90 @@ formView subscribeForm =
|| saving
|| invalid
in
Html.div
[ Html.class "content" ]
[ Html.h3
[]
[ Html.text "Want to know more?" ]
, Html.p
[]
[ Html.text "Subscribe to stay updated" ]
, formError subscribeForm
, form
[ Html.onSubmit HandleFormSubmit ]
Html.div
[ Html.class "content" ]
[ Html.h3
[]
[ Html.text "Want to know more?" ]
, Html.p
[]
[ Html.text "Subscribe to stay updated" ]
, formError subscribeForm
, form
[ Html.onSubmit HandleFormSubmit ]
[ Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "control" ]
[ Html.input
[ Html.classList
[ ( "input is-medium", True )
, ( "is-danger", Dict.member "full_name" validationErrors )
]
, Html.placeholder "My name is..."
, Html.required True
, Html.value fullName
, Html.onInput HandleFullNameInput
[ Html.class "control" ]
[ Html.input
[ Html.classList
[ ( "input is-medium", True )
, ( "is-danger", Dict.member "full_name" validationErrors )
]
[]
, validationErrorView "full_name" validationErrors
, Html.placeholder "My name is..."
, Html.required True
, Html.value fullName
, Html.onInput HandleFullNameInput
]
[]
, validationErrorView "full_name" validationErrors
]
, Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "control" ]
[ Html.input
[ Html.classList
[ ( "input is-medium", True )
, ( "is-danger", Dict.member "email" validationErrors )
]
, Html.type_ "email"
, Html.placeholder "My email address is..."
, Html.required True
, Html.value email
, Html.onInput HandleEmailInput
]
, Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "control" ]
[ Html.input
[ Html.classList
[ ( "input is-medium", True )
, ( "is-danger", Dict.member "email" validationErrors )
]
[]
, validationErrorView "email" validationErrors
, Html.type_ "email"
, Html.placeholder "My email address is..."
, Html.required True
, Html.value email
, Html.onInput HandleEmailInput
]
]
, Html.div
[ Html.class "field" ]
[ Html.div
[ Html.id "recaptcha" ]
[]
, validationErrorView "recaptcha_token" validationErrors
, validationErrorView "email" validationErrors
]
, Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "control" ]
[ Html.button
[ Html.class "button is-primary is-medium"
, Html.disabled buttonDisabled
]
[ Html.span
[ Html.class "icon" ]
[ Html.i
[ Html.classList
[ ( "fa fa-check", not saving )
, ( "fa fa-circle-o-notch fa-spin", saving )
]
]
, Html.div
[ Html.class "field" ]
[ Html.node "g-recaptcha"
[ Html.id "recaptcha"
, Html.property "token" <| encodeRecaptchaToken recaptchaToken
, Html.on "gotToken" decodeGotToken
]
[]
, validationErrorView "recaptcha_token" validationErrors
]
, Html.div
[ Html.class "field" ]
[ Html.div
[ Html.class "control" ]
[ Html.button
[ Html.class "button is-primary is-medium"
, Html.disabled buttonDisabled
]
[ Html.span
[ Html.class "icon" ]
[ Html.i
[ Html.classList
[ ( "fa fa-check", not saving )
, ( "fa fa-circle-o-notch fa-spin", saving )
]
[]
]
, Html.span
[]
[ Html.text "Subscribe me" ]
]
, Html.span
[]
[ Html.text "Subscribe me" ]
]
]
]
]
]
validationErrorView : String -> ValidationErrors -> Html Msg
@@ -175,3 +180,18 @@ formError subscribeForm =
_ ->
Html.text ""
encodeRecaptchaToken : Maybe String -> Encode.Value
encodeRecaptchaToken maybeRecaptchaToken =
case maybeRecaptchaToken of
Just recaptchaToken ->
Encode.string recaptchaToken
Nothing ->
Encode.null
decodeGotToken : Decode.Decoder Msg
decodeGotToken =
Decode.map SetRecaptchaToken <| Decode.at [ "target", "token" ] <| Decode.string
View
@@ -1,23 +1,12 @@
import Elm from './elm/main';
import Recaptcha from './components/recaptcha';
window.customElements.define('g-recaptcha', Recaptcha);
window.onloadCallback = () => {
const formContainer = document.querySelector('#form_container');
if (formContainer) {
const app = Elm.Main.embed(formContainer);
let recaptcha;
app.ports.initRecaptcha.subscribe((id) => {
window.requestAnimationFrame(() => {
recaptcha = grecaptcha.render(id, {
hl: 'en',
sitekey: '6LcjgjsUAAAAAHIY0kC1fz24mSnB_uinM8k6U1K-',
callback: app.ports.setRecaptchaToken.send,
});
});
});
app.ports.resetRecaptcha.subscribe(() => {
grecaptcha.reset(recaptcha);
});
Elm.Main.embed(formContainer);
}
};
@@ -0,0 +1,31 @@
export default class Recaptcha extends HTMLElement {
constructor() {
const self = super();
self._token = null;
self._grecaptcha = null;
return self;
}
set token(token) {
this._token = token;
if (this._grecaptcha !== null && token === null) grecaptcha.reset(this._grecaptcha);
}
get token() {
return this._token;
}
connectedCallback() {
this._grecaptcha = grecaptcha.render(this, {
hl: 'en',
sitekey: '6LdHSG8UAAAAAO-NxfnWj30tk8_O31eTvvyQUyJA',
callback: (token) => {
this._token = token;
this.dispatchEvent(new CustomEvent('gotToken'));
},
});
}
}
Oops, something went wrong.

0 comments on commit 4e9e880

Please sign in to comment.