Easy apps with hyperHTML — 2, Events and components
Tags: javascript, hyperhtml, tutorial, webdev
Published: 2019-05-28 14:04:21

[Version en español](https://medium.com/easy-apps-with-hyperhtml/aplicaciones-f%C3%A1ciles-con-hyperhtml-2-dd264fa495e5)

[中文版](http://www.lofter.com/lpost/1f16161f_12b7a08fe)

Part 2 written by {% user pinguxx %} {% user paritho %}

1.  [Introduction, wire/bind](https://dev.to/pinguxx/easy-apps-with-hyperhtml-1-31cc)
2.  **Events and components**
3.  [Moar about components and simple state management](https://dev.to/pinguxx/easy-apps-with-hyperhtml-3-1m3l)
4.  [Wire types and custom definitions (intents)](https://dev.to/pinguxx/easy-apps-with-hyperhtml-4-38k3)
5.  [Custom elements with hyper](https://dev.to/pinguxx/easy-apps-with-hyperhtml-5-13hc)
6.  [Customizing my custom elements](https://dev.to/pinguxx/easy-apps-with-hyperhtml-6-1e73)
7.  [Testing!](https://dev.to/pinguxx/easy-apps-with-hyperhtml-7-5b9g)
8.  [Async loading, placeholder and a Typeahead with hyper](https://dev.to/pinguxx/easy-apps-with-hyperhtml-8-async-loading-5d96)
9.  [Handling routes](https://dev.to/pinguxx/easy-apps-with-hyperhtml-9-routing-59k0)
10.  [3rd party libraries](https://dev.to/pinguxx/easy-apps-with-hyperhtml-10-3rd-party-libraries-2n7b)

![](https://thepracticaldev.s3.amazonaws.com/i/ttyywhl48ay1jv635ans.jpeg)

If you followed along in [part 1](https://dev.to/pinguxx/easy-apps-with-hyperhtml-1-31cc), you now know the basics to begin working with hyperHTML. We can now dive into more complex topics. Recall the table we made in part 1:

{% stackblitz basics-table ctl=1 %}

Let’s start by enabling sorting in our column headers.

### Events

First, we are going to move the render part of our previous example to a function so we can reuse it. We started with this:

{% gist https://gist.github.com/pinguxx/1fa59056bb9a78acfc6ebc7b78eeda43 %}

We’ll change it to this:

{% gist https://gist.github.com/pinguxx/ca3f9fd8356e2df57abdfc7590f8fd3f %}


The next thing we need to do is update our column headers to contain an `<a>` tag so the user knows it can be clicked. We’ll also need an event listener to capture the `onclick` event. For simplicity, let’s also add a `data-target` attribute so we know what attribute the user is trying to sort. With these pieces in place, our `<thead>` template will end up like this:

{% gist https://gist.github.com/pinguxx/1f9886d5da544065bd67e3d31b4b3fae %}

What is that `onclick`thing? HyperHTML lets us pass a function to the event and it will be called for us. Let’s create a simple sort function to see what we are getting:

{% gist https://gist.github.com/pinguxx/24b43256a8e3f9ba799926187ab03868 %}

The target and ‘this’ are the same in this example. Great! Now we have the anchor tag, which contains the `data-target`, that we will use to sort our table. Let’s update our sort function:

{% gist https://gist.github.com/pinguxx/71b23929ed5e65bf2e4e547791194b7c %}

While that is all cool and nice, if the user clicks a second time on the header, it’s not going to reverse the sorting. This is functionality we expect our table to have, so let’s fix that and see how it all works.

{% stackblitz basics-table-1 %}

If you inspect the table code, you’ll see that only the body rows are being re-painted even tough we are calling display every time. HyperHTML is smart enough to just update the parts that were changed. This illustrates how fast it is, and how cheap its render function is to use.

* * *

### Components

Now that we have our table, it will be easier if we put all of our code related to it in a single place. In addition to cleaning up our code, we’ll be able to re-use this table in other projects. We can accomplish this with a simple object:

{% stackblitz basics-table-2 file=index.js %}

We have a basic JavaScript object with html as our render variable before, data as our array variable and state. We moved the render() out of the display() function, and notice that we no longer have sort(). Instead, we pass ‘this’ to the onclick event:

```
onclick=${this}
```

and handle it with…

#### HandleEvent

This very special function is part of the EcmaScript standard. If an object has it, it will be invoked as `obj.handleEvent(e).` This means we can attach an event listener

```
el.addEventListener('click', Table)
```

and the click event will be passed to handleEvent function. `this` will be the current object (not the element!). This solves a lot of the typical problems we encounter when handling events. For more information you can read all the amazing things handleEvent does here [handleEvent](https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38)

In our case, we are passing the current object to handleEvent. Now, we just move all the sort functionality inside of this function. Of course we can do more things with this, but this gives us all the functionality we need for sorting the table.

As an aside, you can also use a function to construct your object, just like you’d expect.

{% stackblitz basics-table-3 ctl=1 %}

Pretty much the same as above, the only change is that we added an Id to the table. If you don’t want to use classes, you can go with this approach and hyperHTML wont get in your way.

#### Classes

“That’s all nice and good but what about classes?” you may be thinking. Well, you can use them too.

{% stackblitz basics-table-4 ctl=1 %}

And now you have a class, the only thing we changed (besides making it a class) was to call the arguments props, and pass the Id inside an object. Nothing fancy, this just makes it just easier to enhance later on.

And yes, hyperHTML also has a way to create components in a very easy way. It’s called hyper.Component. This function gives you a few extras I think you’ll find helpful:

*   state handling
*   default html attribute binded to itself
*   handleEvent, but even easier!
*   onconnected and ondisconnected functions
*   and more

For more information about hyper.Component you can read the docs [hyper.Component ](https://viperhtml.js.org/hyperhtml/documentation/#components-3)

Enough selling the idea, lets see an actual demo using all the things!!

{% stackblitz basics-table-5 ctl=1 %}

First we added Component to our import (hyper.Component that is), then we extend it with the Table. The Component class takes care of “this.html”, so we removed it.

#### Handling events with Component

Where is our handleEvent function?, well component already implements it so we no longer need it either! The way Component defines handleEvent is like this:

```
this[‘on’ + event.type](e)
```

This means if you are listening for a onclick event, handleEvent will receive the event type of “click” and will call `this.onclick(e)`, and now we can have our own functions per event type `onclick(e) {…}`.

You can even have functions defined to handle custom events! For example, say you are emitting a custom event, “enroll”. You can attach the listener:

```
onenroll=${this}
```

and then handle it inside the component with:

```
onenroll(e){ /* do stuff with the enroll event! */}
```

{% gist https://gist.github.com/pinguxx/9c2187b8039c9ab50903b3de31fa1e03 %}

Back in our Table, we now have `onclick` to handle the click event on the column headers and do the sort.

#### State

Notice we added `get defaultState(){...}`. This is a function to return the initial state, so if you haven’t set or updated the state, you’ll get this default object. Read more about it in the [documentation](https://viperhtml.js.org/hyperhtml/documentation/#components-3)

We also added the `onclick` (sort function), and a call to the `setState` function. SetState will update the state object and will call render for you auto-magically. Other frameworks will update the state asynchronously for “reasons”, but since updates are very fast in hyperHTML setState will fire right away. If you need to update several things, I would recommend constructing an object and then call `setState(newobj)`.

{% gist https://gist.github.com/pinguxx/62051dc580005a9dbf34d5850a82af46 %}

* * *

We saw a lot of code this time. Hang in there, we are just beginning to scratch the surface of hyperHTML. In the next part, we will see how to use several components in an app, how to do conditional rendering and more details about components.