├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── bower.json
├── html
├── .gitignore
└── index.html
├── package.json
├── psc-package.json
├── src
├── JQuery.js
└── JQuery.purs
└── test
└── Main.purs
/.gitignore:
--------------------------------------------------------------------------------
1 | /.*
2 | !/.gitignore
3 | !/.github
4 | !/.travis.yml
5 |
6 | # Dependencies
7 | bower_components
8 | node_modules
9 |
10 | # Generated files
11 | output
12 | generated-docs
13 |
14 | # Lockfiles
15 | package-lock.json
16 | *.lock
17 |
18 | # Extra files
19 | tmp
20 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | dist: trusty
3 | sudo: required
4 | node_js: stable
5 | env:
6 | - PATH=$HOME/purescript:$PATH
7 | install:
8 | - TAG=$(basename $(curl --location --silent --output /dev/null -w %{url_effective} https://github.com/purescript/purescript/releases/latest))
9 | - curl --location --output $HOME/purescript.tar.gz https://github.com/purescript/purescript/releases/download/$TAG/linux64.tar.gz
10 | - tar -xvf $HOME/purescript.tar.gz -C $HOME/
11 | - chmod a+x $HOME/purescript
12 | - npm install -g bower
13 | - npm install
14 | - bower install --production
15 | script:
16 | - npm run -s build
17 | - bower install
18 | - npm run -s test
19 | after_success:
20 | - >-
21 | test $TRAVIS_TAG &&
22 | echo $GITHUB_TOKEN | pulp login &&
23 | echo y | pulp publish --no-push
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 PureScript
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # purescript-jquery
2 |
3 | [](https://github.com/purescript-contrib/purescript-jquery/releases)
4 | [](http://github.com/paf31)
5 |
6 | PureScript type declarations for jQuery. See [module documentation on Pursuit](https://pursuit.purescript.org/packages/purescript-jquery).
7 |
8 | ## Example
9 |
10 | ```purs
11 | main = ready do
12 | -- Get the document body
13 | body <- body
14 |
15 | -- Create a text box
16 | div <- create "
"
17 | input <- create "
"
18 | appendText "Your Name: " div
19 | append input div
20 | append div body
21 |
22 | -- Create a paragraph to display a greeting
23 | greeting <- create "
"
24 | css { color: "red" } greeting
25 | append greeting body
26 |
27 | -- Listen for change events on the text box
28 | on "change" (handleChange input greeting) input
29 |
30 | where
31 | handleChange :: JQuery -> JQuery -> JQueryEvent -> JQuery -> Effect Unit
32 | handleChange input greeting _ _ = unsafePartial do
33 | val <- getValue input
34 | for_ (runExcept (readString val)) \name -> do
35 | log $ "Name changed to " <> name
36 | setText ("Hello, " <> name) greeting
37 | ```
38 |
39 | (from [test/Main.purs](test/Main.purs)).
40 |
41 | ## Installation
42 |
43 | bower i purescript-jquery
44 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "purescript-jquery",
3 | "homepage": "https://github.com/purescript/purescript-jquery",
4 | "description": "Type declarations for jQuery",
5 | "keywords": [
6 | "purescript"
7 | ],
8 | "license": "MIT",
9 | "ignore": [
10 | "**/.*",
11 | "bower_components",
12 | "node_modules",
13 | "output",
14 | "bower.json",
15 | "Gruntfile.js",
16 | "package.json"
17 | ],
18 | "repository": {
19 | "type": "git",
20 | "url": "git://github.com/paf31/purescript-jquery.git"
21 | },
22 | "dependencies": {
23 | "purescript-web-dom": "^1.0.0",
24 | "purescript-effect": "^2.0.0",
25 | "purescript-foreign": "^5.0.0"
26 | },
27 | "devDependencies": {
28 | "purescript-console": "^4.1.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/html/.gitignore:
--------------------------------------------------------------------------------
1 | index.js
2 |
--------------------------------------------------------------------------------
/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
purescript-jquery example
5 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "clean": "rimraf output && rimraf .pulp-cache",
5 | "test": "pulp build -I test && pulp browserify -m Test.Main --to html/index.js",
6 | "build": "pulp build"
7 | },
8 | "devDependencies": {
9 | "pulp": "^14.0.0",
10 | "purescript-psa": "^0.7.3",
11 | "rimraf": "^3.0.2"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/psc-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "source": "https://github.com/purescript/package-sets.git",
4 | "set": "psc-0.10.1",
5 | "depends": [
6 | "arrays",
7 | "bifunctors",
8 | "console",
9 | "control",
10 | "datetime",
11 | "distributive",
12 | "dom",
13 | "eff",
14 | "either",
15 | "enums",
16 | "exceptions",
17 | "foldable-traversable",
18 | "foreign",
19 | "functions",
20 | "generics",
21 | "identity",
22 | "integers",
23 | "invariant",
24 | "js-date",
25 | "lazy",
26 | "lists",
27 | "math",
28 | "maybe",
29 | "media-types",
30 | "monoid",
31 | "newtype",
32 | "nonempty",
33 | "nullable",
34 | "partial",
35 | "prelude",
36 | "proxy",
37 | "st",
38 | "strings",
39 | "tailrec",
40 | "transformers",
41 | "tuples",
42 | "unfoldable",
43 | "unsafe-coerce"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/src/JQuery.js:
--------------------------------------------------------------------------------
1 | /* global exports */
2 | "use strict";
3 |
4 | exports.ready = function(func) {
5 | return function() {
6 | jQuery(document).ready(func);
7 | };
8 | };
9 |
10 | exports.select = function(selector) {
11 | return function() {
12 | return jQuery(selector);
13 | };
14 | };
15 |
16 | exports.find = function(selector) {
17 | return function(ob) {
18 | return function() {
19 | return ob.find(selector);
20 | };
21 | };
22 | };
23 |
24 | exports.parent = function(ob) {
25 | return function() {
26 | return ob.parent();
27 | };
28 | };
29 |
30 | exports.closest = function(selector) {
31 | return function(ob) {
32 | return function() {
33 | return ob.closest(selector);
34 | };
35 | };
36 | };
37 |
38 | exports.create = function(html) {
39 | return function() {
40 | return jQuery(html);
41 | };
42 | };
43 |
44 | exports.setAttr = function(attr) {
45 | return function(val) {
46 | return function(ob) {
47 | return function() {
48 | ob.attr(attr, val);
49 | };
50 | };
51 | };
52 | };
53 |
54 | exports.getAttrImpl = function(attr) {
55 | return function(ob) {
56 | return function() {
57 | return ob.attr(attr);
58 | };
59 | };
60 | };
61 |
62 | exports.attr = function(attrs) {
63 | return function(ob) {
64 | return function() {
65 | ob.attr(attrs);
66 | };
67 | };
68 | };
69 |
70 | exports.css = function(props) {
71 | return function(ob) {
72 | return function() {
73 | ob.css(props);
74 | };
75 | };
76 | };
77 |
78 | exports.hasClass = function(cls) {
79 | return function(ob) {
80 | return function() {
81 | return ob.hasClass(cls);
82 | };
83 | };
84 | };
85 |
86 | exports.toggleClass = function(cls) {
87 | return function(ob) {
88 | return function() {
89 | ob.toggleClass(cls);
90 | };
91 | };
92 | };
93 |
94 | exports.setClass = function(cls) {
95 | return function(flag) {
96 | return function(ob) {
97 | return function() {
98 | ob.toggleClass(cls, flag);
99 | };
100 | };
101 | };
102 | };
103 |
104 | exports.setProp = function(p) {
105 | return function(val) {
106 | return function(ob) {
107 | return function() {
108 | ob.prop(p, val);
109 | };
110 | };
111 | };
112 | };
113 |
114 | exports.getProp = function(p) {
115 | return function(ob) {
116 | return function() {
117 | return ob.prop(p);
118 | };
119 | };
120 | };
121 |
122 | exports.append = function(ob1) {
123 | return function(ob) {
124 | return function() {
125 | ob.append(ob1);
126 | };
127 | };
128 | };
129 |
130 | exports.unsafeAppendHtml = function(s) {
131 | return function(ob) {
132 | return function() {
133 | ob.append(s);
134 | };
135 | };
136 | };
137 |
138 | exports.appendText = function(s) {
139 | return function(ob) {
140 | return function() {
141 | ob.append(document.createTextNode(s));
142 | };
143 | };
144 | };
145 |
146 | exports.body = function() {
147 | return jQuery(document.body);
148 | };
149 |
150 | exports.remove = function(ob) {
151 | return function() {
152 | ob.remove();
153 | };
154 | };
155 |
156 | exports.clear = function(ob) {
157 | return function() {
158 | ob.empty();
159 | };
160 | };
161 |
162 | exports.before = function(ob) {
163 | return function(ob1) {
164 | return function() {
165 | ob1.before(ob);
166 | };
167 | };
168 | };
169 |
170 | exports.getText = function(ob) {
171 | return function() {
172 | return ob.text();
173 | };
174 | };
175 |
176 | exports.setText = function(text) {
177 | return function(ob) {
178 | return function() {
179 | ob.text(text);
180 | };
181 | };
182 | };
183 |
184 | exports.getHtml = function(ob) {
185 | return function() {
186 | return ob.html();
187 | };
188 | };
189 |
190 | exports.setHtml = function(html) {
191 | return function(ob) {
192 | return function() {
193 | ob.html(html);
194 | };
195 | };
196 | };
197 |
198 | exports.getValue = function(ob) {
199 | return function() {
200 | return ob.val();
201 | };
202 | };
203 |
204 | exports.setValue = function(val) {
205 | return function(ob) {
206 | return function() {
207 | ob.val(val);
208 | };
209 | };
210 | };
211 |
212 | exports.toggle = function(ob) {
213 | return function() {
214 | ob.toggle();
215 | };
216 | };
217 |
218 | exports.setVisible = function(flag) {
219 | return function(ob) {
220 | return function() {
221 | ob.toggle(flag);
222 | };
223 | };
224 | };
225 |
226 | exports.toArray = function(ob) {
227 | return function() {
228 | var els = ob.toArray();
229 | var copy = [];
230 | for (var i = 0; i < els.length; i++) {
231 | copy.push(jQuery(els[i]));
232 | }
233 | return copy;
234 | };
235 | };
236 |
237 | exports.on = function(evt) {
238 | return function(act) {
239 | return function(ob) {
240 | return function() {
241 | ob.on(evt, function(e) {
242 | act(e)(jQuery(this))();
243 | });
244 | };
245 | };
246 | };
247 | };
248 |
249 | exports.delegate = function(evt) {
250 | return function(sel) {
251 | return function(act) {
252 | return function(ob) {
253 | return function() {
254 | ob.on(evt, sel, function(e) {
255 | act(e)(jQuery(this))();
256 | });
257 | };
258 | };
259 | };
260 | };
261 | };
262 |
263 |
264 | exports.off = function(evt) {
265 | return function(ob) {
266 | return function() {
267 | return ob.off(evt);
268 | };
269 | };
270 | };
271 |
272 |
273 | exports.deafen = function(ob) {
274 | return function() {
275 | return ob.off();
276 | };
277 | };
278 |
279 | exports.preventDefault = function(e) {
280 | return function() {
281 | e.preventDefault();
282 | };
283 | };
284 |
285 | exports.stopPropagation = function(e) {
286 | return function() {
287 | e.stopPropagation();
288 | };
289 | };
290 |
291 | exports.stopImmediatePropagation = function(e) {
292 | return function() {
293 | e.stopImmediatePropagation();
294 | };
295 | };
296 |
297 | exports.getTarget = function(e) {
298 | return function() {
299 | return jQuery(e.target);
300 | };
301 | };
302 |
303 | exports.getCurrentTarget = function(e) {
304 | return function() {
305 | return jQuery(e.currentTarget);
306 | };
307 | };
308 |
309 | exports.getPageX = function(e) {
310 | return function() {
311 | return e.pageX;
312 | };
313 | };
314 |
315 | exports.getPageY = function(e) {
316 | return function() {
317 | return e.pageY;
318 | };
319 | };
320 |
321 | exports.getWhich = function(e) {
322 | return function() {
323 | return e.which;
324 | };
325 | };
326 |
327 | exports.getMetaKey = function(e) {
328 | return function() {
329 | return e.metaKey;
330 | };
331 | };
332 |
333 |
334 | exports.clone = function(ob) {
335 | return function() {
336 | return ob.clone();
337 | };
338 | };
339 |
340 | exports.cloneWithDataAndEvents = function(ob) {
341 | return function() {
342 | return ob.clone(true);
343 | };
344 | };
345 |
--------------------------------------------------------------------------------
/src/JQuery.purs:
--------------------------------------------------------------------------------
1 | -- | This module defines foreign types and functions for working with
2 | -- | the jQuery library.
3 |
4 | module JQuery
5 | ( JQuery
6 | , JQueryEvent
7 | , Selector
8 | , ready
9 | , select
10 | , find
11 | , parent
12 | , closest
13 | , create
14 | , setAttr
15 | , getAttr
16 | , attr
17 | , css
18 | , hasClass
19 | , toggleClass
20 | , setClass
21 | , addClass
22 | , removeClass
23 | , setProp
24 | , getProp
25 | , append
26 | , remove
27 | , clear
28 | , before
29 | , appendText
30 | , body
31 | , getText
32 | , setText
33 | , getHtml
34 | , setHtml
35 | , getValue
36 | , setValue
37 | , toggle
38 | , setVisible
39 | , hide
40 | , display
41 | , on
42 | , on'
43 | , off
44 | , off'
45 | , toArray
46 | , preventDefault
47 | , stopPropagation
48 | , stopImmediatePropagation
49 | , getTarget
50 | , getCurrentTarget
51 | , getPageX
52 | , getPageY
53 | , getWhich
54 | , getMetaKey
55 | , clone
56 | , cloneWithDataAndEvents
57 | ) where
58 |
59 | import Prelude (Unit)
60 | import Effect (Effect)
61 | import Foreign (Foreign, isUndefined, unsafeFromForeign)
62 | import Data.Functor (map)
63 | import Data.Maybe (Maybe(..))
64 |
65 | -- | The type of collections of jQuery-wrapped nodes.
66 | foreign import data JQuery :: Type
67 |
68 | -- | Type of jQuery event objects.
69 | foreign import data JQueryEvent :: Type
70 |
71 | -- | A type synonym to help readability of type signatures.
72 | type Selector = String
73 |
74 | -- | Run a function when the document is loaded.
75 | foreign import ready :: forall a. Effect a -> Effect Unit
76 |
77 | -- | Wrapper function for jQuery selection $('..')
78 | foreign import select :: Selector -> Effect JQuery
79 |
80 | -- | Find child nodes matching a selector
81 | foreign import find :: Selector -> JQuery -> Effect JQuery
82 |
83 | -- | Get the parent elements.
84 | foreign import parent :: JQuery -> Effect JQuery
85 |
86 | -- | Find the closest element matching the selector.
87 | foreign import closest :: Selector -> JQuery -> Effect JQuery
88 |
89 | -- | Create an element.
90 | foreign import create :: String -> Effect JQuery
91 |
92 | -- | Set a single attribute.
93 | foreign import setAttr :: forall a. String -> a -> JQuery -> Effect Unit
94 |
95 | foreign import getAttrImpl :: String -> JQuery -> Effect Foreign
96 |
97 | -- | Get an attribute value.
98 | getAttr :: String -> JQuery -> Effect (Maybe String)
99 | getAttr str jq = map foreignToString (getAttrImpl str jq)
100 | where foreignToString f =
101 | if isUndefined f
102 | then Nothing
103 | else Just (unsafeFromForeign f)
104 |
105 | -- | Set multiple attributes.
106 | foreign import attr :: forall attr. { | attr } -> JQuery -> Effect Unit
107 |
108 | -- | Set CSS properties.
109 | foreign import css :: forall css. { | css } -> JQuery -> Effect Unit
110 |
111 | -- | Test if an element has a CSS class.
112 | foreign import hasClass :: String -> JQuery -> Effect Boolean
113 |
114 | -- | Toggle the specified CSS class.
115 | foreign import toggleClass :: String -> JQuery -> Effect Unit
116 |
117 | -- | Set the specified CSS class.
118 | foreign import setClass :: String -> Boolean -> JQuery -> Effect Unit
119 |
120 | -- | Add the specified CSS class.
121 | addClass :: String -> JQuery -> Effect Unit
122 | addClass cls = setClass cls true
123 |
124 | -- | Remove the specified CSS class.
125 | removeClass :: String -> JQuery -> Effect Unit
126 | removeClass cls = setClass cls false
127 |
128 | -- | Set a single property.
129 | foreign import setProp :: forall a. String -> a -> JQuery -> Effect Unit
130 |
131 | -- | Get a property value.
132 | foreign import getProp :: String -> JQuery -> Effect Foreign
133 |
134 | -- | Append the first node as a child node of the second.
135 | foreign import append :: JQuery -> JQuery -> Effect Unit
136 |
137 | -- | Remove selected elements.
138 | foreign import remove :: JQuery -> Effect Unit
139 |
140 | -- | Remove child elements.
141 | foreign import clear :: JQuery -> Effect Unit
142 |
143 | -- | Insert an element before another.
144 | foreign import before :: JQuery -> JQuery -> Effect Unit
145 |
146 | -- | Append text as a child node. Importantly, if jQuery recognises the String
147 | -- | as HTML, the parsed HTML will be appended, rather than the string. Hence,
148 | -- | this function can be dangerous when dealing with unchecked user input.
149 | foreign import unsafeAppendHtml :: String -> JQuery -> Effect Unit
150 |
151 | -- | Append text as a child node.
152 | foreign import appendText :: String -> JQuery -> Effect Unit
153 |
154 | -- | Get the document body node.
155 | foreign import body :: Effect JQuery
156 |
157 | -- | Get the text content of an element.
158 | foreign import getText :: JQuery -> Effect String
159 |
160 | -- | Set the text content of an element.
161 | foreign import setText :: String -> JQuery -> Effect Unit
162 |
163 | -- | Get the html content of an element.
164 | foreign import getHtml :: JQuery -> Effect String
165 |
166 | -- | Set the html content of an element
167 | foreign import setHtml :: String -> JQuery -> Effect Unit
168 |
169 | -- | Get the value of a form element.
170 | foreign import getValue :: JQuery -> Effect Foreign
171 |
172 | -- | Set the value of a form element.
173 | foreign import setValue :: forall a. a -> JQuery -> Effect Unit
174 |
175 | -- | Toggle visibility of an element.
176 | foreign import toggle :: JQuery -> Effect Unit
177 |
178 | -- | Set the visibility of an element.
179 | foreign import setVisible :: Boolean -> JQuery -> Effect Unit
180 |
181 | -- | Hide elements.
182 | hide :: JQuery -> Effect Unit
183 | hide = setVisible false
184 |
185 | -- | Show elements.
186 | display :: JQuery -> Effect Unit
187 | display = setVisible true
188 |
189 | -- | Register an event handler.
190 | foreign import on :: forall a. String -> (JQueryEvent -> JQuery -> Effect a) -> JQuery -> Effect Unit
191 |
192 | -- | Register an event handler for elements matching a selector.
193 | foreign import delegate :: forall a. String -> Selector -> (JQueryEvent -> JQuery -> Effect a) -> JQuery -> Effect Unit
194 |
195 | on':: forall a. String -> Selector -> (JQueryEvent -> JQuery -> Effect a) -> JQuery -> Effect Unit
196 | on' = delegate
197 |
198 | -- | Remove an event handler.
199 | foreign import off :: String -> JQuery -> Effect Unit
200 |
201 | -- | Remove all event handler.
202 | foreign import deafen :: JQuery -> Effect Unit
203 |
204 | off':: JQuery -> Effect Unit
205 | off' = deafen
206 |
207 | -- | Get an array of matching elements.
208 | foreign import toArray :: JQuery -> Effect (Array JQuery)
209 |
210 | -- | Prevent the default action for an event.
211 | foreign import preventDefault :: JQueryEvent -> Effect Unit
212 |
213 | -- | Stop propagation an event.
214 | foreign import stopPropagation :: JQueryEvent -> Effect Unit
215 |
216 | -- | Stop immediate propagation an event.
217 | foreign import stopImmediatePropagation :: JQueryEvent -> Effect Unit
218 |
219 | -- | Get the `target` propery of the event object.
220 | foreign import getTarget :: JQueryEvent -> Effect JQuery
221 |
222 | -- | Get the `currentTarget` property from the event object.
223 | foreign import getCurrentTarget :: JQueryEvent -> Effect JQuery
224 |
225 | -- | Get the `pageX` property from the event object.
226 | foreign import getPageX :: JQueryEvent -> Effect Number
227 |
228 | -- | Get the `pageY` property from the event object.
229 | foreign import getPageY :: JQueryEvent -> Effect Number
230 |
231 | -- | Get the `which` property from the event object.
232 | foreign import getWhich :: JQueryEvent -> Effect Int
233 |
234 | -- | Get the `metaKey` property from the event object.
235 | foreign import getMetaKey :: JQueryEvent -> Effect Boolean
236 |
237 | -- | Create a deep copy of the set of matched elements.
238 | foreign import clone :: JQuery -> Effect JQuery
239 |
240 | -- | Create a deep copy of the set of matched elements,
241 | -- | including event handlers and element data.
242 | foreign import cloneWithDataAndEvents :: JQuery -> Effect JQuery
243 |
--------------------------------------------------------------------------------
/test/Main.purs:
--------------------------------------------------------------------------------
1 | module Test.Main where
2 |
3 | import Prelude hiding (append)
4 |
5 | import Effect (Effect)
6 | import Effect.Console (log)
7 | import JQuery (JQuery, JQueryEvent, on, append, css, create, appendText, body, ready, setText, getValue)
8 | import Control.Monad.Except (runExcept)
9 | import Foreign (readString)
10 | import Data.Foldable (for_)
11 | import Partial.Unsafe (unsafePartial)
12 |
13 | main :: Effect Unit
14 | main =
15 | ready $ do
16 | -- Get the document body
17 | body <- body
18 |
19 | -- Create a text box
20 | div <- create "
"
21 | input <- create "
"
22 | appendText "Your Name: " div
23 | append input div
24 | append div body
25 |
26 | -- Create a paragraph to display a greeting
27 | greeting <- create "
"
28 | css { color: "red" } greeting
29 | append greeting body
30 |
31 | -- Listen for change events on the text box
32 | on "change" (handleChange input greeting) input
33 | where
34 | handleChange :: JQuery -> JQuery -> JQueryEvent -> JQuery -> Effect Unit
35 | handleChange input greeting _ _ = unsafePartial do
36 | val <- getValue input
37 | for_ (runExcept (readString val)) \name -> do
38 | log $ "Name changed to " <> name
39 | setText ("Hello, " <> name) greeting
40 |
--------------------------------------------------------------------------------