Dynamically create column and row in HTML - html

I have data structure like this. and
<param1> could be repeating . We can have multiple value for param1
<param>
<param1>
<name>
<value>
</param1>
<param1>
<name1>
<value1>
</param1>
</param>
I want to display in html dynamically like this(like column row ). How can we do it ???
name name1
value value1
Can someone suggest how to do it . I am new to this area

The solution should be:
<!DOCTYPE html>
<html>
<style>
param-list {
font-size : 20px;
display:inline-block;
border:1px solid gray;
}
param-list > *{
font-size : 20px;
display:block;
}
</style>
<body>
<param-list>
<my-name></my-name>
<my-value></my-value>
</param-list>
<param-list>
<my-name1></my-name1>
<my-value1></my-value1>
</param-list>
<script>
class ParamList extends HTMLElement {
connectedCallback() {
this.children;
}
}
customElements.define('param-list', ParamList);
class Name extends HTMLElement {
connectedCallback() {
this.innerHTML = `name`;
}
}
customElements.define('my-name', Name);
class Name1 extends HTMLElement {
connectedCallback() {
this.innerHTML = `name1`;
}
}
customElements.define('my-name1', Name1);
class Value extends HTMLElement {
connectedCallback() {
this.innerHTML = `value`;
}
}
customElements.define('my-value', Value);
class Value1 extends HTMLElement {
connectedCallback() {
this.innerHTML = `value1`;
}
}
customElements.define('my-value1', Value1);
</script>
</body>
</html>
Live at custom-element
ref:
https://www.html5rocks.com/en/tutorials/webcomponents/customelements/
How to create custom tags for html
https://dev.to/jfbrennan/custom-html-tags-4788
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements

Related

lit: no attributes values in constructor

I'm building a count down in lit, and there is no HTML attributes (count, width, color, colorback, display) values unless adding timeout to constructor:
JS:
import {LitElement, html} from 'lit';
class ProgressBar extends LitElement
{
static get properties()
{
return {
count: {type: Number},
width: {type: Number},
color: {type: String},
colorback: {type: String},
display: {type: String}
}
}
render()
{
let output = '';
if(this.display==='true')
{
output = html`
<style>
:host > div
{
background-color: ${this.colorback};
width: 100%;
}
:host > div > div
{
background-color: ${this.color};
width: ${this.width}%;
height: 30px;
}
</style>
<div>
<div></div>
</div>
`;
}
return output;
}
draw()
{
let self = this
let x = self._date_end - (+new Date());
self.width = x * 100 / self.count
if(self.width>0)
{
window.setTimeout(function()
{
self.draw()
}, 1000 / 60)
}
else
self.width = 0
}
main()
{
let self = this
self._date_end = new Date((+new Date())+self.count);
self.draw()
}
constructor()
{
super()
let self = this
// working
window.setTimeout(function()
{
self.main()
}, 1000)
// not working
self.main()
}
}
window.customElements.define('progress-bar', ProgressBar)
HTML:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<progress-bar
display="true"
width="100"
color="#4cAf50"
colorback="#ddd"
count="5000">
</progress-bar>
<script src="main.js"></script>
</body>
</html>
How to deal with it? Thank you
Using connectedCallback method works fine:
connectedCallback()
{
super.connectedCallback()
this.main()
}
constructor()
{
super()
}
https://lit.dev/docs/components/lifecycle/#connectedcallback

Combining the ::slotted and ::part pseudo elements

