After I appendChild() in ie6, do stylesheets apply to that element? - dom

I am creating some elements in javascript like so:
var parent = document.createElement('div');
parent.setAttribute('id', 'parent');
var child = document.createElement('div');
child.setAttribute('class', 'child');
parent.appendChild(child);
otherelement.appendChild(parent);
I have a stylesheet which has styles for #parent and .child. However, it appears the styles are being applied to the parent but not the child. Does ie6 only support styles on id's and not classes or am I doing something wrong?

Stupid mistakes slipping my mind. Fixed it with the following code:
parent.id = 'parent';
child.className = 'child';

Related

How to use javascript libraries that require binding to DOM nodes

I have been trying to use Ag-Grid with Svelte. I understand that the main problem with using this grid library is that it needs to bind to a dom element that may not exist at the time of the code executing. For example:
// lookup the container we want the Grid to use
var eGridDiv = document.querySelector('#myGrid');
In this case, the #myGrid element does not exist yet.
I have tried creating an element and then placing it on the HTML part of the Svelte component, like this.
let eGridDiv = document.createElement("DIV");
let gridOptions = { columnDefs: columnDefs, rowData: $orders };
new Grid(eGridDiv, gridOptions);
And then down on the HTML section
<eGridDiv />
However, the new element does not seem to be initialized by Ag-Grid.
So what is the recommended way to use these types of libraries in Svelte?
If you want to use a DOM node in the script part of your component you can use the bind:this={domNode} element binding to get a reference to it, and then use it after the component has been rendered in onMount.
<script>
import { onMount } from 'svelte';
let domNode;
// ...
onMount(() => {
const gridOptions = { columnDefs: columnDefs, rowData: $orders };
new Grid(domNode, gridOptions);
});
</script>
<div bind:this={domNode} />

Rendering <style> inside Component with Renderer (Angular 7)

I have issue with rendering inside component. I would like to emit data from another component and send to another component, data was emitted, but the problem is when I create the element with Renderer2, sometimes it's working, but sometimes not. Probably it's a problem with rendering style element in a component?
toolbar.state.service.ts
My service method for emitting data
private globalStyles = new BehaviorSubject<string>('');
formDesign(data: any) {
this.globalStyles.next(data);
}
aside.component.ts
Here I emit data from Reactive Form control and send to another component.
// Height
this.formGlobal.controls['height'].valueChanges
.pipe(debounceTime(500))
.pipe(distinctUntilChanged())
.pipe(takeUntil(this.destroy$))
.subscribe(height => {
this.formGlobal.controls['height'].setValue(height);
this.formGlobal.updateValueAndValidity();
this.showDataCriteria = {
width: this.formGlobal.controls['width'].value + 'px',
height: height + 'px'
};
this.toolbarStatus.formDesign(this.showDataCriteria);
});
builder.component.ts
Here I'm getting data from aside.component.ts and it received!
/**
* Generate CSS
*/
generateCss() {
let basicStyles = ' ';
let newStyle: HTMLElement;
let style: HTMLElement = this.document.getElementById('custom-class');
style
? (newStyle = style)
: (newStyle = this.renderer.createElement('style'));
this.renderer.setAttribute(newStyle, 'id', 'custom-class');
let completeStyleFields = '';
this.customStyle.global
? (basicStyles += `#${this.projectInfo.id} {${this.customStyle.global}}`)
: (basicStyles += '');
console.log(basicStyles);
this.customStyle.sections.forEach(element => {
completeStyleFields += `#${element.id} {${element.textProps}}`;
});
basicStyles += completeStyleFields;
const text = (this.document.textContent = basicStyles);
newStyle.innerText = text;
this.renderer.appendChild(this.dndComponent.nativeElement, newStyle);
}
The Main problem is after style element was created, and I'm seeing the element in the DOM, styles not accepting! Sometimes accepting, and sometimes not. What should I do? How manipulate reload page probably to inject component and styles element?
Short UPD:
After all, I'm seeing #4152ae54-8a9d-49d5-a33d-62dfbbd35890 {height:600px; width:812px; }
But styles not accepted to the elements!
CSS can't render if the first numeric letter (#4152ae54-8a9d-49d5-a33d-62dfbbd35890). That’s because even though HTML5 is quite happy for an ID to start with a number, CSS is not. CSS simply doesn’t allow selectors to begin with a number. The relevant part of the specification states.

Leaflet-draw control's toolbar not displaying

