mirror of
https://github.com/aelve/guide.git
synced 2024-11-23 21:13:07 +03:00
Add search
This commit is contained in:
parent
75067a7748
commit
059718e9b3
12
src/JS.hs
12
src/JS.hs
@ -34,6 +34,8 @@ allJSFunctions = JS . T.unlines . map fromJS $ [
|
|||||||
-- Utilities
|
-- Utilities
|
||||||
replaceWithData, appendData,
|
replaceWithData, appendData,
|
||||||
moveNodeUp, moveNodeDown,
|
moveNodeUp, moveNodeDown,
|
||||||
|
-- Search
|
||||||
|
search,
|
||||||
-- Add methods
|
-- Add methods
|
||||||
addLibrary, addCategory,
|
addLibrary, addCategory,
|
||||||
addPro, addCon,
|
addPro, addCon,
|
||||||
@ -147,6 +149,16 @@ moveNodeDown =
|
|||||||
el.next().after(el);
|
el.next().after(el);
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
search :: JSFunction a => a
|
||||||
|
search =
|
||||||
|
makeJSFunction "search" ["node", "s"]
|
||||||
|
-- TODO: set address bar to “/?query=...” so that the user would be able to
|
||||||
|
-- see/share the search URL
|
||||||
|
[text|
|
||||||
|
$.post("/search", {query: s})
|
||||||
|
.done(replaceWithData(node));
|
||||||
|
|]
|
||||||
|
|
||||||
-- | Create a new category.
|
-- | Create a new category.
|
||||||
addCategory :: JSFunction a => a
|
addCategory :: JSFunction a => a
|
||||||
addCategory =
|
addCategory =
|
||||||
|
33
src/Main.hs
33
src/Main.hs
@ -3,6 +3,7 @@ OverloadedStrings,
|
|||||||
TemplateHaskell,
|
TemplateHaskell,
|
||||||
RankNTypes,
|
RankNTypes,
|
||||||
FlexibleInstances,
|
FlexibleInstances,
|
||||||
|
FlexibleContexts,
|
||||||
QuasiQuotes,
|
QuasiQuotes,
|
||||||
ScopedTypeVariables,
|
ScopedTypeVariables,
|
||||||
FunctionalDependencies,
|
FunctionalDependencies,
|
||||||
@ -263,6 +264,21 @@ addMethods = Spock.subcomponent "add" $ do
|
|||||||
|
|
||||||
otherMethods :: SpockM () () (IORef GlobalState) ()
|
otherMethods :: SpockM () () (IORef GlobalState) ()
|
||||||
otherMethods = do
|
otherMethods = do
|
||||||
|
-- Search
|
||||||
|
Spock.post "search" $ do
|
||||||
|
query <- param' "query"
|
||||||
|
let queryWords = T.words query
|
||||||
|
let rank :: Category -> Int
|
||||||
|
rank cat = sum [
|
||||||
|
length (queryWords `intersect` (cat^..items.each.name)),
|
||||||
|
length (queryWords `intersect` T.words (cat^.title)) ]
|
||||||
|
cats <- withGlobal (use categories)
|
||||||
|
let rankedCats
|
||||||
|
| null queryWords = cats
|
||||||
|
| otherwise = filter ((/= 0) . rank) .
|
||||||
|
reverse . sortOn rank $ cats
|
||||||
|
lucid $ renderCategoryList rankedCats
|
||||||
|
|
||||||
-- Moving things
|
-- Moving things
|
||||||
Spock.subcomponent "move" $ do
|
Spock.subcomponent "move" $ do
|
||||||
-- Move trait
|
-- Move trait
|
||||||
@ -323,11 +339,18 @@ renderRoot globalState = do
|
|||||||
write anything here. Also, Markdown is supported, so use
|
write anything here. Also, Markdown is supported, so use
|
||||||
bold/italics/code if you need to.
|
bold/italics/code if you need to.
|
||||||
|]
|
|]
|
||||||
categoriesNode <- div_ [id_ "categories"] $ do
|
let searchHandler s = JS.search ("#categories" :: Text, s)
|
||||||
mapM_ renderCategory (globalState ^. categories)
|
input_ [type_ "text", placeholder_ "search",
|
||||||
thisNode
|
onInputSubmit searchHandler]
|
||||||
let handler s = JS.addCategory (categoriesNode, s)
|
renderCategoryList (globalState^.categories)
|
||||||
input_ [type_ "text", placeholder_ "new category", onInputSubmit handler]
|
let addCategoryHandler s = JS.addCategory ("#categories" :: Text, s)
|
||||||
|
input_ [type_ "text", placeholder_ "new category",
|
||||||
|
onInputSubmit addCategoryHandler]
|
||||||
|
|
||||||
|
renderCategoryList :: [Category] -> HtmlT IO ()
|
||||||
|
renderCategoryList cats =
|
||||||
|
div_ [id_ "categories"] $
|
||||||
|
mapM_ renderCategory cats
|
||||||
|
|
||||||
renderCategoryTitle :: Editable -> Category -> HtmlT IO ()
|
renderCategoryTitle :: Editable -> Category -> HtmlT IO ()
|
||||||
renderCategoryTitle editable category =
|
renderCategoryTitle editable category =
|
||||||
|
Loading…
Reference in New Issue
Block a user