1
1
mirror of https://github.com/aelve/guide.git synced 2024-11-27 10:10:50 +03:00

Add category heading editing

This commit is contained in:
Artyom 2016-02-17 19:43:35 +03:00
parent eb89d3230d
commit 0d51bb67d4
2 changed files with 93 additions and 13 deletions

View File

@ -116,6 +116,9 @@ main = runSpock 8080 $ spockT id $ do
-- them and inject into the page. We don't want to duplicate rendering on
-- server side and on client side.
-- TODO: rename methods to “category/add” etc
-- TODO: move Javascript here
-- TODO: turn traversals into lenses
Spock.post "/add/category" $ do
title' <- param' "title"
id' <- liftIO (newId stateVar)
@ -145,21 +148,34 @@ main = runSpock 8080 $ spockT id $ do
Spock.post ("/add/pros" <//> var) $ \itemId' -> do
content <- param' "content"
changedItems <- withS $ do
changedItem <- withS $ do
itemById itemId' . pros %= (++ [content])
gets (^.. itemById itemId')
case changedItems of
[x] -> lucid $ renderItem x
_ -> return ()
gets (^?! itemById itemId')
lucid $ renderItem changedItem
Spock.post ("/add/cons" <//> var) $ \itemId' -> do
content <- param' "content"
changedItems <- withS $ do
changedItem <- withS $ do
itemById itemId' . cons %= (++ [content])
gets (^.. itemById itemId')
case changedItems of
[x] -> lucid $ renderItem x
_ -> return ()
gets (^?! itemById itemId')
lucid $ renderItem changedItem
Spock.post ("/edit/category" <//> var <//> "title") $ \catId' -> do
title' <- param' "title"
changedCategory <- withS $ do
categoryById catId' . title .= title'
gets (^?! categoryById catId')
lucid $ renderCategoryHeading changedCategory
Spock.get ("/edit/category" <//> var <//> "title/edit") $ \catId' -> do
category <- withS $ do
gets (^?! categoryById catId')
lucid $ renderCategoryHeadingEdit category
Spock.get ("/edit/category" <//> var <//> "title/cancel") $ \catId' -> do
category <- withS $ do
gets (^?! categoryById catId')
lucid $ renderCategoryHeading category
renderRoot :: S -> Html ()
renderRoot s = do
@ -171,11 +187,29 @@ renderRoot s = do
let handler = "addCategory(this.value);"
input_ [type_ "text", placeholder_ "new category", submitFunc handler]
renderCategoryHeading :: Category -> Html ()
renderCategoryHeading category =
h2_ $ do
-- TODO: make category headings anchor links
toHtml (category^.title)
" "
textButton "edit" $ format "startCategoryHeadingEditing({});"
[category^.catId]
renderCategoryHeadingEdit :: Category -> Html ()
renderCategoryHeadingEdit category =
h2_ $ do
let handler = format "finishCategoryHeadingEditing({}, this.value);"
[category^.catId]
input_ [type_ "text", value_ (category^.title), submitFunc handler]
" "
textButton "cancel" $ format "cancelCategoryHeadingEditing({});"
[category^.catId]
renderCategory :: Category -> Html ()
renderCategory category =
div_ [id_ (format "cat{}" [category^.catId])] $ do
-- TODO: make category headings links
h2_ (toHtml (category^.title))
renderCategoryHeading category
-- Note: if you change anything here, look at js.js/addLibrary to see
-- whether it has to be updated.
div_ [class_ "items"] $
@ -225,6 +259,16 @@ submitFunc f = onkeyup_ $ format
\ this.value = ''; }"
[f]
-- A text button looks like “[cancel]”
textButton
:: Text -- ^ Button text
-> Text -- ^ Onclick handler
-> Html ()
textButton caption handler = span_ $ do
"["
a_ [href_ "javascript:void(0)", onclick_ handler] (toHtml caption)
"]"
lucid :: Html a -> ActionT IO a
lucid = html . TL.toStrict . renderText

View File

@ -14,6 +14,36 @@ function addCategory(s) {
});
}
// start category heading editing (this happens when you click on “[edit]”)
//
// this turns the heading into an editbox, and adds a [cancel] link
function startCategoryHeadingEditing(catId) {
$.get("/edit/category/"+catId+"/title/edit")
.done(function(data) {
setCategoryHeadingHtml(catId, data);
});
}
// finish category heading editing (this happens when you submit the field)
//
// this turns the heading with the editbox back into a simple text heading
function finishCategoryHeadingEditing(catId, s) {
$.post("/edit/category/"+catId+"/title", {title: s})
.done(function(data) {
setCategoryHeadingHtml(catId, data);
});
}
// cancel category heading editing
//
// this turns the heading with the editbox back into a simple text heading
function cancelCategoryHeadingEditing(catId) {
$.get("/edit/category/"+catId+"/title/cancel")
.done(function(data) {
setCategoryHeadingHtml(catId, data);
});
}
// add pros to some item
function addPros(itemId, s) {
$.post("/add/pros/" + itemId, {content: s})
@ -32,4 +62,10 @@ function addCons(itemId, s) {
// reload an item
function setItemHtml(itemId, data) {
$("#item"+itemId).replaceWith(data) }
$("#item"+itemId).replaceWith(data);
}
// reload a category heading
function setCategoryHeadingHtml(catId, data) {
$("#cat"+catId+" > h2").replaceWith(data);
}