-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCustomElement.elm
173 lines (141 loc) · 4.89 KB
/
CustomElement.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
port module CustomElement exposing (init, subscriptions, update, view)
--import Html.Attributes exposing (class, classList)
--import Html.Events exposing (onClick)
import Dict
import Html exposing (Html, div, h3, text)
import Json.Decode exposing (Value, decodeValue)
import Json.Encode as Encode
import Json.Form
import Json.Form.Config exposing (Config)
import Json.Schema.Definitions exposing (Schema)
import Json.Value as JsonValue exposing (JsonValue, decoder)
type alias Model =
{ form : Json.Form.Model
, config : Config
, schema : Json.Schema.Definitions.Schema
, value : Maybe JsonValue.JsonValue
}
init : Value -> ( Model, Cmd Msg )
init v =
let
schema =
v
|> decodeValue (Json.Decode.field "schema" Json.Schema.Definitions.decoder)
-- |> Result.mapError (Debug.log "schema parse error")
|> Result.withDefault Json.Schema.Definitions.blankSchema
config =
v
|> decodeValue (Json.Decode.field "config" Json.Form.Config.decoder)
-- |> Result.mapError (Debug.log "config parse error")
|> Result.withDefault Json.Form.Config.defaultConfig
value =
v
|> decodeValue (Json.Decode.field "value" JsonValue.decoder)
|> Result.toMaybe
in
initForm schema value config
initForm : Schema -> Maybe JsonValue -> Config -> ( Model, Cmd Msg )
initForm schema value config =
let
form =
value
|> Json.Form.init config schema
|> Tuple.first
in
( { form = form
, value = form.value
, schema = schema
, config = config
}
, [ ( "value"
, form.value
|> Maybe.map JsonValue.encode
|> Maybe.withDefault Encode.null
)
, ( "isValid", form.errors |> Dict.isEmpty |> Encode.bool )
, ( "errors", form.errors |> Encode.dict (String.join "/") (Encode.list Encode.string) )
]
|> Encode.object
|> valueUpdated
)
type Msg
= JsonFormMsg Json.Form.Msg
| ChangeValue Value
| ChangeSchema Value
| ChangeConfig Value
update : Msg -> Model -> ( Model, Cmd Msg )
update message model =
case message of
ChangeConfig v ->
case v |> decodeValue Json.Form.Config.decoder of
Ok config ->
( { model
| config = config
, form = model.form |> Json.Form.updateConfig config
}
, Cmd.none
)
Err _ ->
( model
, Cmd.none
)
ChangeSchema v ->
let
schema =
v
|> decodeValue Json.Schema.Definitions.decoder
|> Result.withDefault Json.Schema.Definitions.blankSchema
in
( { model | form = model.form |> Json.Form.updateSchema schema }, Cmd.none )
ChangeValue v ->
let
value =
v
|> decodeValue JsonValue.decoder
|> Result.toMaybe
in
initForm model.schema value model.config
JsonFormMsg msg ->
let
( ( m, cmd ), exMsg ) =
Json.Form.update msg model.form
( value, exCmd ) =
case exMsg of
Json.Form.UpdateValue v errors ->
( v
, Encode.object
[ ( "value"
, v
|> Maybe.withDefault JsonValue.NullValue
|> JsonValue.encode
)
, ( "isValid", errors |> Dict.isEmpty |> Encode.bool )
, ( "errors", errors |> Encode.dict (String.join "/") (Encode.list Encode.string) )
]
|> valueUpdated
)
_ ->
( model.value, Cmd.none )
in
( { model
| form = m
, value = value
}
, Cmd.batch [ cmd |> Cmd.map JsonFormMsg, exCmd ]
)
view : Model -> Html Msg
view model =
model.form
|> Json.Form.view
|> Html.map JsonFormMsg
port valueChange : (Value -> msg) -> Sub msg
port valueUpdated : Value -> Cmd msg
port schemaChange : (Value -> msg) -> Sub msg
port configChange : (Value -> msg) -> Sub msg
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.batch
[ valueChange ChangeValue
, schemaChange ChangeSchema
, configChange ChangeConfig
]