Dynamically instantiate, add polymer elements dart - dart

Trying to dynamically add polymer elements
on the click event not able to add the element
tried using initPolymer (resulting in stack error :element already initialized)
4 files.
item.html
<polymer-element name="init-item" >
<template>
<input type="image" src="button_minus_red.gif" on-click="{{remove}}">
{{Name}}
</template>
<script type="application/dart" src="item.dart"></script>
</polymer-element>
item.dart:
import 'package:polymer/polymer.dart';
#CustomTag('init-item')
class Item extends PolymerElement{
#observable String Name='hello';
void remove(){
Name='';
}
PlayerItem.created(): super.created(){}
}
index.dart:
import 'package:polymer/polymer.dart';
import 'item.dart'
// getting unused warning for item.dart
main() async{....
//init moved to main
initPolymer().then((_) {});
}
//adding to form element on click event
Code to run(click event)
{ //onReady added here
Polymer.onReady.then((_) { yourPlayer.children.add(new Element.tag('player-item')) ;});
}
tag added to index.html and also dynamic addition as shown above.
Due to above changes when page reloaded was automatically getting custom element included.
Removed the element form the index.html
works as expected (no Errors)
Previous error:
when used initPolymer
element added in place of tag and also within form.
on subsequent click events added within form but stack error(initialization already done)
Are there any issues due to async(highly false)? How should I approach this?

item is not a valid Polymer- or Custom Element name. It is a requirement that custom elements must have a dash in their name like my-item.
At the top of your question you write about a click event but the code example at the bottom shows you're doing it from main().
This two things are quite different.
If you call the code in the click handler of a Polymer element it should just work.
If you have a custom main you need to ensure Polymer is initialized properly before you instantiate elements.
See https://stackoverflow.com/a/20982658/217408 for more details.
import "package:polymer/polymer.dart";
main() {
initPolymer().then((zone) => zone.run(() {
Polymer.onReady.then((_) {
var yourPlayer = querySelector('#people');
yourPlayer.children.add(new Element.tag('player-item'));
});
}));
}

Related

Svelte - pass use:action to component child

I'm new to Svelte and it is very likely I'm missing something here.
I'm using sveltestrap and svelte-spa-router.
When I try creating a <Button> (from sveltestrap) and using the link action (from svelte-spa-router) like this:
<script>
import { Button } from 'sveltestrap';
import {link} from 'svelte-spa-router';
let myLink = '/foo/bar';
</script>
<Button use:link={myLink}>
Click here
</Button>
I get the following error:
[!] (plugin svelte) ValidationError: Actions can only be applied to DOM elements, not components
My expectation was that somehow (??) the <Button> would 'pass down' the use:link to the child html node.
Is there a best practice for this type of situation?
Since you're using a button component, you might want to change your code to use push rather than link in the on:click event.
<script>
import { Button } from 'sveltestrap';
import { push } from 'svelte-spa-router';
let myLink = '/foo/bar';
</script>
<Button on:click={() => push(myLink)}>
Click here
</Button>

Access elements in Angular Dart

I have a top level element <x-app> with nested modal dialogs
<x-app>
<material-content>
...
</material-content>
<x-alert-dialog></x-alert-dialog>
</x-app>
where <x-alert-dialog> contains
<modal [visible]="dlgVisible" dialog-id="alert-dialog-modal">
<material-dialog class="alert-dialog">
....
</material-dialog>
</modal>
Generated HTML contains <x-app> and overlay container div which contains modals as on the image
What I need is to access <div pane-id="default-1"...> to change z-index. and I don't know how. I cannot access it in CSS as any reference via :host is not possible.
I tried to access it programatically in x-app component. I have
class AppComponent implements AfterViewInit {
#override
void ngAfterViewInit() {
var doc = getDocument();
var alertDlg = doc.querySelector(".alert-dialog");
var alertPane = alertDlg.parent;
}
}
But alertDlg is always null. I also tried var alertDlg = querySelector(".alert-dialog");
Is there any way to access the element?
I solved it by adding *ngIf="dlgVisible" to <modal> tag, so it's now
<modal *ngIf="dlgVisible" [visible]="dlgVisible" dialog-id="alert-dialog-modal">
This way the dialog is injected to/removed from DOM by the visibility flag. The reason why I wanted to change z-index was to get the alert and other app wide dialogs above other dialogs created later in other components.
Altering DOM solves this as the dialogs are inserted after (and thus displayed above) other dialogs. Hope this will help someone.

How to remove "on-click" from a custom Polymer component

