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