DEV Community

Joe Boris
Joe Boris

Posted on • Updated on

Simple JS UI Components

The Web Component APIs in JavaScript are great, but they're relatively new and kinda hard to learn. They're also struggling to gain traction in the industry still (at the time of writing), making them a little risky to invest in. In the meantime, there are simple patterns you can follow to make components in vanilla JavaScript without the Web Component APIs.

First, let's establish a more declarative way to create a DOM node. You can use a library like jQuery, or define a function to do it yourself. In this article let's use our own function called $.

// Return a DOM element created from parsing the HTML string
function $(html, properties = {}) {
  const template = document.createElement("template");
  template.innerHTML = html.trim();
  const element = template.content.firstChild;

  // Copy the properties to the element
  Object.assign(element, properties);

  return element;
}
Enter fullscreen mode Exit fullscreen mode

Usage:

const form = $(`<form></form>`);
Enter fullscreen mode Exit fullscreen mode

Now let's make a little component. Let's say we want a generic CRUD form component...

function newCrudForm(data, mode) {
  const form = $(`<form></form>`);

  render(mode);

  function render(mode) {
    form.innerHTML = "";

    const disabledInRead = mode == "read" ? "disabled" : "";

    form.append(
      $(`<label>Text: </label>`),
      $(`<input type="text" ${disabledInRead} />`, {
        value: data.text,
        // NOTE: Using this method syntax will bind 'this' to the textbox
        oninput() {
          data.text = this.value;
        },
      }),
      $(`<button>${mode == "read" ? "Edit" : "Save"}</button>`, {
        onclick() {
          const newMode = mode == "read" ? "update" : "read";
          render(newMode);
        },
      })
    );
  }

  return form;
}
Enter fullscreen mode Exit fullscreen mode

Note: For simplicity, I didn't implement two-way binding, but it can be added to $ easily

Usage:

const data = { text: "example text" };
document.body.append(newCrudForm(data, "read"));
Enter fullscreen mode Exit fullscreen mode

Explanation

newCrudForm returns a form element with its own "state". Its state consists of the data object and the mode string. The data state is bound to the textbox. To change the mode state and react to the change, we just need to re-render and pass in a new value. That's what the button does.

Note: "state" is just the info associated with a component

Conclusion

Hopefully you'll find this easier to learn than the Web Component APIs like I did. Thoughts? Questions? Criticism? Leave a comment below 👇

Top comments (2)

Collapse
 
dannyengelman profile image
Danny Engelman

You have created a fancy DOM element, but this is not a Web Component created with the Custom Elements API

Collapse
 
jdboris profile image
Joe Boris

Thanks for the comment. That's what I meant by the first paragraph, but maybe the title was misleading. I updated it just in case