Unable to add custom elements using the document.execCommand - html

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"));

Related

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

TableRow cells Collection set attribute

I'm looping through a table in the form of table.rows.length and inside it rows.cells.length and when a certain cell meets a certain criteria then I would like to set an attribute to that html of that cell.
I know you can change the innerHTMl like
var x = document.getElementById("myTable").rows[0].cells;
x[0].innerHTML = "NEW CONTENT";
so I thought the attr would be like
x[0].attr = ('name', 'value');
But no such luck.
could someone please point me to the right direction?
If there are any resources you can recommend that give a full list of all the options you can add to a cell this way that would be great!
Since you're operating with HTML nodes directly - you're dealing with HTMLElement objects that are, in their turn, inherited from generic Element.
As you can see from documentation - you can reach attributes through Element.attributes map, each of them are Attr object with name and value properties.
So correct way will be to use:
x[0].setAttribute('name', 'value');
Working with jQuery and es6 syntax you could use the map function:
var xtr = $('#mytable tr');
xtr.map(itr => {
xtd = $(itr).children('td');
xtd.map(itd => {
$(itd).attr('key', 'value');
});
});
If thats confusing you can work with the for loop the old way:
var xtr = $('#mytable tr');
for(i in xtr){
xtd = $(xtr[i]).children('td');
for(j in xtd){
$(xtd[j]).attr('key', 'value');
}
}
Point being when using jQuery what you do is:
$('element').attr('key', 'value');

How to find attribute values of components in an HTML page other than inspecting it

I've been working on Sencha test and I am in a situation to find all the attribute values like IDs, NAMEs, etc to add those in my scripts, to represent the component. So what I am doing for that is,
go to web page -> right click component -> Inspect element -> and then get enough component attributes by referring to the HTML code.
Is there any way to find attribute values of components in an HTML page other than inspecting it ??? Please advice..
Try the App Inspector for Sencha chrome extension, which will help you to debug ExtJS and Sencha Touch applications much easier.
It also helps you to inspect your component tree, data stores, events, and layouts.
You can install it from the below URL,
App Inspector For Sencha
Hope this helps!
To get Attribute Values of component elements programmatically:
First, get the component. There are various ways, e.g.:
var component = Ext.getCmp(id) gets you the component with a certain id.
var component = Ext.ComponentQuery.query(xtype) gets you an array of all components of a certain xtype
Second, on that component, call getEl() or any other element selector, e.g.:
var el = component.getEl()
var el = grid.getView().getEl()
var el = formfield.inputEl
Third, on the el, call getAttributes:
var attributes = el.getAttributes()
attributes will now contain an object like this:
class:"x-grid-view x-grid-with-col-lines x-grid-with-row-lines x-fit-item x-grid-view-default x-unselectable"
data-componentid:"tableview-1325"
id:"tableview-1325"
role:"rowgroup"
style:"margin: 0px; overflow: auto; width: 317px; height: 664px;"
tabindex:"0"
you can press ctrl+u that will show you the page source. use ctrl+f to find the element which u want. This is easier than inspect element.
Go to the browser console and execute the below script to collect the list of attributes of each element.
var parentEl = document.getElementById("container");
getElementsAndAttributes(parentEl);
function getElementsAndAttributes(container) {
var all = container.getElementsByTagName("*");
for (var i = 0, max = all.length; i < max; i++) {
console.log(all[i].tagName);
var attrs = all[i].attributes;
var keys = Object.keys(attrs);
for (var j = 0; j < keys.length; j++) {
var attr = attrs[keys[j]];
console.log(attr.name + " -> " + attr.value);
}
}
}
<body>
<div id="container">
<span class="title" style="color:GREEN;">Phineas</span>
<img src="https://cdn.pastemagazine.com/www/blogs/lists/2010/05/12/phineas.jpg" width="104" height="142">
</div>
</body>

Cesium: Theming the InfoBox

I have seen a few examples on Google Groups which demonstrate how to modify the css of the infobox. In this particular example, javascript is used to append a css link to the head of the document:
https://groups.google.com/forum/#!topic/cesium-dev/f0iODd42PeI
var cssLink = frameDocument.createElement("link");
cssLink.href = buildModuleUrl('Path/To/Your/CSS/File.css');
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
viewer.infoBox.frame.contentDocument.head.appendChild(cssLink);
This, however, has not resulted in any changes to the style of my markup.
At best, I have been able to wrap the contents of the infobox by iterating through the entities in the .then function call subsequent to loading a geoJson dataset. When wrapping the contents, I can set style values which are readily apparent in the resulting markup.
var dataSource = Cesium.GeoJsonDataSource.load('../data/mGeoJson.json').then(function(data) {
viewer.dataSources.add(data);
var entities = data.entities.values;
for (var i = 0; i < entities.length; i++)
var entity = entities[i];
if (entity.properties.hasOwnProperty("description")) {
entity.description = '<div style="height: 360px;">' + entity.properties.description
+ '</div>';
}
}
}
This is useful, but does not completely satisfy the requirements of my app.
Could someone provide additional insight into overriding the theme of the infobox, without having to iterate over entities to modify the value of their description properties?
The original solution here wasn't working, because the infoBox is an iframe that has not yet asynchronously loaded when you were trying to modify it.
Instead, you can add an load listener to the iframe, like this:
var viewer = new Cesium.Viewer('cesiumContainer');
var frame = viewer.infoBox.frame;
frame.addEventListener('load', function () {
var cssLink = frame.contentDocument.createElement('link');
cssLink.href = Cesium.buildModuleUrl('Path/To/Your/CSS/File.css');
cssLink.rel = 'stylesheet';
cssLink.type = 'text/css';
frame.contentDocument.head.appendChild(cssLink);
}, false);
This waits for the iframe to become ready to receive the modification, and then applies it.
For what it's worth, I've found success in modifying the theme of the infobox by simply importing my css files in the head of the document. I'm not sure why I wasn't able to modify it directly with stylesheets, as it wasn't previously affecting the infobox's appearance, and this issue was mirrored in the posts that I found in the cesium-dev Google Group. Regardless, it seems to be working just fine now.

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?