How to create an instance of Polymer element programmatically? - polymer

Please refer to this JSBin, basically I would like to create an instance of an element in its parent element scope. Wondering how should I do this?
If possible, is there a declarative way to do this?
Thanks.
PS. Please open the link in Chrome only.

There are several ways to instantiate and element.
Declarative:
<my-element>
JS:
document.createElement('my-element');
Constructor (if one is find):
new MyElement();
See http://www.html5rocks.com/en/tutorials/webcomponents/customelements/#instantiating

I believe you are looking for the constructor (see here) attribute.
You need to include it in your polymer element declaration.
<polymer-element name="p-paper"
attributes="content"
constructor="Paper"
noscript>
And then you can create instances of your element like this -
// How to create an instance of <p-paper> here?
var paper = new Paper();

Related

Parent node in react-testing-library

The component that I have testing renders something this:
<div>Text<span>span text</span></div>
As it turns out for testing the only reliable text that I have is the 'span text' but I want to get the 'Text' part of the <div>. Using Jest and react-testing-library I can
await screen.findByText(spanText)
This returns an HTMLElement but it seems limited as I don't have any of the context around the element. For example HTML methods like parentNode and previousSibling return null or undefined. Ideally I would like to get the text content of the parent <div>. Any idea how I can do this with either Jest or react-testing-library?
A good solution for this is the closest function.
In description of closest function is written: Returns the first (starting at element) including ancestor that matches selectors, and null otherwise.
The solution would look like this:
screen.getByText("span text").closest("div")
Admittedly, Testing Library doesn't communicate clearly how to do this. It includes an eslint rule no-direct-node-access that says "Avoid direct Node access. Prefer using the methods from Testing Library". This gives the impression that TL exposes a method for a situation like this, but at the moment it does not.
It could be you don't want to use .closest(), either because your project enforces that eslint rule, or because it is not always a reliable selector. I've found two alternative ways to tackle a situation like you describe.
within():
If your element is inside another element that is selectable by a Testing Library method (like a footer or an element with unique text), you can use within() like:
within(screen.getByRole('footer')).getByText('Text');
find() within the element with a custom function:
screen.getAllByText('Text').find(div => div.innerHTML.includes('span text'));
Doesn't look the prettiest, but you can pass any JS function you want so it's very flexible and controllable.
Ps. if you use my second option depending on your TypeScript config you may need to make an undefined check before asserting on the element with Testing Library's expect(...).toBeDefined().
But I have used HTML methods a lot and there was no problem yet. What was your problem with HTML methods?
You can try this code.
const spanElement = screen.getElementByText('span text');
const parentDiv = spanElement.parentElement as HTMLElement;
within(parentDiv).getElementByText('...');

How to check if a class mixin has been applied to a Polymer element?

I would like to check if a mixin has been applied to a custom element, but I don't think I can use 'instanceof', since a mixin is not properly a base class (I tried, of course).
I would need to enforce that an element added to a collection can be only of a kind with a particular class mixin applied...
Any suggestions?
Not sure I understand you question correctly.
I assume you want to check something like MyCustomElement has already apply MyMixin or not?
You can check from the instance
let instance = new MyCustomElement()
console.log(instance instanceof MyMixin)
This will only work when MyMixin is a class not a factory function. If you follow documentation you need to change it.
Another way, you can declare some static function in MyMixin. Then you can call from MyCustomElement to check it.

Is it possible to inject HTML into a polymer component via an attribute?

I'm using one of the core polymer components that basically has:
<polymer-element attributes="label">
<div>{{label}}</div>
as part of the source. I'd like to inject some HTML into this so that it ultimately renders as:
<div>Item <small>Description</small></div>
Is there any way to do this without copying the entire component (which is basically impossible considering the dependency chain)?
Polymer doesn't allow setting HTML inside {{}} expressions because it's a known XSS outlet. However, there are ways around it (1, 2).
I'm not sure there's a great way around this issue but I found something that works. You want to extend the element but also need to modify its shadow dom because of the .innerHTML limitation. Taking paper-button as an example, it has an internal {{label}}. You could extend the element, drill into its shadow dom, and set .innerHTML of the container where {{label}} is set. React to label changing (labelChanged) and call this.super():
<polymer-element name="x-el" extends="paper-button">
<template>
<shadow></shadow>
</template>
<script>
Polymer('x-el', {
labelChanged: function() {
// When label changes, find where it's set in paper-button
// and set the container's .innerHTML.
this.$.content.querySelector('span').innerHTML = this.label;
// call paper-button's labelChanged().
this.super();
}
});
</script>
</polymer-element>
Demo: http://jsbin.com/ripufoqu/1/edit
Problem is that it's brittle and requires you to know the internals of the element you're extending.