I'm trying to use the ::slotted selector in combination with the ::part selector, I want an outer custom element to style a part in an inner custom element, the problem is that I can't get it to work.
So my question is, is my syntax wrong? Is this not possible to do?
Here is a basic example demonstration, I want the parent element to make the button in the child element have a red background
class ParentElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#parent-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("parent-element", ParentElement);
class ChildElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#child-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("child-element", ChildElement);
<template id="parent-template">
<style>
:host {
background-color: pink;
padding: 20px;
}
::slotted(child-element) {
background-color: blue;
padding: 10px;
}
::slotted(child-element)::part(button) {
background-color: red;
}
</style>
<slot></slot>
</template>
<template id="child-template">
<button part="button">Style me!</button>
</template>
<parent-element>
<child-element></child-element>
</parent-element>
You can't do this right now, but that feature is currently being reviewed for addition to the spec. See https://github.com/w3c/csswg-drafts/issues/3896 and https://github.com/w3c/csswg-drafts/issues/7922
You could define the style in the parent-element:
class ParentElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#parent-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("parent-element", ParentElement);
class ChildElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#child-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("child-element", ChildElement);
<template id="parent-template">
<style>
:host {
background-color: pink;
padding: 20px;
}
::slotted(child-element) {
background-color: blue;
padding: 10px;
}
</style>
<slot></slot>
</template>
<template id="child-template">
<button part="button">Style me!</button>
</template>
<parent-element>
<style>
child-element::part(button) {
background-color: red;
}
</style>
<child-element></child-element>
</parent-element>
or directly in the child-element:
class ParentElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#parent-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("parent-element", ParentElement);
class ChildElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
let template = document.querySelector("template#child-template");
this.shadowRoot.append(template.content.cloneNode(true));
}
}
customElements.define("child-element", ChildElement);
<template id="parent-template">
<style>
:host {
background-color: pink;
padding: 20px;
}
::slotted(child-element) {
background-color: blue;
padding: 10px;
}
</style>
<slot></slot>
</template>
<template id="child-template">
<style>
button {
background-color: red;
}
</style>
<button part="button">Style me!</button>
</template>
<parent-element>
<child-element></child-element>
</parent-element>

Attributes in Web Components do not show up

This is my HTML with a custom web component.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advanced ToDo App with Web Components</title>
</head>
<body>
<todo-item todo="Walk the dog" data-id="1"></todo-item>
<script src="../static/listItems.js"></script>
</body>
</html>
This is my JS file where I set up the component.
const template = document.createElement("template");
template.innerHTML = `<style>
h4 {
color: white;
font-size: 14px;
display: block;
padding: 10px 5px;
background: orange;
}
</style>
<div class="todo-item">
<h4></h4>
</div>
`;
class TodoItem extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector("h4").innerText = this.getAttribute("todo");
}
connectedCallback() {
this.shadowRoot
.querySelector(".todo-item")
.addEventListener("click", () => {
console.log(this.getAttribute("data-id"));
});
}
}
window.customElements.define("todo-item", TodoItem);
// Über Daten iterieren
const body = document.querySelector("body");
const dummydata = [
{ id: 1, description: "Walk the dog" },
{ id: 2, description: "Play football" }
];
for (item of dummydata) {
console.log(item.description);
todoItem = document.createElement("todo-item");
todoItem.setAttribute("todo", item.description); # Does not work!
todoItem.setAttribute("data-id", item.id);
body.appendChild(todoItem);
}
The component in the HTML works perfectly fine, but when I try to create them dynamically with JavaScript setting the attributes seem not to work. The "todo"-text does not get displayed. Is setting this "todo" attribute invalid?
Got it - the attribute has to be set inside the connectedCallBack function. When doing it before the attribute valu will be null
connectedCallback() {
this.shadowRoot
.querySelector(".todo-item")
.addEventListener("click", () => {
console.log(this.getAttribute("data-id"));
});
this.shadowRoot.querySelector("h4").innerText = this.getAttribute("todo");
}

How to change background color when a variable is negative?

I need to change the background color of a styled div to red when variable totalNetworkScore is negative.
You could try a ternary operator to set conditional classes.
:class="{{totalNetworkScore ? 'green' : 'red'}}"
in css:
.green {
background: green;
}
.red {
background: red;
}
you can use the #emotion/core library and do something like this:
import { css } from "#emotion/core";
import React from "react";
checkNegative = counter => {
if (counter) {
return css`
background: green;
`;
}
};
class Component extends React.Component {
state = { counter: -1 };
render() {
return <div css={checkNegative(this.state.counter)}>some text</div>;
}
}
export default Component;

Vaadin cache.js

