mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-11-30 23:06:10 +03:00
Add edit form.
This commit is contained in:
parent
ef0e421aea
commit
314f15dbf3
@ -188,6 +188,13 @@ action routeParams =
|
|||||||
|> Maybe.withDefault Session.empty
|
|> Maybe.withDefault Session.empty
|
||||||
in
|
in
|
||||||
case formResult of
|
case formResult of
|
||||||
|
Ok (EditItem itemId) ->
|
||||||
|
( okSessionThing
|
||||||
|
-- TODO implement
|
||||||
|
, Response.render {}
|
||||||
|
)
|
||||||
|
|> DataSource.succeed
|
||||||
|
|
||||||
Ok (DeleteItem itemId) ->
|
Ok (DeleteItem itemId) ->
|
||||||
okSessionThing
|
okSessionThing
|
||||||
|> Session.get "sessionId"
|
|> Session.get "sessionId"
|
||||||
@ -406,14 +413,17 @@ view maybeUrl sharedModel model app =
|
|||||||
, body =
|
, body =
|
||||||
[ div
|
[ div
|
||||||
[ class "todomvc-wrapper"
|
[ class "todomvc-wrapper"
|
||||||
, style "visibility" "hidden"
|
|
||||||
]
|
]
|
||||||
[ section
|
[ section
|
||||||
[ class "todoapp" ]
|
[ class "todoapp" ]
|
||||||
[ newItemForm
|
[ newItemForm
|
||||||
|> Form.toDynamicFetcher "new-item"
|
|> Form.toDynamicFetcher "new-item"
|
||||||
|> Form.withOnSubmit (\_ -> ClearNewItemInput)
|
|> Form.withOnSubmit (\_ -> ClearNewItemInput)
|
||||||
|> Form.renderHtml [] Nothing app ()
|
|> Form.renderHtml
|
||||||
|
[ class "create-form" ]
|
||||||
|
Nothing
|
||||||
|
app
|
||||||
|
()
|
||||||
, lazy3 viewEntries app app.data.visibility optimisticEntities
|
, lazy3 viewEntries app app.data.visibility optimisticEntities
|
||||||
, lazy2 viewControls app.data.visibility optimisticEntities
|
, lazy2 viewControls app.data.visibility optimisticEntities
|
||||||
]
|
]
|
||||||
@ -459,6 +469,7 @@ type Action
|
|||||||
= CreateItem String
|
= CreateItem String
|
||||||
| DeleteItem String
|
| DeleteItem String
|
||||||
| ToggleItem ( Bool, String )
|
| ToggleItem ( Bool, String )
|
||||||
|
| EditItem ( String, String )
|
||||||
|
|
||||||
|
|
||||||
completeItemForm : Form.HtmlForm String Action Todo Msg
|
completeItemForm : Form.HtmlForm String Action Todo Msg
|
||||||
@ -547,12 +558,16 @@ viewEntries app visibility entries =
|
|||||||
[ class "main"
|
[ class "main"
|
||||||
, style "visibility" cssVisibility
|
, style "visibility" cssVisibility
|
||||||
]
|
]
|
||||||
[ input
|
[ button
|
||||||
[ class "toggle-all"
|
[ classList
|
||||||
, type_ "checkbox"
|
[ ( "toggle-all", True )
|
||||||
|
, ( "checked"
|
||||||
|
, True
|
||||||
|
)
|
||||||
|
]
|
||||||
, name "toggle"
|
, name "toggle"
|
||||||
, checked allCompleted
|
|
||||||
|
|
||||||
|
--, checked allCompleted
|
||||||
--, onClick (CheckAll (not allCompleted))
|
--, onClick (CheckAll (not allCompleted))
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
@ -590,10 +605,12 @@ viewEntry app todo =
|
|||||||
Nothing
|
Nothing
|
||||||
app
|
app
|
||||||
todo
|
todo
|
||||||
, label
|
, editItemForm
|
||||||
[--onDoubleClick (EditingEntry todo.id True)
|
|> Form.toDynamicFetcher ("edit-" ++ uuidToString todo.id)
|
||||||
]
|
|> Form.renderHtml []
|
||||||
[ text todo.description ]
|
Nothing
|
||||||
|
app
|
||||||
|
todo
|
||||||
, if uuidToString todo.id == "" then
|
, if uuidToString todo.id == "" then
|
||||||
Html.text ""
|
Html.text ""
|
||||||
|
|
||||||
@ -605,20 +622,39 @@ viewEntry app todo =
|
|||||||
app
|
app
|
||||||
todo
|
todo
|
||||||
]
|
]
|
||||||
, input
|
|
||||||
[ class "edit"
|
|
||||||
, value todo.description
|
|
||||||
, name "title"
|
|
||||||
, id ("todo-" ++ uuidToString todo.id)
|
|
||||||
|
|
||||||
--, onInput (UpdateEntry todo.id)
|
|
||||||
--, onBlur (EditingEntry todo.id False)
|
|
||||||
--, onEnter (EditingEntry todo.id False)
|
|
||||||
]
|
|
||||||
[]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
editItemForm : Form.HtmlForm String Action Todo Msg
|
||||||
|
editItemForm =
|
||||||
|
Form.init
|
||||||
|
(\itemId description ->
|
||||||
|
{ combine =
|
||||||
|
Validation.succeed Tuple.pair
|
||||||
|
|> Validation.andMap itemId
|
||||||
|
|> Validation.andMap description
|
||||||
|
|> Validation.map EditItem
|
||||||
|
, view =
|
||||||
|
\formState ->
|
||||||
|
[ FieldView.input
|
||||||
|
[ class "edit-input"
|
||||||
|
, name "title"
|
||||||
|
, id ("todo-" ++ uuidToString formState.data.id)
|
||||||
|
]
|
||||||
|
description
|
||||||
|
, Html.button [ style "display" "none" ] [ Html.text "Edit" ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> Form.hiddenField "itemId" (Field.text |> Field.required "Must be present")
|
||||||
|
|> Form.field "description"
|
||||||
|
(Field.text
|
||||||
|
|> Field.required "Must be present"
|
||||||
|
|> Field.withInitialValue (.description >> Form.Value.string)
|
||||||
|
)
|
||||||
|
|> Form.hiddenKind ( "kind", "edit-item" ) "Expected kind"
|
||||||
|
|
||||||
|
|
||||||
uuidToString : Uuid -> String
|
uuidToString : Uuid -> String
|
||||||
uuidToString (Uuid uuid) =
|
uuidToString (Uuid uuid) =
|
||||||
uuid
|
uuid
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
|
/* Create to Kent C. Dodds for modified TodoMVC styles: https://github.com/kentcdodds/remix-todomvc/blob/97bbf6c548c71e1535ebe05b707b985f19caf953/app/routes/todos.css */
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todomvc-wrapper {
|
|
||||||
visibility: visible !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -18,15 +16,12 @@ button {
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-font-smoothing: antialiased;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
font-smoothing: antialiased;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
color: #4d4d4d;
|
color: #4d4d4d;
|
||||||
@ -34,26 +29,15 @@ body {
|
|||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-font-smoothing: antialiased;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
font-smoothing: antialiased;
|
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
|
||||||
input[type="checkbox"] {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todoapp {
|
.todoapp {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
margin: 130px 0 40px 0;
|
margin: 130px 0 40px 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||||
0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.todoapp input::-webkit-input-placeholder {
|
.todoapp input::-webkit-input-placeholder {
|
||||||
@ -88,7 +72,7 @@ input[type="checkbox"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.new-todo,
|
.new-todo,
|
||||||
.edit {
|
.edit-input {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -96,23 +80,28 @@ input[type="checkbox"] {
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border: 1px solid #999;
|
border: 1px solid #999;
|
||||||
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
|
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-font-smoothing: antialiased;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
font-smoothing: antialiased;
|
}
|
||||||
|
|
||||||
|
.edit-input {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-input:not(:focus) {
|
||||||
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-todo {
|
.new-todo {
|
||||||
padding: 16px 16px 16px 60px;
|
padding: 16px 16px 16px 60px;
|
||||||
border: none;
|
border: none;
|
||||||
background: rgba(0, 0, 0, 0.003);
|
background: rgba(0, 0, 0, 0.003);
|
||||||
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
|
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
@ -121,28 +110,27 @@ input[type="checkbox"] {
|
|||||||
border-top: 1px solid #e6e6e6;
|
border-top: 1px solid #e6e6e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
label[for='toggle-all'] {
|
.main.no-todos {
|
||||||
display: none;
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main.no-todos .toggle-all {
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-all {
|
.toggle-all {
|
||||||
position: absolute;
|
|
||||||
top: -55px;
|
|
||||||
left: -12px;
|
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
text-align: center;
|
|
||||||
border: none; /* Mobile Safari */
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-all:before {
|
|
||||||
content: '❯';
|
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
|
position: absolute;
|
||||||
|
top: -52px;
|
||||||
|
left: 0;
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
color: #e6e6e6;
|
color: #e6e6e6;
|
||||||
padding: 10px 27px 10px 27px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-all:checked:before {
|
.toggle-all.checked {
|
||||||
color: #737373;
|
color: #737373;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +158,7 @@ label[for='toggle-all'] {
|
|||||||
.todo-list li.editing .edit {
|
.todo-list li.editing .edit {
|
||||||
display: block;
|
display: block;
|
||||||
width: 506px;
|
width: 506px;
|
||||||
padding: 13px 17px 12px 17px;
|
padding: 12px 16px;
|
||||||
margin: 0 0 0 43px;
|
margin: 0 0 0 43px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,49 +166,40 @@ label[for='toggle-all'] {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li .toggle {
|
.todo-list li button.toggle {
|
||||||
text-align: center;
|
z-index: 1;
|
||||||
width: 40px;
|
padding: 10px;
|
||||||
/* auto, since non-WebKit browsers doesn't support input styling */
|
|
||||||
height: auto;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
border: none; /* Mobile Safari */
|
display: flex;
|
||||||
-webkit-appearance: none;
|
align-items: center;
|
||||||
appearance: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li .toggle:after {
|
.todo-list li input {
|
||||||
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo-list li .toggle:checked:after {
|
|
||||||
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo-list li label {
|
|
||||||
white-space: pre-line;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
padding: 15px 60px 15px 15px;
|
padding: 15px 15px 15px 60px;
|
||||||
margin-left: 45px;
|
|
||||||
display: block;
|
display: block;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
transition: color 0.4s;
|
transition: color 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li.completed label {
|
.todo-list li.completed input {
|
||||||
color: #d9d9d9;
|
color: #d9d9d9;
|
||||||
text-decoration: line-through;
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li .destroy {
|
.todo-list li .destroy {
|
||||||
display: none;
|
opacity: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
bottom: 0;
|
|
||||||
|
/* this hack makes the "x" look centered */
|
||||||
|
bottom: -3px;
|
||||||
|
padding-bottom: 43px;
|
||||||
|
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
@ -230,24 +209,18 @@ label[for='toggle-all'] {
|
|||||||
transition: color 0.2s ease-out;
|
transition: color 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li .destroy:hover {
|
.todo-list li .destroy:hover,
|
||||||
|
.todo-list li .destroy:focus {
|
||||||
color: #af5b5e;
|
color: #af5b5e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li .destroy:after {
|
.todo-list li .destroy:after {
|
||||||
content: '×';
|
content: "×";
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-list li:hover .destroy {
|
.todo-list li:hover .destroy,
|
||||||
display: block;
|
.todo-list li .destroy:focus {
|
||||||
}
|
opacity: 1;
|
||||||
|
|
||||||
.todo-list li .edit {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo-list li.editing:last-child {
|
|
||||||
margin-bottom: -1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
@ -259,18 +232,16 @@ label[for='toggle-all'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.footer:before {
|
.footer:before {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6,
|
||||||
0 8px 0 -3px #f6f6f6,
|
0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6,
|
||||||
0 9px 1px -3px rgba(0, 0, 0, 0.2),
|
0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
||||||
0 16px 0 -6px #f6f6f6,
|
|
||||||
0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-count {
|
.todo-count {
|
||||||
@ -304,7 +275,6 @@ label[for='toggle-all'] {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters li a.selected,
|
|
||||||
.filters li a:hover {
|
.filters li a:hover {
|
||||||
border-color: rgba(175, 47, 47, 0.1);
|
border-color: rgba(175, 47, 47, 0.1);
|
||||||
}
|
}
|
||||||
@ -320,7 +290,6 @@ html .clear-completed:active {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.clear-completed:hover {
|
.clear-completed:hover {
|
||||||
@ -349,28 +318,6 @@ html .clear-completed:active {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Hack to remove background from Mobile Safari.
|
|
||||||
Can't use it globally since it destroys checkboxes in Firefox
|
|
||||||
*/
|
|
||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
|
||||||
.toggle-all,
|
|
||||||
.todo-list li .toggle {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo-list li .toggle {
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-all {
|
|
||||||
-webkit-transform: rotate(90deg);
|
|
||||||
transform: rotate(90deg);
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 430px) {
|
@media (max-width: 430px) {
|
||||||
.footer {
|
.footer {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@ -379,4 +326,41 @@ html .clear-completed:active {
|
|||||||
.filters {
|
.filters {
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: rgb(185, 28, 28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-form {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-todo-error {
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-form {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-update-error {
|
||||||
|
font-size: 14px;
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
bottom: 4px;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user