Unable to access elements inside Shadow Root in WCT - polymer

In my unit test, I am unable to access dom element from shadow root.
var el = fixture('basic');
var imgElement = el.shadowRoot.querySelector('img');
I am getting null in imgElement. How to get the img element?
I have tried also,
var imgElement2= document.querySelector('img');

If you are trying to access the dom element in the shadow root. Try ;
this.$.<element-id>
or
this.shadowRoot.querySelector(selector) / ie:('#element-id')

you have to use the setup function first
suite('test', function(){
setup(function () {
my-el = fixture('DefaultElement');
});

Related

How to hide shadowRoot element?

I'm trying to hide a div (answers-box) nested in a shadowRoot element, but can't seem to do so.
When I inspect the page with dev tools, this is the format:
I'm using the following at the end of my code to work with the shadowRoot element:
<script>
$(document).ready(function ()
{
var crowdElement = document.getElementById('myCrowd');
console.log(crowdElement);
var shRoot = crowdElement.shadowRoot;
console.log('Here is the var: ' + shRoot)
});
</script>
</body>
</html>
but it comes back as null in the console.
At the time you execute the ready callback the Custom Element <crown-form> is not defined yet.
Probably because the loading of the Custom Element definition is deferred or asynchronous.
You should wait for it by using whenDefined().
customElements.whenDefined( 'crowd-form' ).then( () => {
var crowdElement = document.getElementById('myCrowd');
console.log(crowdElement);
var shRoot = crowdElement.shadowRoot;
console.log('Here is the var: ' + shRoot)
} )
If crowdElement.shadowRoot is returning null then this Shadow DOM is closed. This means that its implementation internals are inaccessible and unchangeable from JavaScript. Here you can read more about closed shadow DOMs.

Two way binded data appears as string in Polymer

I am trying to render polymer template using below code,
const shadowRoot = this.attachShadow({mode: 'open'});
const htmlTemplate = importDoc.querySelector('template');
shadowRoot.innerHTML = htmlTemplate.innerHTML;
But this renders two way binded data also as a string instead of showing the binded value e.g
<h1 id ="contactFooter">{{localize('_testVal')}}</h1>
is displayed as it is do anyone have any idea? Two way binding is just example it renders everything like this.
To use a <template> tag you should use importNode on the content.
e.g.
var clone = document.importNode(htmlTemplate.content, true);
shadowRoot.appendChild(clone);
// note that you will need to clear the shadowRoot if you do rerenderings
// OR you could try
shadowRoot.innerHTML = htmlTemplate.content;
see more details here https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template

Unable to add custom elements using the document.execCommand

I am trying to add a custom element into a editable div using document.execCommand detailed at https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand.
But when I try to add a custom polymer element using the execCommand, browser is unable to recognize the custom element even if it was already imported into scope.
var video-id='FnoL3d33U8o'//a youtube video Id
var html = '<p><div><custom-video-element width="454" height="280" video-id="'+videoUrl+'"></custom-video-element></div></p>';
document.execCommand('insertHTML', false, html);
But this doesn't help and the custom-video-element is not recognized by the browser. Please help if there is any alternate ways or if I am running after a mirage!
if you know what element you need to append, then you can use document.createElement.
There are multiple options how to achiev that, but In your case:
var p = document.createElement("p");
var div = document.createElement("div");
var custom = document.createElement("custom-video-element")
custom.setAttribute("video-id", videoUrl);
.. setting another attributes ..
div.appendChild(custom);
p.appendChild(div);
document.appendChild(p);
and that is it. This should work well.
Of course there might be better and easier solutions but in your case this isn't so bad.
if you create bigger html structure inside your JS, you will do something like:
var div = document.createElement("div");
var inner = "<div class="test"><div></div><p class="p"></p></div>;
div.innerHTML = inner;
div.querySelector(".p").appendChild(document.createElement("custom-video-element"));

How to access content of leaflet popups

I am creating a leaflet-popup as set of html elements:
var popupBox = document.createElement('div');
$(popupBox)
.addClass('popup-box')
.attr("id", "mypopup");
var popupBoxContent = document.createElement('div');
$(popupBoxContent)
.addClass('some-class')
.html('foo')
.appendTo(popupBox);
myLeafletObject.bindPopup(popupBox);
Unfortunatly i am not able to access this elements later on. For example trying to do:
$('popup').append(someNewHTMLElement)
fails. Can somebody help?

Transverse Html Elements Till a Specifc Attribute (id) using Jquery

I am using Jquery 1.7.2.
I want to transverse Html Elements Till a Specifc Attribute (id) using Jquery on
mouse over on any html element in my page.
we have parents() function but problem is how to select stop on the parent element which has id attribute
$("*", document.body).click(function (e) {
e.stopPropagation();
var domEl = $(this).get(0);
var parentEls = $(domEl).parents()
.map(function () {
return this.tagName;
})
.get().join(", ");
$("b").append("" + parentEls + "");
});
this is code but i am getting all element till root
but i want to stop on a closet elements which has attribute id in the tag
Please help me out .
Just use closest:
$(this).closest('#the-id');
Unless your'e just looking for the closest one that has any id attribute, which would be:
$(this).closest('[id]');
Edit: after seeing your updated question, this should be what you want:
$(document).click(function(e) {
e.preventDefault();
var parents = $(e.target).parentsUntil('[id]')
.map(function() { return this.tagName; }).get().join(',');
console.log(parents);
});
Note that this approach accomplishes what you want without selecting and binding click events to every node in the DOM, which is a pretty heavy handed approach.
Edit (again): looks like maybe you wanted to include the tag with the id attribute on it (the above solution is everything up to, but not including that tag). To do this, the solution is pretty similar:
$(document).click(function(e) {
e.preventDefault();
var $parents = $(e.target).parentsUntil('[id]');
var tagNames = $parents.add($parents.parent())
.map(function() { return this.tagName; }).get().join(',');
console.log(tagNames);
});
It looks like you want to map the hierarchy from the clicked element up to the document root. In that case, you can apply parents() to event.target:
$(document).click(function(e) {
e.preventDefault();
var parentEls = $(e.target).parents().map(function() {
return this.tagName;
}).get().join(", ");
});
Note that, as jmar777, you should also change your selector: "*" adds an event handler to all the elements, which is probably not what you want. Bind a single handler to document instead to take advantage of event bubbling.