Easy apps with hyperHTML — 6, Customizing my custom elements
Tags: hyperhtml, javascript, webdev, tutorial
Published: 2019-06-03 17:52:19

Part 6 written by Trevor Ganus, {% user pinguxx %} {% user paritho %}

1. [Introduction, wire/bind](https://dev.to/pinguxx/easy-apps-with-hyperhtml-1-31cc)
2. [Events and components](https://dev.to/pinguxx/easy-apps-with-hyperhtml-2-hbi)
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-5hdl-temp-slug-7285698)
6. **Customizing my custom elements**
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/firfj2mwfpzudmvf3k58.jpeg)

### Recap

In parts 1–5, we talked about the basics of hyperHTML. We also learned about an amazing feature called hyper.Component. We dove into “intents ” that let us extend hyperHTML and simplify our templates. While learning all this we created a simple table:

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

Finally, we learned the basics of custom elements and a nice little utility called hyperHTML-Element, which gives us some of the `hyper.Component` features out of the box, and so much more.

In part 6, we’re going to discover how we can convert our table from a component to a custom element. We’ll also see how easy it is to add functionality to our custom element, extending it to be even more useful. Using custom elements makes it so easy to reuse our code, a baby could do it — if the [baby knew HTML](https://www.amazon.com/HTML-Babies-Code-Sterling-Childrens/dp/1454921552), and [JavaScript](https://www.amazon.com/Javascript-Babies-Code-Sterling-Childrens/dp/1454921579), of course. Also, once we have a custom element, we don’t need hyperHTML anywhere else in our app unless we want it. This makes the custom elements plug-and-play with any framework. When was the last time a React component could say that?

### Columns

Let’s start thinking about the elements of the table: header, footer and body. For our case, header and footer are the important parts. We will generate the footer based on the data just like before.

Let’s start with a custom element for the columns. This element will contain the information necessary to render:

* the label (for the header)
* the attribute used for this column (from the data)
* if it’s sortable or not
* the type of data to display

{% stackblitz intermediate-ce-07 ctl=1 %}

Simple right? We don’t even render anything, all the heavy lifting will be in the table itself.

### Table

Now let’s generate a custom element with a simple table.

{% stackblitz intermediate-ce-08 ctl=1 %}

Let’s first add a hyper-column to our HTML

{% gist https://gist.github.com/pinguxx/369bf57bea92aaff2a09991dd91c8b2c %}

Then, we need to update our created function to read the columns and store them in an array that we can reuse later:

{% gist https://gist.github.com/pinguxx/4b3f5df36a70102e99c2c0fc9bb05e3b %}

(used `[].slice.call` instead of `[…this.querySelectorAll(“hyper-column”)]` because of an error using stackblitz)

And lastly, let’s update our template to use the columns.

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

Well cool. But we are not really using data from anywhere… let’s fix that. We’ll add a data property.

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

We now need to update our `<tbody>` part of the template to show one row for each item in the data.

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

(if ``wire(column, `col${item.id}`)`` looks unfamiliar to you, review [part 4](https://dev.to/pinguxx/easy-apps-with-hyperhtml-4-38k3)!)

Of course, we still need to pass data to the table. The index file is where we’ll do that.

{% gist https://gist.github.com/pinguxx/53516e1ae48e3bd25ae49c4b6a10cb7e %}

Let’s see our full code so far:

{% stackblitz intermediate-ce-09 ctl=1 %}

To finish off the table, we need to add the rest of the columns. Notice, this is very similar to what we’ve done in previous parts of this tutorial!

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

### Intents

Recall intents from [part 4](https://dev.to/pinguxx/easy-apps-with-hyperhtml-4-38k3)? Let’s use intents to display icons and dates correctly. We happen to like the [octicon](https://octicons.github.com/) library of icons, but you can feel free to bring your own icon set.

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

Then extract the rendering of the `<td>`’s and `<th>`’s for easier reading.

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

(Note that, for user-provided values, you should be sure to use the ‘text’ type. Otherwise, use of ‘html’ could lead to potential HTML injection issues. Normally, hyperHTML will escape HTML used in expressions `${...}`).

We are using state so let’s make sure we have a defaultState set:

{% gist https://gist.github.com/pinguxx/36ce9cead46e06751de57def88954244 %}

And again update our template

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

Much easier to follow :D.

{% stackblitz intermediate-ce-10 ctl=1 %}

### State & Events

We need to be able to sort the data when a user clicks on the table header. Let’s add `onclick="${this}" data-call="headerClick"` to our a tags so we can do this. We will also need to add the `headerClick` function to handle the event.

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

Remember calling `setState` will call `render()`, so we don’t need to explicitly call `render()` here. Let’s see our table with the sorting and icons working.

{% stackblitz intermediate-ce-11 ctl=1 %}

### Footer

Then at the bottom of the table, we will add our footer.

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

Nothing fancy here. Aaannddd we are done… or at least we replicated the component we had with custom elements. This is no small thing. Now, we can just use `<hyper-table>` with some `<hyper-column>` inside and you have a simple yet functional table.

{% stackblitz intermediate-ce-12 ctl=1 %}

![](https://cdn-images-1.medium.com/max/500/1*UrLtjrYjonasE97oiL6f8A.jpeg)

### Customization

Every good table should be able to add/update/remove columns, right? Glad you asked! Let’s add some functions to our table that will allow us to do just that.

First let’s add to our column element a new attribute called name. This will be used to update/remove columns. If no name is passed we’ll just use the attribute.

#### addColumn

We will let the developer add a column by passing a new `<hyper-column>`. We’ll also allow an object to be passed with the attributes needed. This will update our columns array.

{% gist https://gist.github.com/pinguxx/2353b1aa6676018620e1fa101e250bf9 %}

#### removeColumn

Based on the newly added name to the column, we can easily remove columns from the table. In theory we could use index instead of name, but I wanted to show that we can do either with the elements.

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

#### updateColumn

Again using the name attribute, we can update the column details.

{% gist https://gist.github.com/pinguxx/4709a0e83d85e4465ca8d4b62b2b5bdf %}

Let’s see how it looks:

{% stackblitz intermediate-ce-13 ctl=1 %}

Well, that was easy, and we enhanced our table with very useful functionality!.

Now you are a custom element/hyperHTML master :D. Or, at least you can start creating your own elements! In the next part we are going to add testing to our table element and maybe add the ability to filter the table display. Please send us your feedback to improve this tutorial.

* * *