Wednesday, November 26, 2014

Native Form Inputs with Polymer


Polymer's inability to define form elements still bugs me. Recent work to support this in Paper Elements is progress, but sometimes you just don't want an input element that looks like a Google property.

I have a solution in Patterns in Polymer. Said solution works with minimal overhead in both JavaScript and Dart. Still, there is overhead and the penalty is paid by the developer using my awesome custom element... which makes my awesome custom element slightly less awesome.

The current approach in Patterns in Polymer requires additional code to sync a hidden <input>'s value with that of the Polymer custom element. So why not have the Polymer element be responsible for synchronizing with the hidden input? And why not take that a step further by making the Polymer element responsible for creating the hidden input in the containing light DOM?

The answer to the last question is encapsulation. But darn it, if Polymer can't make native form elements then screw encapsulation. This turns out to be surprisingly easy to implement. To add support to the <x-pizza> element for a "toppings" form input value, I can add a hidden input when <x-pizza> is attached to the DOM:
@CustomTag('x-pizza')
class XPizza extends PolymerElement {
  Element lightInput;
  // ...
  void attached() {
    super.attached();
    // ...
    lightInput = new HiddenInputElement()..name = 'toppings';
    parent.append(lightInput);
  }
  // ...
}
With that element in the light DOM, I can keep it in sync with the internal pizza state by making the already defined _updatePizzaState() method responsible for updating the hidden field as well:
@CustomTag('x-pizza')
class XPizza extends PolymerElement {
  // ...
  updatePizzaState([_]) {
    // ...
    if (lightInput == null) return;
    lightInput.value = state;
  }
  // ...
}
And that works perfectly fine:



I still think that the MutationObserver approach is a useful pattern for the book, but I am hard-pressed to think that it is a better solution than a breaks-encapsulation, light-DOM input. I'll give it a day or two for this idea to percolate, but I may need a chapter rewrite shortly.


Day #6

No comments:

Post a Comment