I'm trying to add a Polymer UI to an existing HTML page which contains a form. I don't have control over the content of the page, only the header and footer, so I can't change the form to use Polymer elements rather than <input>. So instead I'm trying to rewrite the form using Javascript.
I'm finding that adding an is attribute to an existing element has no effect --- the element doesn't get upgtaded.
I presume that this is all happening at a point after which Polymer has scanned the DOM looking for is attributes, so it's not noticing my change. (Although creating a new element with an is attribute and adding it also doesn't work, which is kind of weird, because adding a Polymer custom element does work.)
Is there any way around this; such as telling Polymer when I add the new element so that it can be upgraded properly?
To use is=, you must be extending a native element. These are called type extension custom elements (http://www.html5rocks.com/en/tutorials/webcomponents/customelements/#usetypeextension).
In general, I don't believe adding the is= attribute at a later time has any effect on upgrading the element. The element needs to be declared up front with is= (e.g. <input is="core-input">) or instantiated dynamically using the special version of createElement:
var input = document.createElement('input', 'core-input');
In the declared case, this is the parsers signal to alter the prototype of the element when it's seen. In the JS case, that's done at creation time. If you just use el.setAttribute('is', 'core-input'), the element's prototype is already created by that point so it has no effect.
Related
TL;DR: I'm looking for slots but without shadow dom
I'm looking for a solution that should "change" something like:
<form-control>
element(s): like input, select, custom elements containing form elements
</form-control>
into something like:
<form-control>
<label></label>
<div>
element(s)
</div>
</form-control>
where form-control is the needed custom element; now specific for forms, but a general wrapper solution is a good thing to know
Solutions I think about:
using shadow dom and slots: that will be the natural solution, but until the form participation api will be widely supported it's not a solution; plus, including bootstrap css in every 'small' web component is overkill (and selecting only needed css classes is even more overkill), so I am using web components (with shadow dom) only at 'top' level elements (like a whole form, table, modal etc., the rest are only custom elements, without shadow dom)
"moving" children from custom element into that div: it works but if a child is a custom element then connectedCallback will be called twice (because it will be moved into dom); of course connectedCallback can be guarded (one time execution), but when the child element must async load something ... well, it 'smells' trouble; if somehow a custom element could be "moved" without disconnectedCallback/connectedCallback that should work fine, but I don't think that is possible
try to use (or inspire from) a bootstrap web component collection; unfortunately I could not find any framework based on bs5
Any idea will be appreciated!
how do I refresh a specific element in html using only vanilla javascript.
the goal is after adding an attribute to it with a value.
I will refresh the element.
Libraries like React are built for this purpose. But we can sort of do it with pure Javascript too. Here's what we need to do:
delete the element with parent.removeChild(element)
create another one with document.createElement(element)
set the properties the way you want element.setAttribute(name, value)
add it to the parent element with parent.appendChild(newElement)
I have working example here in this link: https://codepen.io/edo9k/pen/poyRJJN?editors=1010
But you can also update the element directly, instead of 'refreshing' it. Which can be done with element.setAttribute or getting the attribute directly like a I do changing the font size of the element in line 20 of the example: elm.style.fontSize = counter + "pt";.
Your question lacks context, but depending on what you're trying to do, you should consider a library or some alternative method of updating this element. There might be security issues doing it like the way I'm proposing here, both by modifying attributes directly or by deleting/adding a new element.
You can find detailed explanation of all these API function in Mozilla's Web Docs: https://developer.mozilla.org/pt-BR/docs/Web/API
I am tying polymer elements in with an existing framework and I am looking for a way to publish events to my framework when certain properties are set on my elements, but only when they are set from a source other then my framework.
For example, I have a custom input element with a "caption" attribute. If data binding inside my elements or some source other than my framework sets the caption property on my control, I want an event published to my framework informing it that the caption property changed, but if my framework sets the caption property, I do not want to publish the event.
I currently publishing these events in an observe block. I have a function on my elements called setFromExternalModel(prop, value) that I use to set the value of a property from my framework. If there were some way for me to pass data from this function on to the observe block, I could prevent the event from being published, but I haven't been able to come up with an elegant way to do this.
Thoughts?
Why is it important to not fire events if your framework changes a property?
It is much less complicated to treat all property changes the same way.
Polymer's core and paper elements have no concept of framework/user data changes, and we haven't thought of any use cases where this would be important.
We'd like to be able to replace element definitions at run-time. No need to assume that elements in the DOM will be magically updated. We'd just like to be able to recycle the element name.
What is the recommended method for removing Polymer elements from the page/registry entirely?
e.g. Remove for version 1, add for version 2.
You can't. Once a custom element name is registered on the page, it can't be re-registered. Try running var XFoo = document.registerElement('x-foo'); twice in the console in Chrome.
In a future version of the Custom Elements spec there may be an element registry to manage. But that's a ways off.
I am creating a site that allows viewing and editing the contents of the 'src-div' contents within the 'edit-div.' I am not editing the src-div directly, because its thumbnailed using css zoom property.
I have considered using knockout.js to bind both elements to an observable. Currently, I have implemented the feature with jquery .html() function: simply set edit-div innerhtml to src-div innerhtml on 'select', and reverse the process after changes are made to edit-div to update the src-div.
I am wondering if I really need 2 divs here, or if there is some way to actually view the same element twice on a page, and any changes made will automatically reflect in both 'views,' elimiating the need to copy innerhtml property back and forth between two elements.
essentially, this is like a mirror effect, without the flip.
the closest thing I found so far is:
http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Reflections/Reflections.html
Any recommended practices for performing this task are appreciated.
(Almost) everything you see on a page has a counterpart in the DOM. Everything in the DOM gets exactly rendered one time (apart from pseudo-classes). And every node in the DOM can only have one parent (no exclusions).
Unfortunately you'll have to clone the specific node and add changes to both, as there is no copy & translate mechanism in the current CSS documentation.
If you're using jquery you can use one div and "clone" it. You can read this for more information.
http://api.jquery.com/clone/
If you set the class of the div to the same thing, you can have changes propagated to both. Then you can apply .addClass to the second div to apply a "reflected" affect (if that's your final goal).