I'm trying to use Leaflet-draw in VueJS, after calling it
import LeafletDraw from 'leaflet-draw'
But when I'm trying to use it
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
});
map.addControl(drawControl);
I only have a partial control's toolbar
Am I missing a CSS file to include ?
If someone is still looking for a solution so inside the vue component for example Map.vue you need to add this:
<script>
import "leaflet-draw/dist/leaflet.draw.css";
.
.
.
</script>
The issue was related to this one https://github.com/Leaflet/Leaflet.draw/issues/617
Importing the CSS file directly in my component and overriding the CSS property did the trick (with a valid path to the sprite; in Vue case, the static folder)
.leaflet-draw-toolbar a {
background-image: url('/static/spritesheet.png');
}

Search on descendants of an element

With protractor whats the best way to select child elements? Say we have the layout below...
<div id='parent_1'>
<div class='red'>Red</div>
<div class='blue'>Blue</div>
</div>
<div id='parent_2'>
<div class='red'>Red</div>
<div class='blue'>Blue</div>
</div>
With jQuery we'd do something like this.
var p1 = $('#parent_1');
var p1_red = $('.red', p1); //or p1.find('.red');
var p1_blue = $('.blue', p1); //or p1.find('.blue');
But with Protractor does it make sense to first get the parent element?
Since doing this var p1 = element('#parent_1'); doesn't actually retrieve/search for the object until getText() or something is called.
so doing this..
Scenario 1
expect(p1.element('.red')).toBe('red');
expect(p1.element('.blue')).toBe('blue');
OR
Scenario 2
expect(element('#parent_1').element('.red')).toBe('red');
expect(element('#parent_1').element('.blue')).toBe('blue');
OR
Scenario 3
expect(element('#parent_1 > .red')).toBe('red');
expect(element('#parent_1 > .blue')).toBe('blue');
Are there any benefits in one approach over the other?
This is what I'm doing but I don't know if there's any advantage of separating the parent from the cssSelector:
function getChild(cssSelector, parentElement){
return parentElement.$(cssSelector);
}
var parent = $('#parent_1');
var child_red = getChild('.red', parent);
var child_blue = getChild('.blue', parent);
Looking at Protractor's elementFinder I could be doing this:
function getChild(cssSelector, parentCss){
return $(parentCss).$(cssSelector);
}
var child_red = getChild('.red', '#parent_1');
var child_blue = getChild('.blue', '#parent_1');
The advantage of separating the child from the child css selector would only be if you'd like to use the parent for something else. Otherwise, it's slightly faster to do it in one call, like expect(element('#parent_1 > .red')).toBe('red'); since Protractor doesn't need to make two calls to the browser in this case.
Another reason to use the first approach would be if you were using a Locator strategy that cannot be expressed in CSS. For example:
var parent = element(by.css('.foo'));
var child = parent.element(by.binding('childBinding'));
expect(child.getText()).toEqual('whatever');

Working with openlayers and typescript classes

/// <reference path="openlayers.d.ts" />
class MapComponent {
element: HTMLElement;
map: OpenLayers.Map;
constructor(element: HTMLElement) {
// Setup our map object
this.element = element;
this.map = new OpenLayers.Map(this.element);
}
init() {
// Setup our two layer objects
var osm_layer_map = new OpenLayers.Layer.OSM("OSM");
// Add layers to the map
this.map.addLayers([osm_layer_map]);
// Add a layer switcher control
this.map.addControl(new OpenLayers.Control.LayerSwitcher({}));
// Zoom the map to the max extent
if (!this.map.getCenter()) {
this.map.zoomToMaxExtent();
}
}
}
window.onload = () => {
var el = document.getElementById('map');
var mc = new MapComponent(el);
mc.init();
}
I have the above piece of code to work with a simple HTML file with only 1 of ID, 'map' with style: height and width # 500px.
I have tried several other ways to get the map to display but so far all i got was a white page (blank).
Can anybody point me in the right direction?
Solutions tried so far:
using jquery with ready function
replace window.onload with a call direct from the html, <script><script/>
place document.getElementById() in the new OpenLayers.Map(here); when first creating this.map
placing the window.onload call above and below (currently)
using export class or public init() or both
As of now, I just want it to work.
Seems that creating the map with the element provided and later defining the options doesn't work.
Instead either initialize the map with options
var options = {
projection: "EPSG:3857",
maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
center: new OpenLayers.LonLat(-12356463.476333, 5621521.4854095)
};
this.map = new OpenLayers.Map(this.element, options);
Or call this.map.render(this.element) at the end of your init method.
Also make sure your div is actually visible and has some size specified, otherwise it might be not visible...