I have a custom button component done in Polymer Dart:
<div id="buttonDiv">
<my-button id="traceButton"
mode="icon" faicon="fa-comment-o"
toolTip="Print a simple comment"
disabled="false" on-click="{{ traceSomething }}">
</my-button>
</div>
I'm trying to copy/paste this button somewhere else. So a user defines it somwhere, and I basically move it by way of getting $['buttonDiv'].children then inserting it somewhere else. The problem is that {{ traceSomething }} is now irrelevant since it's not part of the new parent. I get errors saying that the parent object, which is another polymer component doesn't have an instance getter "traceSomething".
My question is, is there a way to remove "traceSomething" before I insert it somwhere else? I tried removing the "onClick" event listeners, but the buttons still wants to call that function upon click. Also, I've tried adding a preventDefault, etc, like in: In Dart, if I listen to a click event with two listeners, how do I know which happens first?
But, no luck.
I'm not sure what you mean by copy/past. Do you clone the element, or do you just append it to some other elements children.
Anyway, I don't think you can remove the event listener if it was added declaratively. If you add it imperatively it is easy to remove and readd later.
import 'dart:async';
...
StreamSubscription subsc;
#override
attached() {
super.attached();
subscr = onClick.listen((e) => (this.parentNode as ShadowRoot).host.traceSomething(e));
}
#override
detached() {
super.detached();
if(subscr != null) {
subscr.cancel();
}
}
See also https://stackoverflow.com/a/22168745/217408 about accessing the parent of a Polymer element (for Dart Polymer <= 0.16.x)

Taking total control of PaperInput validation

I'm using PaperInput and like the feel. But, is there a way to do the validation using my own logic? For instance, in some cases a pattern match is not enough to determine the error I'd like to display. An example would be I want the PaperInput to specify an item which can only be added once, so the validation would do a lookup in some model map and if input.inputValue is not present it is valid, otherwise invalid.
<paper-input floatingLabel
id="alias-input"
validate="{{aliasIsValid}}"
type="text"
error="{{aliasError}}"
label="Person Alias (eg: King, Eldest Son, Mooch, etc.)"
required
></paper-input>
So, I would like to be able to implement bool aliasIsValid() and set #observable String aliasError when validation is invalid. I do not think this is how it works, but is there a way to achieve this?
Polymer.dart <= 0.16.x
import 'dart:html';
import 'package:polymer/polymer.dart';
import 'package:core_elements/core_input.dart';
#CustomTag('app-element')
class AppElement extends PolymerElement {
AppElement.created() : super.created() {}
void inputHandler(Event e) {
var inp = ($['custom'] as CoreInput);
// very simple check - you can check what you want of courxe
if(inp.inputValue.length < 5) {
// any text is treated as validation error
inp.jsElement.callMethod('setCustomValidity', ["Give me more!"]);
} else {
// empty message text is interpreted as valid input
inp.jsElement.callMethod('setCustomValidity', [""]);
}
}
}
To validate only when the input element loses focus remove validateImmediately from the HTML element and use the on-change event instead (not tested).
<paper-input id="custom" on-input="{{inputHandler}}" validateImmediately></paper-input>
I added a comment at https://github.com/dart-lang/core-elements/pull/102 to make this method available directly in Dart with the next update.
The documentation of <core-input> states that the HTML5 constraint validation API is supported. For more information see
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation

Access Polymer inner element programmatically

I'm enclosing my app in a Polymer element and I want to use another polymer element inside it. To call all the method of the inner element I'm trying to use $[].
Insider the external polymer element I have this:
ImageEditor ime;
DivElement div2;
ImageTool.created(): super.created(){
div2 = $["secondDiv"];
ime = $["imageEditor1"]
}
In the Html I simply have:
<polymer-element name="da-imagetool">
<template>
<div class="images" id="mainDiv">
<da-imageeditor id="imageEditor1" name="ied"></da-imageeditor>
with the script src at the end.
For some reason I get an exception when I assign the imageEditor1 to ime.
Exception: type 'HtmlElement' is not a subtype of type 'ImageEditor' of 'value'.
It looks like the browser hasn't upgraded the <da-imageeditor> elements.
Make sure that you <import> the <da-imageeditor> element, and have the correct #CustomTag annotation on the ImageEditor class declaration.
This is most likely an issue with the import path.
If you don't use the right path the type is not recognized (canonicalization problem)
This bug should be solved since a while
https://code.google.com/p/dart/issues/detail?id=15953
but I haven't worked with Polymer since.
Show your import paths (HTML and Dart) and the directory structure of your app (where is your entry page and your Polymer elements) then I'll take a look.
Which version of dart-polymer are you using? With the 0.9.5, the following lines:
XElement.created(): super.created() { print($['el-id']); }
void enteredView() { print($['el-id']); }
In created(), the referred element gives nothing whereas in enteredView(), it does refer to the specific element of the shadow root.
The behavior disappears if shadowRoot.querySelector('#el-id') is used in lieu of the shorthand map $['el-id'].

Resources