Shadow DOM
Se trata de una técnica que está siendo utilizada recientemente para salvar el problema de la encapsulación en el propio HTML.
Cuando creamos elementos reutilizables, deseamos que vengan encapsulados, de forma que no interfieran con los demás elementos, funciones y estilos de la web. ¿Pero cómo evitamos que cualquier llamada JQuery, o cualquier estilo pueda afectar a los diferentes elementos de los que se compone nuestro elemento Polymer?
Una vez más, la respuesta es el Shadow DOM. Se trata de una capa de abstracción que se introduce en el DOM del navegador, que “esconde” los elementos que se encuentren dentro. Cuando creamos un elemento Polymer, la plantilla que lo forma se encuentra diréctamente dentro de una capa de Shadow DOM, que podemos ver en inspector de elementos del navegador como #shadow-root. Todo elemento o script exterior a ese #shadow-root no podrá acceder a elementos interiores, de forma que nos aseguramos una perfecta armonía entre los elementos que reutilizamos y el código ya existente en la web.
Utilizando elementos en un Form clásico
Si nos paramos a mirar en el inspector del navegador cómo está hecho el interior del elemento paper-checkbox, podemos observar que no tiene ningún input, sino que se compone de div con atributos de estado. Esto, sumado a que los elementos dentro de un shadow-root no son accesibles para ser enviados por un submit externo vía POST, nos complica sacarles el partido a en un formulario clásico.
¿Cómo salvamos este problema? Tenemos varias opciones.
Lo más indicado cuando estamos trabajando con Polymer en nuestra aplicación sería tirar por la borda la manera clásica de formar y enviar los formularios y cambiarlos por elementos Polymer propios que interactuan con el Back-End del servidor por Ajax y se comportan de una manera más dinámica y fluída. Por ejemplo, podemos hacer que al clicar en el botón de Enviar, se realice una transición entre el formulario que hemos rellenado y la siguiente vista que se nos va a mostrar, en vez de cambiar de página de forma brusca y sin animaciones con un POST y un GET.
Pero seguramente os haya pasado que queráis ver la utilidad de estos elementos en una página ya existente, seguramente utilizando algún framework de servidor y no os sea posible cambiar la manera en la que trabaja con los formularios. En este caso no estamos vetados a trabajar con Polymer en nuestra aplicación. Lo que tendremos que hacer es interactuar con los elementos de Polymer y los elementos input que el formulario necesita.
Siguiendo el ejemplo del CheckBox, vamos crear un input de tipo checkbox invisible que será el que envía la informácion por POST y lo actualizaremos cada vez que elpaper-checkbox cambie de valor.
Además, no olvidemos que los elementos de tipo checkbox sólo envían información al servidor si están marcados, por lo que es una práctica muy utilizada el poner un input adicional de tipo hidden con el valor false y el mismo atributo name, de forma que si el primer input no vale true, enviará la información de este segundo. Veamos el ejemplo anterior con un form.
<!DOCTYPE html> <html> <head> <!-- 1. Cargar platform.js soporte de elementos. --> <script src="bower_components/platform/platform.js"></script> <!-- 2. Usar HTML Import para cargar el papaer-checkbox y sus dependencias. --> <link rel="import" href="bower_components/paper-checkbox/paper-checkbox.html"> </head> <body> <form> <!-- 3. Utilizamos el elemento en nuestra página. --> <paper-checkbox id="paperBox">Hello World!</paper-checkbox> <!-- 4. Añadimos inputs clásicos invisibles para un checkbox. --> <input type="checkbox" id="helloBox" name="helloBox" hidden /> <input type="hidden" name="helloBox" value="false" /> <input type="submit" value="Enviar" /> </form> </body> </html>
Ya tenemos los inputs, sólo nos falta actualizarlo con los cambios del paper-checkbox. Para esto, utilizamos un evento que lanza el propio paper-checkbox llamado change cada vez que cambia de valor. Este evento como los que puedan tener otros elementos, son listados en la documentación, dentro del html de paper-checkbox que estamos importando, o bien en la documentación de Polymer.
Veamos el código JavaScript que necesitaría el ejemplo.
<script> document.querySelector('#paperBox').addEventListener('change', function (e) { $('#helloBox').attr('checked', $('#paperBox').attr('checked') != undefined); }); </script>
Utilizando el método querySelector, añadimos un manejador al evento change que paper-checkbox lanzará automáticamente cada vez que el usuario modifique el valor. Así, con ayuda de JQuery, accedemos al valor que tiene actualmente el paper-checkbox y le aplicamos ese mismo valor al atributo checked de nuestro input checkbox.