Skip to content

Commit ba1a80f

Browse files
committed
Add EditHeadings example without Signals
1 parent 8e7c3a7 commit ba1a80f

File tree

5 files changed

+148
-139
lines changed

5 files changed

+148
-139
lines changed

examples/index.html

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,11 @@
11
<!doctype>
22
<html>
33
<head>
4-
<title>A purescript-concur-react example</title>
4+
<title>Concur Purescript Examples</title>
55
</head>
66
<body>
77
<h1>Concur Purescript Examples</h1>
8-
<hr>
9-
<h2>Wire Example</h2>
10-
<div id="wire"></div>
11-
<hr>
12-
<h2>Hello World</h2>
13-
<div id="hello"></div>
14-
<hr>
15-
<h2>Counter</h2>
16-
<div id="counter"></div>
17-
<hr>
18-
<h2>Count focus</h2>
19-
<div id="focusCount"></div>
20-
<hr>
21-
<h2>Login</h2>
22-
<div id="login"></div>
23-
<hr>
24-
<h2>Routing</h2>
25-
<div id="routing"></div>
26-
<hr>
27-
<h2>Counting with Signals!</h2>
28-
<div id="signals"></div>
29-
<hr>
30-
<h2>Editable Tree</h2>
31-
<div id="editHeadings"></div>
32-
<hr>
33-
<h2>Mini Todo List with Signals!</h2>
34-
<div id="todos"></div>
35-
<hr>
36-
<h2>Postfix Calculator</h2>
37-
<div id="calc"></div>
38-
<hr>
39-
<h2>Ajax Demo</h2>
40-
<div id="ajax"></div>
41-
<hr>
42-
<h2>Color</h2>
43-
<div id="color"></div>
44-
<hr>
45-
<h2>Timers</h2>
46-
<div id="timers"></div>
47-
<hr>
48-
<h2>The Elm Architecture</h2>
49-
<div id="teaWidget"></div>
50-
<hr>
51-
<h2>Huge List of 50 thousand buttons</h2>
52-
<div id="hugeButtonList"></div>
53-
<hr>
54-
<h2>Tail Recursion Demo</h2>
55-
<div id="tailRecursion"></div>
56-
<hr>
8+
<div id="main"></div>
579
<script src="index.js"></script>
5810
</body>
5911
</html>

examples/index.prod.html

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,11 @@
11
<!doctype>
22
<html>
33
<head>
4-
<title>A purescript-concur-react example</title>
4+
<title>Concur Purescript Examples</title>
55
</head>
66
<body>
77
<h1>Concur Purescript Examples</h1>
8-
<hr>
9-
<h2>Hello World</h2>
10-
<div id="hello"></div>
11-
<hr>
12-
<h2>Counter</h2>
13-
<div id="counter"></div>
14-
<hr>
15-
<h2>Count focus</h2>
16-
<div id="focusCount"></div>
17-
<hr>
18-
<h2>Login</h2>
19-
<div id="login"></div>
20-
<hr>
21-
<h2>Routing</h2>
22-
<div id="routing"></div>
23-
<hr>
24-
<h2>Counting with Signals!</h2>
25-
<div id="signals"></div>
26-
<hr>
27-
<h2>Editable Tree</h2>
28-
<div id="editHeadings"></div>
29-
<hr>
30-
<h2>Mini Todo List with Signals!</h2>
31-
<div id="todos"></div>
32-
<hr>
33-
<h2>Postfix Calculator</h2>
34-
<div id="calc"></div>
35-
<hr>
36-
<h2>Ajax Demo</h2>
37-
<div id="ajax"></div>
38-
<hr>
39-
<h2>Color</h2>
40-
<div id="color"></div>
41-
<hr>
42-
<h2>Timers</h2>
43-
<div id="timers"></div>
44-
<hr>
45-
<h2>The Elm Architecture</h2>
46-
<div id="teaWidget"></div>
47-
<hr>
48-
<h2>Huge List of 50 thousand buttons</h2>
49-
<div id="hugeButtonList"></div>
50-
<hr>
51-
<h2>Tail Recursion Demo</h2>
52-
<div id="tailRecursion"></div>
53-
<hr>
8+
<div id="main"></div>
549
<script src="index.prod.minified.js"></script>
5510
</body>
5611
</html>

examples/src/Main.purs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ module Main where
22

33
import Prelude
44

