Is it possible to use querySelector() on a dynamically created element? - dart

I'm using appendHtml() in a loop to dynamically add li elements (with unique IDs in the string) to a ul. When I need to access these dynamically created li elements by their IDs to, for example, create nested lists, querySelector() returns null. If I should be able to do this, then there could very well be bugs in my code. But I want to make sure this is the case.

It doesn't matter how elements are added, if the are part of the DOM querySelector can find them.

Related

Define custom element within another custom element only

We know that we can register our custom element like this:
customElements.define('x-my-element', MyElement);
And now, this element is available like so:
<x-my-element>Woo</x-my-element>
However, is there some sort of a scoped CustomElementRegistry for a specific ShadowRoot?
I'm working on a browser plugin that needs to inject some custom elements into a page, but I want to avoid accidentally colliding with custom elements that the host page may have defined. If I define an outer custom element, and all elements within are defined to work only within that outer custom element, that solves the problem.
(As an alternative, I'll probably just randomly generate element names with a build script.)
There is a proposal for scope registries, no consensus:
https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md
https://github.com/WICG/webcomponents/issues?q=is%3Aissue+is%3Aopen+scoped

Vaadin 14 TreeGrid - Cannot add the same item multiple times

Working on a project that will display hierarchies of "tasks". I'm running into a problem where it will not allow for multiple entries of the same object. From what I can tell, the "duplicate" item is under a different parent.
The domain data allows for this - a given task may appear in lots of places.
It would seem that this is intentional (maybe), but is there a way around this?
It's intentional to a degree; each Grid and TreeGrid data item is expected to be unique. You could work around this by creating your own implementation of the hierarchical DataProvider class (for example extend AbstractHierarchicalDataProvider) which overrides the getId method along with the other required methods. The return value of this method needs to be unique per item, as it's used as a hash key.
Well, this is probably not the best solution, but it works.
I added a field to the abstract super class that is initialized with the current time (long ms). When I am adding items to the tree grid, I check to see if the tree contains the item and if so, I randomize the field and then add it. The new field is marked #Transient so it's not persisted.

Can Orbeon controls have multiple values?

I think the answer is no, but the question has been put to me so I'd like to confirm. My understanding is that any custom XBL control that I create for use in Form Builder can have one and only one value. Is this correct?
I have always assumed this because the control name is then used in the data instance as the name of the node which contains the the value.
This question comes from the desire to have reusable components with multiple values, for example, an Address control so that addresses can be recorded consistently and the same set of fields does not need to be added many times. Orbeon does have some support for this in the form of Section Templates but because the control names stay the same in each instance of a Section Template this does not work well with our design.
The best idea I've had is that a custom control which records multiple values could encode all the values into a single text string for example in JSON. Of course, this is not ideal.
Are there any other options?
It is possible for controls to have multiple values. When that happens the values are typically stored in nested elements. I.e. a control could bound to an element <address>, and could create nested elements <street>, <city>,<country>, etc to store the different parts of the address.
In practice, you can look at how this is done in the Image Annotation annotation control (see wpaint.xbl), which creates nested elements <image> and <annotation>, leveraging the xxbl:mirror="true" functionality.

Dart observable list that does not delete and reinsert all elements on change

We have some code that has a custom web component to display each element in an observable list. It seems that when an element is added to the list, the Web-UI infrastructure sees fit to remove all of the DOM nodes that represent elements in the list, and then re-add them along with the new element.
Not knowing much about the internal workings of the Dart-UI code, I would actually expect the addition of an element in the observable list to simply add one (or more) nodes to the DOM, without removing any of the existing nodes from the DOM.
Is it possible to achieve this sort of behavior?
There is an open issue for this: https://github.com/dart-lang/web-ui/issues/431. John wrote
fwiw, I'm working on a data-binding overhaul right now. The new
implementation includes stable lists by default.
so this should be fixed eventually.

Accessing Template Elements Prorgramatically in Web UI

Is there any easy way to access the associated element object of an element declared in your template. For instance say I have a button on my template and I want to access the ButtonElement object so I can manipulate it programmatically.
I appreciate I could give it an ID and query for it onInsert. Is this the best practise? If so how do I stop the ID's not being unique if multiple instances of the component are used or is the query restricted to the Shadow DOM?
I appreciate I could give it an ID and query for it onInsert. Is this the best practise?
It's not if you have multiple of them (as you realized). Duplicate ID's do not only happen when used multiple times in the same component, but also if the component is inserted multiple times to the page.
You can always go with traditional classes:
...
<template>
<div class="some-part-of-your-component">foo</div>
</template>
...
DivElement somePart;
inserted() {
somePart = _root.query('.some-part-of-your-component');
}

Resources