Attributes / DOM Binding

Suppose we need to add an attribute to our button, which regulates whether the button is enabled or disabled. We obviously need this attribute to change the disabled attribute on the <button> element. First, let's add this attribute into the Component.attribute_names array:

export class MyButtonComponent extends extend_as("MyButtonComponent").mix(Component).with() {
  constructor() {
    this.attribute_names = ["caption", "disabled"];
  }
}

Then, let's change our html code and add a special html attribute to our button, which will connect the disabled attribute of the Component:

Now, if we change the attribute:

button1.set("disabled", "disabled");

Webface.js will update the html in the document to look like this:

Notice how the disabled="disabled" attribute was added to the <button> element. Of course, the data-component-attr-map can be added not just to the dom element of the component, but also to any of the descendant nodes of that element - then the component will update them upon attribute change.

The syntax of the data-component-attr-map is the following: attr_1:html-attr-1,attr_2:html-attr-2. That is, you can have multiple pairs of component-attribute names and html-attribute names, separated by commas. Html-attribute names may be different from component-attribute names. For instance, consider the following code:

In this example the component-attribute inactive binds to the html-attribute disabled. And we also have one more attribute called button_type (needed for whatever reason!) that binds to the attribute data-button-type.

There is also a more concise, simplified way to write attribute map - you can just list attributes, separated by commas like this:

In this case, disabled and button_type attributes of our ButtonComponent will automatically bind to data-disabled and data-button-type html-attributes of the <button> tag. In other words, the previous code is equivalent to writing:

However, the good news is, you don't even have to write data-component-attr-map at all. By default, Webface.js Component instances will look for the corresponding html data- attributes when they are trying to update attribute value in the dom. So you could've easily had the following html:

and updating attribute with button1.set("button_type", "special button") would've updated this html to: