Skip to content

Commit 25cd493

Browse files
committed
add instructions for elmish attributes function #44
1 parent 21f05d5 commit 25cd493

File tree

1 file changed

+74
-16
lines changed

1 file changed

+74
-16
lines changed

Diff for: todo-list.md

+74-16
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,9 @@ This is a "copy-paste" of the _generated_ code including the Todo items:
410410
Let's split each one of these elements into it's own `function`
411411
(_with any necessary "helpers"_) in the order they appear.
412412

413-
#### `<section>`
413+
### `<section>` HTML Element
414414

415-
The _first_ HTML we encounter in the TodoMVC app is
415+
The _first_ HTML element we encounter in the TodoMVC app is
416416
`<section>`.
417417
`<section>` represents a standalone section — which doesn't have
418418
a more specific semantic element to represent it —
@@ -427,40 +427,98 @@ our `section` function (_which will create the_ `<section>` _DOM node_)
427427
will be a function with _two_ arguments:
428428
+ `attributes` - a list (Array) of HTML attributes/properties
429429
e.g: `id` or `class`.
430-
+ `children` - a list (Array) of child HTML elements
430+
+ `childnodes` - a list (Array) of child HTML elements
431431
(_nested within the_ `<section>`)
432432

433433
Each of these function arguments will be "_applied_" to the HTML element.
434434
We therefore need a pair of "helper" functions (_one for each argument_).
435435

436+
Section in Elm: http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html
437+
<br />
438+
Demo: https://ellie-app.com/LTtNVQjfWVa1
439+
![ellie-elm-section](https://user-images.githubusercontent.com/194400/42708957-bbcc1020-86d6-11e8-97bf-f2f3a1c6fdea.png)
436440

437441

438-
#### `attributes`
442+
### `attributes`
439443

440-
`attributes(attrlist, node)`
444+
The `JSDOC` comment for our `attributes` function is:
445+
```js
446+
/**
447+
* attributes applies the desired attributes to the desired node.
448+
* Note: this function is "impure" because it "mutates" the node.
449+
* however it is idempotent; the "side effect" is only applied once.
450+
* @param {Array.<String>} attrlist list of attributes to be applied to the node
451+
* @param {Object} node DOM node upon which attribute(s) should be applied
452+
* @example
453+
* // returns node with attributes applied
454+
* div = attributes(["class=item", "id=mydiv", "active=true"], div);
455+
*/
456+
```
457+
This should give you a _good idea_ of what code needs to be written.
441458

442-
The `attributes` function is "impure" as it "mutates"
443-
the target DOM `node`, however the application of attributes
444-
to DOM node(s) is idempotent;
445-
the attribute will only be applied _once_ to the node
446-
regardless of how many times the `attributes` function is called.
447-
see: https://en.wikipedia.org/wiki/Idempotence
459+
But let's write the _test_ first!
460+
Add the following test to the `test/elmish.test.js` file: <br />
461+
462+
```js
463+
test('elmish.attributes applies class HTML attribute to a node', function (t) {
464+
const root = document.getElementById(id);
465+
let div = document.createElement('div');
466+
div.id = 'divid';
467+
div = elmish.attributes(["class=apptastic"], div);
468+
root.appendChild(div);
469+
// test the div has the desired class:
470+
const nodes = document.getElementsByClassName('apptastic');
471+
t.equal(nodes.length, 1, "<div> has 'apptastic' class applied");
472+
t.end();
473+
});
474+
```
448475

476+
Given the code in the test above,
477+
take a moment to think of how _you_ would write,
478+
the `attributes` function to apply a CSS `class` to an element. <br />
479+
Note: we have _seen_ the code _before_ in the `counter` example.
480+
The difference is this time we want it to be "generic";
481+
we want to apply a CSS `class` to _any_ DOM node.
449482

483+
If you can, make the test _pass_
484+
by writing the `attributes` function.
485+
(_don't forget to_ `export` _the function at the end of the file_).
450486

487+
If you get "stuck", checkout:
488+
https://github.com/dwyl/learn-elm-architecture-in-javascript/tree/master/examples/todo-list/elmish.js <br />
451489

452-
Section in Elm: http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html
453-
<br />
454-
Demo: https://ellie-app.com/LTtNVQjfWVa1
455-
![ellie-elm-section](https://user-images.githubusercontent.com/194400/42708957-bbcc1020-86d6-11e8-97bf-f2f3a1c6fdea.png)
456490

457491

458492

459-
The Elm HTML Attributes package is:
493+
> The `attributes` function is "impure" as it "mutates"
494+
the target DOM `node`, however the application of attributes
495+
to DOM node(s) is idempotent;
496+
the attribute will only be applied _once_ to the node
497+
regardless of how many times the `attributes` function is called.
498+
see: https://en.wikipedia.org/wiki/Idempotence
499+
500+
501+
For reference, the Elm HTML Attributes package is:
460502
http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Attributes
461503

504+
### `childnodes`
462505

506+
The `childnodes` functionality is a one-liner: <br />
507+
```js
508+
childnodes.forEach(function(el){ parent.appendChild(el) });
509+
```
510+
It's easy to think: "_why bother to create a_ `function`...?" <br />
511+
The _reasons_ to create _small_ functions are: <br />
512+
**a)** Keep the _functionality_ "DRY" https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
513+
which means we can _easily_ track down all instances of function invocation.
514+
<br />
515+
**b)** If we ever need to modify the function, e.g: to performance optimise it, there is a _single_ definition.
516+
<br />
517+
**c)** It makes unit-testing the functionality easy;
518+
that's _great_ news for reliability!
463519

520+
With that in mind, let's write a _test_ for the `childnodes` function!
521+
Add the following code to the `test/elmish.test.js` file: <br />
464522

465523

466524

0 commit comments

Comments
 (0)