Binding to events on parent page from iframe [duplicate]

I have an iframe and in order to access parent element I implemented following code:
window.parent.document.getElementById('parentPrice').innerHTML
How to get the same result using jquery?
UPDATE: Or how to access iFrame parent page using jquery?
To find in the parent of the iFrame use:
$('#parentPrice', window.parent.document).html();
The second parameter for the $() wrapper is the context in which to search. This defaults to document.
how to access iFrame parent page using jquery
window.parent.document.
jQuery is a library on top of JavaScript, not a complete replacement for it. You don't have to replace every last JavaScript expression with something involving $.
If you need to find the jQuery instance in the parent document (e.g., to call an utility function provided by a plug-in) use one of these syntaxes:
window.parent.$
window.parent.jQuery
Example:
window.parent.$.modal.close();
jQuery gets attached to the window object and that's what window.parent is.
You can access elements of parent window from within an iframe by using window.parent like this:
// using jquery
window.parent.$("#element_id");
Which is the same as:
// pure javascript
window.parent.document.getElementById("element_id");
And if you have more than one nested iframes and you want to access the topmost iframe, then you can use window.top like this:
// using jquery
window.top.$("#element_id");
Which is the same as:
// pure javascript
window.top.document.getElementById("element_id");
in parent window put :
<script>
function ifDoneChildFrame(val)
{
$('#parentPrice').html(val);
}
</script>
and in iframe src file put :
<script>window.parent.ifDoneChildFrame('Your value here');</script>
yeah it works for me as well.
Note : we need to use window.parent.document
$("button", window.parent.document).click(function()
{
alert("Functionality defined by def");
});
It's working for me with little twist.
In my case I have to populate value from POPUP JS to PARENT WINDOW form.
So I have used $('#ee_id',window.opener.document).val(eeID);
Excellent!!!
Might be a little late to the game here, but I just discovered this fantastic jQuery plugin https://github.com/mkdynamic/jquery-popupwindow. It basically uses an onUnload callback event, so it basically listens out for the closing of the child window, and will perform any necessary stuff at that point. SO there's really no need to write any JS in the child window to pass back to the parent.
There are multiple ways to do these.
I) Get main parent directly.
for exa. i want to replace my child page to iframe then
var link = '<%=Page.ResolveUrl("~/Home/SubscribeReport")%>';
top.location.replace(link);
here top.location gets parent directly.
II) get parent one by one,
var element = $('.iframe:visible', window.parent.document);
here if you have more then one iframe, then specify active or visible one.
you also can do like these for getting further parents,
var masterParent = element.parent().parent().parent()
III) get parent by Identifier.
var myWindow = window.top.$("#Identifier")

How to change properties of elemnts\childs created with script on flash builder

Hi guys im creating/adding elemnts in my item renderer but from some reason you cant access their specific properties, you can only change the general properties. I created a LABEL component but when i do LabelName.font , nothing happens, its like flex doesnt recognize that this is a LABEL. Here is my code
var mylabel:Label = new Label()
mylabel.font
when i do "mylabel.someProperty" it only shows the general properties of any component, but how can i change other properties like font,color,size etc..
Thanks ahead [=
Fonts are defined as styles in Flex, not propeties, so you need to use the setStyle method to update it. (Not my favorite part about Flex.) For example:
myLabel.setStyle('fontFamily', newFont)
There is a difference between MXML and ActionScript in this. In MXML, styles of a component are shown as if they were properties, when they are really not. To set the fontFamily of your label in AS3 code, for example, you would use
myLabel.setStyle("fontFamily", "Arial")