I just completed the writeup for using custom Polymer elements in plain-old HTML forms in Patterns in Polymer. Now I wonder if the entire premise was wrong. That's par for the course for me, but thankfully I have these little research spurts to allow me to investigate.
The solution currently presented in Patterns in Polymer is based on using mutation observers to watch a Polymer attribute, updating a hidden HTML form element accordingly. That works fine and really is not too much code. Still, I wonder if there is a better solution. Specifically, what if the Polymer inherits from InputElement? Would the Polymer work directly inside a form like any other element?
In the Dart version of a very simple
<hello-you>, I update the polymer-element declaration to extend the input element:<polymer-element name="hello-you" extends="input">
<template>
<!-- ... -->
<input type=text name="embedded_polymer_param" value="{{value}}">
<!-- ... -->
</template>
<script type="application/dart" src="hello_you.dart"></script>
</polymer-element>Then, in the backing hello_you.dart, I change the class to extend InputElement and mixin both Polymer and Observable:@CustomTag('hello-you')
class HelloYou extends InputElement with Polymer, Observable {
@published String value;
HelloYou.created() : super.created() {
polymerCreated();
}
// ...
}Since this no longer extends PolymerElement directly, I also have to manually invoke polymerCreated() when the element is created.With that, I am ready to use a “hello-you” version of an
<input>. Since this is extending a built-in field, I have to use the regular HTML name and tack on is="hello-you" to use the extended version: <form action="test" method="post">
<input type=hidden id=your_name>
<h1>Plain-old Form</h1>
<input type=text name="plain_old_param">
<input name="polymer_value" is="hello-you">
<input type=text name="distributed_param">
</input>
<button>Play</button>
</form>And that works. Kind of.When I submit the form, I see the value from the Polymer extended
<input> among the form parameters:plain_old_param: polymer_value:asdf distributed_param:The problem is the use of the
<input> element. It does not accept child elements, which breaks trying to project content into the Polymer:
The element with the “Projected” placeholder text ought to be rendered in the Polymer, not to the side. There is also the weird styling on the
<input>. Well, not too weird, this is an <input> after all. Still, it would have to be addressed if I wanted to push this further.The main reason that I would be unlikely to use this approach over mutation observing is that it makes it hard to work with multiple values from the Polymer. Also, unless I am mistaken, extending browser elements does not work at all in the JavaScript version of Polymer. The example given in the documentation extends another Polymer, not a standard browser element. When I tried it in JavaScript:
<polymer-element name="hello-you" extends="input" attributes="value">Then the element was ignored completely.
Phew! So a complete chapter rewrite is not necessary, which is always nice. I will likely add a sentence in the JavaScript version of Patterns in Polymer about not being able to extend built-in elements. It may be a paragraph about the limitations of doing so in the Dart version. But either way, the current mutation observer approach seems solid.
Day #1,022
No comments:
Post a Comment