1-
1+ fires
22# TodoMVC Tutorial (Rails 5.2.x)
33
44### Prerequisites
@@ -437,13 +437,11 @@ Lets change `App` to look like this:
437437# app/hyperstack/components/app.rb
438438class App < HyperComponent
439439 include Hyperstack ::Router
440- render do
441- SECTION do
442- Header ()
443- Route (' /' , exact: true ) { Redirect (' /all' ) }
444- Route (' /:scope' , mounts: Index )
445- Footer ()
446- end
440+ render(SECTION ) do
441+ Header ()
442+ Route (' /' , exact: true ) { Redirect (' /all' ) }
443+ Route (' /:scope' , mounts: Index )
444+ Footer ()
447445 end
448446end
449447```
@@ -609,16 +607,17 @@ To summarize:
609607+ User saves the Todo being edited: editing changes to ` false ` .
610608+ User changes focus away (` blur ` ) from the Todo being edited: editing changes to ` false ` .
611609
612- In order to accomplish this our ` EditItem ` component is going to communicate to its parent via two application defined events - ` saved ` and ` cancel ` .
610+ In order to accomplish this our ` EditItem ` component is going to communicate to its parent via two application defined events - ` saved ` and ` cancel ` .
611+
613612Add the following 5 lines to the ` EditItem ` component like this:
614613
615614``` ruby
616615# app/hyperstack/components/edit_item.rb
617616class EditItem < HyperComponent
618617 param :todo
619- triggers :saved # add
620- triggers :cancel # add
621- after_mount { DOM [dom_node].focus } # add
618+ fires :saved # add
619+ fires :cancel # add
620+ after_mount { jQ [dom_node].focus } # add
622621
623622 render do
624623 INPUT (defaultValue: @Todo .title)
@@ -630,17 +629,17 @@ class EditItem < HyperComponent
630629 end
631630end
632631```
633- The first two new lines add our custom events.
632+ The first two new lines add our custom events which will be * fired * by the component .
634633
635634The next new line uses one of several * Lifecycle Callbacks* . In this case we need to move the focus to the ` EditItem ` component after it is mounted.
636- The ` DOM ` class is Hyperstack's jQuery wrapper, and ` dom_node `
635+ The ` jQ ` method is Hyperstack's jQuery wrapper, and ` dom_node `
637636is the method that returns the actual dom node where this * instance* of the component is mounted.
638637This is the ` INPUT ` html element as defined in the render method.
639638
640- The ` saved! ` line will trigger the saved event in the parent component.
641- Notice that the method to trigger a custom event is the name of the event followed by a bang (!).
639+ The ` saved! ` line will fire the saved event in the parent component.
640+ Notice that the method to fire a custom event is the name of the event followed by a bang (!).
642641
643- Finally we add the ` blur ` event handler and trigger our ` cancel ` event.
642+ Finally we add the ` blur ` event handler and fire our ` cancel ` event.
644643
645644Now we can update our ` TodoItem ` component to react to three events: ` double_click ` , ` saved ` and ` cancel ` .
646645
@@ -663,7 +662,7 @@ class TodoItem < HyperComponent
663662 end
664663end
665664```
666- All states in Hyperstack are simply Ruby instance variables (ivars, variables with a leading @). Here we use the ` @editing ` ivar.
665+ All states in Hyperstack are simply Ruby instance variables (ivars for short which are variables with a leading @). Here we use the ` @editing ` ivar.
667666
668667We have already used a lot of states that are built into the HyperModel and HyperRouter.
669668The states of these components are built out collections of instance variables like ` @editing ` .
@@ -748,17 +747,15 @@ Let's start with the `App` component. With styling it will look like this:
748747# app/hyperstack/components/app.rb
749748class App < HyperComponent
750749 include Hyperstack ::Router
751- render do
752- SECTION (class : ' todo-app' ) do # add class todo-app
753- Header ()
754- Route (' /' , exact: true ) { Redirect (' /all' ) }
755- Route (' /:scope' , mounts: Index )
756- Footer ()
757- end
750+ render(SECTION , class : ' todo-app' ) do # add class todo-app
751+ Header ()
752+ Route (' /' , exact: true ) { Redirect (' /all' ) }
753+ Route (' /:scope' , mounts: Index )
754+ Footer ()
758755 end
759756end
760757```
761- The ` Footer ` components needs have a ` UL ` added to hold the links nicely,
758+ The ` Footer ` component needs to have a ` UL ` added to hold the links nicely,
762759and we can also use the ` NavLinks ` ` active_class ` param to highlight the link that is currently active:
763760
764761``` ruby
@@ -772,7 +769,7 @@ class Footer < HyperComponent
772769 LI { NavLink (" /#{ path } " , active_class: :selected ) { path.camelize } }
773770 end
774771 render(DIV , class : :footer) do # add class footer
775- UL (class : :filters) do # wrap links in a UL element with class filers
772+ UL (class : :filters) do # wrap links in a UL element with class filters
776773 link_item(:all )
777774 link_item(:active )
778775 link_item(:completed )
@@ -796,17 +793,17 @@ class Index < HyperComponent
796793end
797794```
798795For the EditItem component we want the parent to pass any html parameters such as ` class ` along to the INPUT tag.
799- We do this by adding the special ` others ` param that will collect any extra params, we then pass it along in to the INPUT tag.
796+ We do this by adding the special ` other ` param that will collect any extra params, we then pass it along in to the INPUT tag.
800797Hyperstack will take care of merging all the params together sensibly.
801798
802799``` ruby
803800# app/hyperstack/components/edit_item.rb
804801class EditItem < HyperComponent
805802 param :todo
806- triggers :saved
807- triggers :cancel
808- others :etc # can be named anything you want
809- after_mount { DOM [dom_node].focus }
803+ fires :saved
804+ fires :cancel
805+ other :etc # can be named anything you want
806+ after_mount { jQ [dom_node].focus }
810807 render do
811808 INPUT (@Etc , defaultValue: @Todo .title, key: @Todo )
812809 .on(:enter ) do |evt |
@@ -864,12 +861,14 @@ This is just a span that we add before the link tags list in the `Footer` compon
864861...
865862render(DIV , class : :footer) do
866863 SPAN (class : ' todo-count' ) do
867- " #{ Todo .active.count} item#{ ' s' if Todo .active.count != 1 } left"
864+ # pluralize returns the second param (item) properly
865+ # pluralized depending on the first param's value.
866+ " #{ pluralize(Todo .active.count, ' item' ) } left"
868867 end
869868 UL (class : :filters) do
870869...
871870```
872- + ** Add 'placeholder' Text To Edit Item** \
871+ + ** Add 'placeholder' Text To Edit Item**
873872` EditItem ` should display a meaningful placeholder hint if the title is blank:
874873
875874``` ruby
@@ -879,7 +878,7 @@ INPUT(@Etc, placeholder: 'What is left to do today?',
879878.on(:enter ) do |evt |
880879...
881880```
882- + ** Don't Show the Footer If There are No Todos** \
881+ + ** Don't Show the Footer If There are No Todos**
883882In the ` App ` component add a * guard* so that we won't show the Footer if there are no Todos:
884883
885884``` ruby
@@ -899,7 +898,7 @@ You have built a small but feature rich full stack Todo application in less than
899898``` text
900899SLOC
901900--------------
902- App: 11
901+ App: 9
903902Header: 8
904903Index: 10
905904TodoItem: 16
@@ -908,7 +907,7 @@ Footer: 16
908907Todo Model: 4
909908Rails Route: 4
910909--------------
911- Total: 85
910+ Total: 83
912911```
913912
914913The complete application is shown here:
@@ -917,13 +916,11 @@ The complete application is shown here:
917916# app/hyperstack/components/app.rb
918917class App < HyperComponent
919918 include Hyperstack ::Router
920- render do
921- SECTION (class : ' todo-app' ) do
922- Header ()
923- Route (' /' , exact: true ) { Redirect (' /all' ) }
924- Route (' /:scope' , mounts: Index )
925- Footer () unless Todo .count.zero?
926- end
919+ render(SECTION , class : ' todo-app' ) do
920+ Header ()
921+ Route (' /' , exact: true ) { Redirect (' /all' ) }
922+ Route (' /:scope' , mounts: Index )
923+ Footer () unless Todo .count.zero?
927924 end
928925end
929926
@@ -956,9 +953,7 @@ class Footer < HyperComponent
956953 LI { NavLink (" /#{ path } " , active_class: :selected ) { path.camelize } }
957954 end
958955 render(DIV , class : :footer) do
959- SPAN (class : ' todo-count' ) do
960- " #{ Todo .active.count} item#{ ' s' if Todo .active.count != 1 } left"
961- end
956+ SPAN (class : ' todo-count' ) { " #{ pluralize(Todo .active.count, ' item' ) } left" }
962957 UL (class : :filters) do
963958 link_item(:all )
964959 link_item(:active )
@@ -987,11 +982,11 @@ end
987982
988983# app/hyperstack/components/edit_item.rb
989984class EditItem < HyperComponent
990- param :todo
991- triggers :save
992- triggers :cancel
993- others :etc
994- after_mount { DOM [dom_node].focus }
985+ param :todo
986+ fires :save
987+ fires :cancel
988+ other :etc
989+ after_mount { jQ [dom_node].focus }
995990 render do
996991 INPUT (@Etc , placeholder: ' What is left to do today?' ,
997992 defaultValue: @Todo .title, key: @Todo )
0 commit comments