5+
import Concur.React.DOM (div_, h2_, hr', text)
56
import Concur.React.Run (runWidgetInDom)
67
import Control.Alt ((<|>))
8+
import Control.MultiAlternative (orr)
79
import Effect (Effect)
810
import Test.Ajax (ajaxWidget)
911
import Test.Calc (calcWidget)
@@ -24,19 +26,27 @@ import Test.Wire (wireWidget)
2426

2527
main :: Effect Unit
2628
main = do
27-
runWidgetInDom "wire" wireWidget
28-
runWidgetInDom "routing" routingWidget
29-
runWidgetInDom "todos" todosWidget
30-
runWidgetInDom "editHeadings" editHeadings
31-
runWidgetInDom "hello" helloWidget
32-
runWidgetInDom "counter" (counterWidget 0 <|> counterWidget 100)
33-
runWidgetInDom "signals" countingWidget
34-
runWidgetInDom "calc" calcWidget
35-
runWidgetInDom "ajax" ajaxWidget
36-
runWidgetInDom "color" (colorWidget "")
37-
runWidgetInDom "timers" timersWidget
38-
runWidgetInDom "hugeButtonList" (hugeButtonListDemo 50000)
39-
runWidgetInDom "tailRecursion" tailRecDemo
40-
runWidgetInDom "login" loginWidget
41-
runWidgetInDom "focusCount" focusCountWidget
42-
runWidgetInDom "teaWidget" teaWidget
29+
runWidgetInDom "main" $ orr
30+
[ widget helloWidget "Hello World"
31+
, widget (counterWidget 0 <|> counterWidget 100) "Counter"
32+
, widget focusCountWidget "Count Focus"
33+
, widget loginWidget "Login"
34+
, widget routingWidget "Routing"
35+
, widget countingWidget "Counting with Signals!"
36+
, widget editHeadings "Editable Tree"
37+
, widget todosWidget "Mini Todo List with Signals"
38+
, widget calcWidget "Postfix Calculator"
39+
, widget ajaxWidget "Ajax Demo"
40+
, widget (colorWidget "") "Color"
41+
, widget timersWidget "Timers"
42+
, widget teaWidget "The Elm Architecture"
43+
, widget (hugeButtonListDemo 50000) "Huge List of 50 thousand buttons"
44+
, widget tailRecDemo "Tail Recursion Demo"
45+
, widget wireWidget "Wire Example"
46+
]
47+
where
48+
widget w s = orr
49+
[ hr'
50+
, h2_ [] $ text s
51+
, div_ [] w
52+
]

examples/src/Test/EditHeadings.purs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ module Test.EditHeadings where
33
import Prelude
44

55
import Concur.Core (Widget)
6-
import Concur.Core.FRP (Signal, dyn, loopS, step)
76
import Concur.React (HTML)
8-
import Concur.React.DOM (div', button, h5, text, ul_, li_)
7+
import Concur.React.DOM (button, div', h5, h5_, li_, text, ul_)
98
import Concur.React.Props (onClick, onDoubleClick, placeholder)
109
import Concur.React.Widgets (textInputEnter)
11-
import Data.Array (catMaybes, cons)
10+
import Control.MultiAlternative (orr)
11+
import Data.Array (cons)
12+
import Data.Array as A
1213
import Data.Maybe (Maybe(..))
13-
import Data.Traversable (traverse)
14+
import Data.Tuple (Tuple(..))
1415

1516
newtype Tree = Tree
1617
{ title :: String
@@ -32,36 +33,60 @@ testTree = Tree
3233
]
3334
}
3435

35-
mkChildren :: Signal HTML (Maybe Tree)
36-
mkChildren = step Nothing $ do
36+
mkChildren :: Widget HTML Tree
37+
mkChildren = do
3738
_ <- button [onClick] [text "New"]
38-
pure (pure (Just (Tree {title: "New Heading", children: []})))
39+
pure $ Tree {title: "New Heading", children: []}
3940

40-
treeView :: Maybe Tree -> Signal HTML (Maybe Tree)
41-
treeView Nothing = pure Nothing
42-
treeView (Just t) = treeView' t
41+
data Action
42+
= EditTitle String
43+
| Delete
44+
| AddChild Tree
45+
| EditChildren (Array Tree)
46+
47+
displayList :: forall a. (a -> Widget HTML (Maybe a)) -> Array a -> Widget HTML (Array a)
48+
displayList render = go
4349
where
44-
treeView' (Tree tree) = li_ [] $ do
45-
title' <- editableTitle tree.title
46-
shouldDel <- step false (pure true <$ button [onClick] [text "Delete"])
47-
if shouldDel
48-
then pure Nothing
49-
else do
50-
newChild <- mkChildren
51-
let children = case newChild of
52-
Nothing -> tree.children
53-
Just newt -> cons newt tree.children
54-
children' <- ul_ [] $ map catMaybes $ traverse treeView' children
55-
pure (Just (Tree {title: title', children: children'}))
50+
go elems = do
51+
Tuple i res <- orr childElements
52+
pure $ case res of
53+
Nothing -> updateElems (A.deleteAt i elems)
54+
Just updatedElem -> updateElems (A.updateAt i updatedElem elems)
55+
where
56+
childElements = elems # A.mapWithIndex \i a -> (Tuple i <$> render a)
57+
updateElems Nothing = elems
58+
updateElems (Just elems') = elems'
5659

57-
editableTitle :: String -> Signal HTML String
58-
editableTitle title = step title do
60+
treeView :: Tree -> Widget HTML (Maybe Tree)
61+
treeView (Tree tree) = li_ [] $ do
62+
res <- orr
63+
[ EditTitle <$> editableTitle tree.title
64+
, Delete <$ button [onClick] [text "Delete"]
65+
, AddChild <$> mkChildren
66+
, EditChildren <$> (ul_ [] $ displayList treeView tree.children)
67+
]
68+
case res of
69+
EditTitle newTitle -> ret {title: newTitle, children: tree.children}
70+
Delete -> pure Nothing
71+
AddChild newChild -> ret {title: tree.title, children: cons newChild tree.children}
72+
EditChildren newChildren -> ret {title: tree.title, children: newChildren}
73+
where
74+
ret t = pure (Just (Tree t))
75+
76+
editableTitle :: String -> Widget HTML String
77+
editableTitle title = do
5978
_ <- h5 [onDoubleClick] [text title]
6079
edited <- div'
6180
[ textInputEnter title false [placeholder title]
6281
, title <$ button [onClick] [text "Cancel"]
6382
]
64-
pure $ editableTitle $ if edited == "" then title else edited
83+
if edited == "" || edited == "title" then editableTitle title else pure edited
6584

6685
editHeadings :: forall a. Widget HTML a
67-
editHeadings = dyn $ ul_ [] $ loopS (Just testTree) treeView
86+
editHeadings = go testTree
87+
where
88+
go tree = do
89+
newTree <- ul_ [] $ treeView tree
90+
case newTree of
91+
Nothing -> h5_ [] $ text "Tree Deleted"
92+
Just tree' -> go tree'
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
module Test.EditHeadingsSignals where
2+
3+
import Prelude
4+
5+
import Concur.Core (Widget)
6+
import Concur.Core.FRP (Signal, dyn, loopS, step)
7+
import Concur.React (HTML)
8+
import Concur.React.DOM (div', button, h5, text, ul_, li_)
9+
import Concur.React.Props (onClick, onDoubleClick, placeholder)
10+
import Concur.React.Widgets (textInputEnter)
11+
import Data.Array (catMaybes, cons)
12+
import Data.Maybe (Maybe(..))
13+
import Data.Traversable (traverse)
14+
15+
newtype Tree = Tree
16+
{ title :: String
17+
, children :: Array Tree
18+
}
19+
20+
testTree :: Tree
21+
testTree = Tree
22+
{ title: "Double click to edit me"
23+
, children:
24+
[ Tree
25+
{ title: "Or use the \"delete\" button to delete me"
26+
, children: []
27+
}
28+
, Tree
29+
{ title: "Or use the \"new\" button to add a sub node"
30+
, children: []
31+
}
32+
]
33+
}
34+
35+
mkChildren :: Signal HTML (Maybe Tree)
36+
mkChildren = step Nothing $ do
37+
_ <- button [onClick] [text "New"]
38+
pure (pure (Just (Tree {title: "New Heading", children: []})))
39+
40+
treeView :: Maybe Tree -> Signal HTML (Maybe Tree)
41+
treeView Nothing = pure Nothing
42+
treeView (Just t) = treeView' t
43+
where
44+
treeView' (Tree tree) = li_ [] $ do
45+
title' <- editableTitle tree.title
46+
shouldDel <- step false (pure true <$ button [onClick] [text "Delete"])
47+
if shouldDel
48+
then pure Nothing
49+
else do
50+
newChild <- mkChildren
51+
let children = case newChild of
52+
Nothing -> tree.children
53+
Just newt -> cons newt tree.children
54+
children' <- ul_ [] $ map catMaybes $ traverse treeView' children
55+
pure (Just (Tree {title: title', children: children'}))
56+
57+
editableTitle :: String -> Signal HTML String
58+
editableTitle title = step title do
59+
_ <- h5 [onDoubleClick] [text title]
60+
edited <- div'
61+
[ textInputEnter title false [placeholder title]
62+
, title <$ button [onClick] [text "Cancel"]
63+
]
64+
pure $ editableTitle $ if edited == "" then title else edited
65+
66+
editHeadings :: forall a. Widget HTML a
67+
editHeadings = dyn $ ul_ [] $ loopS (Just testTree) treeView

0 commit comments

Comments
 (0)