DEV Community

Ivan
Ivan

Posted on • Edited on

Easy apps with hyperHTML — 2, Events and components

Version en español

中文版

Part 2 written by

pinguxx image
paritho image
  1. Introduction, wire/bind
  2. Events and components
  3. Moar about components and simple state management
  4. Wire types and custom definitions (intents)
  5. Custom elements with hyper
  6. Customizing my custom elements
  7. Testing!
  8. Async loading, placeholder and a Typeahead with hyper
  9. Handling routes
  10. 3rd party libraries

If you followed along in part 1, 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:

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:

We’ll change it to this:

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:

What is that onclickthing? 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:

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:

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.

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:

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

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.

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.

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

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

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! */}

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

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).


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.

Top comments (0)