I am trying to build a treeSelectView using checkboxes.
It implements HasValue so setValue hands over a list of nodes which should have checked checkboxes. and those checkboxes will be checked whenever the function is called. And here comes the downpart. When the treeSelectView reaches the client a script with the name https://localhost:8443/VAADIN/static/client/client-BF4676DDAFDA5E40AE93EFEB692AAAD5.cache.js is invoked which sets all the checkboxes in the tree to unchecked. This is the logoutput:
Sending xhr message to server: {"csrfToken":"8eb266a3-ec2b-4238-9d2e-00da55a02c27","rpc":[{"type":"mSync","node":313,"feature":1,"property":"selected","value":false},{"type":"mSync","node":307,"feature":1,"property":"selected","value":false},{"type":"mSync","node":301,"feature":1,"property":"selected","value":false},{"type":"mSync","node":295,"feature":1,"property":"selected","value":false},{"type":"mSync","node":289,"feature":1,"property":"selected","value":false},{"type":"mSync","node":283,"feature":1,"property":"selected","value":false},{"type":"mSync","node":277,"feature":1,"property":"selected","value":false},{"type":"mSync","node":271,"feature":1,"property":"selected","value":false},{"type":"mSync","node":265,"feature":1,"property":"selected","value":false},{"type":"mSync","node":259,"feature":1,"property":"selected","value":false},{"type":"mSync","node":253,"feature":1,"property":"selected","value":false},{"type":"mSync","node":247,"feature":1,"property":"selected","value":false},{"type":"mSync","node":241,"feature":1,"property":"selected","value":false},{"type":"mSync","node":235,"feature":1,"property":"selected","value":false},{"type":"mSync","node":229,"feature":1,"property":"selected","value":false},{"type":"mSync","node":223,"feature":1,"property":"selected","value":false},{"type":"mSync","node":217,"feature":1,"property":"selected","value":false},{"type":"mSync","node":211,"feature":1,"property":"selected","value":false},{"type":"mSync","node":205,"feature":1,"property":"selected","value":false},{"type":"mSync","node":199,"feature":1,"property":"selected","value":false},{"type":"mSync","node":193,"feature":1,"property":"selected","value":false},{"type":"mSync","node":187,"feature":1,"property":"selected","value":false},{"type":"mSync","node":181,"feature":1,"property":"selected","value":false},{"type":"mSync","node":175,"feature":1,"property":"selected","value":false},{"type":"mSync","node":169,"feature":1,"property":"selected","value":false},{"type":"mSync","node":163,"feature":1,"property":"selected","value":false},{"type":"mSync","node":157,"feature":1,"property":"selected","value":false},{"type":"mSync","node":151,"feature":1,"property":"selected","value":false},{"type":"mSync","node":145,"feature":1,"property":"selected","value":false},{"type":"mSync","node":139,"feature":1,"property":"selected","value":false},{"type":"mSync","node":133,"feature":1,"property":"selected","value":false},{"type":"mSync","node":127,"feature":1,"property":"selected","value":false},{"type":"mSync","node":121,"feature":1,"property":"selected","value":false},{"type":"mSync","node":115,"feature":1,"property":"selected","value":false},{"type":"mSync","node":109,"feature":1,"property":"selected","value":false},{"type":"mSync","node":103,"feature":1,"property":"selected","value":false},{"type":"mSync","node":97,"feature":1,"property":"selected","value":false},{"type":"mSync","node":91,"feature":1,"property":"selected","value":false},{"type":"mSync","node":85,"feature":1,"property":"selected","value":false},{"type":"mSync","node":79,"feature":1,"property":"selected","value":false},{"type":"mSync","node":73,"feature":1,"property":"selected","value":false},{"type":"mSync","node":67,"feature":1,"property":"selected","value":false},{"type":"mSync","node":61,"feature":1,"property":"selected","value":false},{"type":"mSync","node":55,"feature":1,"property":"selected","value":false},{"type":"mSync","node":49,"feature":1,"property":"selected","value":false},{"type":"mSync","node":43,"feature":1,"property":"selected","value":false},{"type":"mSync","node":37,"feature":1,"property":"selected","value":false},{"type":"mSync","node":31,"feature":1,"property":"selected","value":false},{"type":"mSync","node":25,"feature":1,"property":"selected","value":false},{"type":"mSync","node":19,"feature":1,"property":"selected","value":false}],"syncId":1,"clientId":1}
This is completely unexpected and unwanted behaviour.
Can anybody tell me why this is happening?
UPDATE
Here is my TreeSelectItem:
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../../bower_components/vaadin-checkbox/src/vaadin-checkbox.html">
<link rel="import" href="../../../bower_components/vaadin-button/src/vaadin-button.html">
<dom-module id="tree-select-item">
<template>
<style>
#currentItemContainer{
background-color: var(--lumo-contrast-10pct);
border-radius: var(--lumo-border-radius);
padding: 5px;
margin: 3px;
overflow: auto;
}
.hidden{
display: none;
}
</style>
<div id="currentItemContainer" style$="{{_getStyle(level)}}" class$="{{_isHidden(hidden)}}">
<div style="width: 90px; float: left">
<vaadin-checkbox id="checkbox" checked="{{selected}}" indeterminate="{{indeterminate}}" disabled="{{readOnly}}"></vaadin-checkbox>
<vaadin-button class$="{{_isToggleHidden(hasDescendents)}}" theme="icon" on-click="collapse" style="--lumo-button-size: var(--lumo-size-xs);">
<iron-icon icon="{{_getCollapseToggle(collapsed)}}" slot="prefix"></iron-icon>
</vaadin-button>
</div>
<div id="layout" float: left></div>
</div>
</template>
<script>
{
class TreeSelectItem extends Polymer.Element {
static get is() {
return 'tree-select-item';
}
/* collapse(){
this.collapsed = !this.collapsed;
var parentElement = this.parentNode.__dataHost;
parentElement.collapse(this.id,this.collapsed);
} */
_getCollapseToggle(collapsed){
return collapsed ? "lumo:angle-right" : "lumo:angle-down";
}
_isToggleHidden(hidden){
return !hidden ? "hidden" : "";
}
_isHidden(hidden){
return hidden ? "hidden" : "";
}
_getStyle(marginFactor){
return "margin-left:"+(20*marginFactor)+"px;";
}
}
window.customElements.define(TreeSelectItem.is, TreeSelectItem);
}
</script>
</dom-module>
Here is the java part
#Data
#Tag("tree-select-item")
#HtmlImport("base/template/component/tree-select-item.html")
public class TreeSelectItem<T extends BasicTreeObject<T>> extends PolymerTemplate<TreeSelectItemTemplateModel> {
/**
* The element containing this item
*/
private TreeSelect<T> treeSelect;
private T item;
#Id("layout")
private Div layout;
#Id("checkbox")
private Checkbox checkbox;
public TreeSelectItem(T item, TreeSelect<T> treeSelect) {
setCollapsed(false);
setSelected(false);
getModel().setLevel(item.getLevel());
getModel().setId(item.getId().intValue());
getModel().setHasDescendents(CollectionUtils.isNotEmpty(item.getChildren()));
getModel().setHidden(false);
getModel().setReadOnly(false);
this.treeSelect = treeSelect;
this.item = item;
render();
}
public void render() {
layout.removeAll();
Component label = treeSelect.getItemRenderer().createComponent(item);
layout.add(label);
}
#EventHandler
public void collapse() {
treeSelect.collapse(this);
}
public void setCollapsed(boolean collapsed) {
getModel().setCollapsed(collapsed);
}
public boolean isCollapsed() {
return getModel().isCollapsed();
}
public void setSelected(boolean selected) {
setIndeterminate(false);
getModel().setSelected(selected);
}
public boolean isSelected() {
return getModel().isSelected();
}
public void addSelectionListener(PropertyChangeListener listener) {
getElement().addPropertyChangeListener("selected", listener);
}
public void setHidden(boolean hidden) {
getModel().setHidden(hidden);
}
public void setIndeterminate(boolean indeterminate) {
getModel().setIndeterminate(indeterminate);
}
public void setReadOnly(boolean readOnly) {
getModel().setReadOnly(readOnly);
}
public String toString() {
return this.item.toString();
}
}
And here is the function that sets the values:
#Override
public void setValue(List<T> value) {
for (TreeSelectItem<T> tsi : this.treeSelectItems) {
tsi.setSelected(value.contains(tsi.getItem()));
}
updateParentNodesCheckbox();
}