lit: no attributes values in constructor - 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

Related

Why width includes border when box-sizing is content-box?

I have this html file
<html lang="en" class=""><head>
<meta charset="UTF-8">
<title>CodePen Demo</title>
<meta name="robots" content="noindex">
<link rel="shortcut icon" type="image/x-icon" href="https://static.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico">
<link rel="mask-icon" type="" href="https://static.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111">
<link rel="canonical" href="https://codepen.io/hardkoded/pen/VwjvWBm">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<style class="INLINE_PEN_STYLESHEET_ID">
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol, ul {
padding-left: 30px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.status {
margin-bottom: 10px;
}
.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
}
</style>
<script src="https://static.codepen.io/assets/editor/iframe/iframeConsoleRunner-7f4d47902dc785f30dedcac9c996b9f31d4dfcc33567cc48f0431bc918c2bf05.js"></script>
<script src="https://static.codepen.io/assets/editor/iframe/iframeRefreshCSS-e03f509ba0a671350b4b363ff105b2eb009850f34a2b4deaadaa63ed5d970b37.js"></script>
<script src="https://static.codepen.io/assets/editor/iframe/iframeRuntimeErrors-29f059e28a3c6d3878960591ef98b1e303c1fe1935197dae7797c017a3ca1e82.js"></script>
</head>
<body class="mouse-navigation">
<div id="errors" style="
background: #c00;
color: #fff;
display: none;
margin: -20px -20px 20px;
padding: 20px;
white-space: pre-wrap;
"></div>
<div id="root"><div class="game"><div class="game-board"><div><div class="board-row"><button class="square"></button><button class="square"></button><button class="square"></button></div><div class="board-row"><button class="square"></button><button class="square"></button><button class="square"></button></div><div class="board-row"><button class="square"></button><button class="square"></button><button class="square"></button></div></div></div><div class="game-info"><div id="status">Next player: X</div><ol><li><button>Go to game start</button></li></ol></div></div></div>
<script>
window.addEventListener('mousedown', function(e) {
document.body.classList.add('mouse-navigation');
document.body.classList.remove('kbd-navigation');
});
window.addEventListener('keydown', function(e) {
if (e.keyCode === 9) {
document.body.classList.add('kbd-navigation');
document.body.classList.remove('mouse-navigation');
}
});
window.addEventListener('click', function(e) {
if (e.target.tagName === 'A' && e.target.getAttribute('href') === '#') {
e.preventDefault();
}
});
window.onerror = function(message, source, line, col, error) {
var text = error ? error.stack || error : message + ' (at ' + source + ':' + line + ':' + col + ')';
errors.textContent += text + '\n';
errors.style.display = '';
};
console.error = (function(old) {
return function error() {
errors.textContent += Array.prototype.slice.call(arguments).join(' ') + '\n';
errors.style.display = '';
old.apply(this, arguments);
}
})(console.error);
</script>
<script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-157cd5b220a5c80d4ff8e0e70ac069bffd87a61252088146915e8726e5d9f147.js"></script>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script id="INLINE_PEN_JS_ID">
function Square(props) {
return (
React.createElement("button", { className: "square", onClick: props.onClick },
props.value));
}
class Board extends React.Component {
renderSquare(i) {
return (
React.createElement(Square, {
value: this.props.squares[i],
onClick: () => this.props.onClick(i) }));
}
render() {
return (
React.createElement("div", null,
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}}
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
history: [
{
squares: Array(9).fill(null) }],
stepNumber: 0,
xIsNext: true };
}
handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
history: history.concat([
{
squares: squares }]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext });
}
jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: step % 2 === 0 });
}
render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
React.createElement("li", { key: move },
React.createElement("button", { onClick: () => this.jumpTo(move) }, desc)));
});
let status;
if (winner) {
status = "Winner: " + winner;
} else {
status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, {
squares: current.squares,
onClick: i => this.handleClick(i) })),
React.createElement("div", { className: "game-info" },
React.createElement("div", { id: "status" }, status),
React.createElement("ol", null, moves))));
}}
// ========================================
ReactDOM.render(React.createElement(Game, null), document.getElementById("root"));
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]];
for (let i = 0; i < lines.length; i++) {if (window.CP.shouldStopExecution(0)) break;
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}window.CP.exitedLoop(0);
return null;
}
//# sourceURL=pen.js
</script>
</body></html>
It's a tic tac toe game from this codepen link https://codepen.io/sophiebits/pen/qNOZOP (I've modified it a little bit).
When I used the inspect utility of Chrome to select one square, and looked at the computed css box model, it says the content of the square is 32px. But in the css portion of the html file, I clearly set the width of the square to be 34px, shouldn't the computed css box model have content width of 34px?
I know that the default value of box-sizing is content-box, so the width property should contain neither border nor padding. That's why I have this question.
Buttons (and some other items) use a box-sizing property "border-box" instead of "content-box"; this explains the different behavior.
Documentation for reference: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
You can change this in css using:
.square{
box-sizing: content-box; /* border-box */
}
See this very simple JSFiddle: https://jsfiddle.net/ue5f164h/
<div class="box"></div>
.box {
background: blue;
border: 5px solid red;
width: 20px;
height: 20px;
}
For me, the width is correct!
You should give a smaller reproducible example in your question so that it's easier for us to debug what's gone wrong.
But as the other answer points out, the problem is that some elements have a different default box-sizing value.
Basically the way box-sizing works is that, it determines if element width should include border or not.
For example -> If you have a div with width of 300px
By using box-sizing: border-box like so
div {
width: 300px;
height: 100px;
border: 10px solid blue;
box-sizing: border-box;
}
Then the width of this div element will always be 300px -> 20px of border and 280px of content -> by adding padding or changing border size you are changing the size of the content
If you use box-sizing: content-box like so:
div {
width: 300px;
height: 100px;
border: 10px solid red;
box-sizing: content-box;
}
The width of the div element will now be 320px -> 300px of content + 20px of border width.
So if you want your element to always have width or height of lets say 50px you would use box-sizing: border-box

Replace cell's editor of ag-grid with tinymce editor

How can we add tinymce editor in the place of editor present in the cell of ag-grid?
In order to customize ag-grid's cell's you need to create a custom Cell Renderer component.
You can pretty much put anything you want in that custom component, including tinyMCE.
More info: https://www.ag-grid.com/javascript-grid-cell-rendering-components/
Please see Cell Renderer
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script>var __basePath = './';</script>
<style media="only screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
</style>
<script src="https://unpkg.com/#ag-grid-community/all-modules#24.1.0/dist/ag-grid-community.min.js"></script>
</head>
<body>
<div id="myGrid" style="height: 100%;width: 100%" class="ag-theme-alpine"></div>
<script src="main.js"></script>
</body>
</html>
main.js
var columnDefs = [
{ field: 'athlete' },
{ field: 'country' },
{ field: 'year', width: 100 },
{ field: 'gold', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'silver', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'bronze', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'total', width: 100 }
];
var gridOptions = {
columnDefs: columnDefs,
components: {
'medalCellRenderer': MedalCellRenderer
},
defaultColDef: {
editable: true,
sortable: true,
flex: 1,
minWidth: 100,
filter: true,
resizable: true
}
};
// cell renderer class
function MedalCellRenderer() {
}
// init method gets the details of the cell to be renderer
MedalCellRenderer.prototype.init = function(params) {
this.eGui = document.createElement('span');
var text = '';
// one star for each medal
for (var i = 0; i < params.value; i++) {
text += '#';
}
this.eGui.innerHTML = text;
};
MedalCellRenderer.prototype.getGui = function() {
return this.eGui;
};
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
agGrid.simpleHttpRequest({ url: 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/grid-packages/ag-grid-docs/src/olympicWinnersSmall.json' })
.then(function(data) {
gridOptions.api.setRowData(data);
});
});

socket.io - show the users in the correct div

I'm pretty new to express and socket.io and I'm trying to achieve a little website:
What is it supposed to do:
You can connect to the website and enter a username
You have to select a column where you want to write (it's stored in var column)
Once on the page with the four column, you can see your username at the top of your column and start doing things there.
The other users see you in the correct column.
What it is not doing:
Actually the three points above are working quite well, my issue is with the last point :
The other users see you in the correct column.
My code is somehow not displaying every user in the correct column, in fact, it's displaying them in the same column as you are
Here is the code
$(document).ready(function () {
var socket = io();
var username = prompt("premier utilisateur : ", "nom");
var column = prompt("colonne ", "1,2,3 ou 4");
var gdhb = "";
socket.emit("new user entered his name");
socket.emit("nomUser", username);
if (column === "1") { column = ".one"; gdhb = ".dir1" }
if (column === "2") { column = ".two"; gdhb = ".dir2" }
if (column === "3") { column = ".three"; gdhb = ".dir3" }
if (column === "4") { column = ".four"; gdhb = ".dir4" }
socket.emit("user chose a column");
socket.emit("columnUser", column);
$(column).append($("<p class='username'>" + username + "</p>"))
$(document.body).click(function (b) {
var verbes = [
"appuie",
"bouscule",
"pousse"
];
var adverbes = [
"puis",
"ensuite",
"pour finir",
"alors"
];
var verbe = verbes[Math.floor(Math.random() * verbes.length)];
var adverbe = adverbes[Math.floor(Math.random() * adverbes.length)];
var verbadv = verbe + " " + adverbe;
console.log(verbadv);
socket.emit("verbadverbe");
socket.emit("verbadv", verbadv);
var div = $("<div />", {
"class": "document"
})
.css({
"left": b.pageX + 'px',
"top": b.pageY + 'px'
})
.append($("<p>" + verbadv + "</p>"))
.appendTo(column);
});
$(document.body).contextmenu(function (rc) {
var div = $("<div />", {
"class": "document"
})
.css({
"left": rc.pageX + 'px',
"top": rc.pageY + 'px'
})
.append($("<p>recule</p>"))
.appendTo(column);
});
var direction = "";
var oldx = 0;
var oldy = 0;
mousemovemethod = function (e) {
if (e.pageX > oldx && e.pageY == oldy) {
direction = "gauche";
}
else if (e.pageX == oldx && e.pageY > oldy) {
direction = "bas";
}
else if (e.pageX == oldx && e.pageY < oldy) {
direction = "haut";
}
else if (e.pageX < oldx && e.pageY == oldy) {
direction = "droite";
}
$(gdhb).append($("<p class='direction' id='direction'>" + direction + "</p>"))
$(".direction").prev().remove();
oldx = e.pageX;
oldy = e.pageY;
}
document.addEventListener('mousemove', mousemovemethod);
socket.on("columnUser", function (column) {
socket.on("nomUser", function (username) {
$(column).append($("<p class='username'>" + username + "</p>"));
socket.on("verbadv", function (verbadv) {
var div = $("<div />", {
"class": "document"
})
.append($("<p>" + verbadv + "</p>"))
.appendTo(column);
});
});
});
});
and the index.js :
const path = require('path');
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
console.log('Nouvel utilisateur')
socket.on("nomUser", (username) => {
console.log(username);
io.emit("nomUser", username);
});
socket.on("verbadv", (verbadv) => {
console.log(verbadv);
io.emit("verbadv", verbadv);
});
socket.on("columnUser", (column) => {
console.log(column);
io.emit("columnUser", column);
});
});
server.listen(3000, () => {
console.log('listen on 3000');
})
Also if it's needed to understand better, here is the css
body {
font-family: sans-serif;
font-size: 1.3rem;
margin: 0;
background-color: DarkSlateGray;
}
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 0px;
grid-auto-rows: minmax(100vh, auto);
height: 100vh;
}
.one,
.two,
.three,
.four {
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
position: relative;
overflow: scroll;
height: 100%;
background-color: tan;
}
.one {
grid-column: 1 / 2;
}
.two {
grid-column: 2 / 3;
}
.three {
grid-column: 3 / 4;
}
.four {
grid-column: 4 / 4;
}
.one::-webkit-scrollbar,
.two::-webkit-scrollbar,
.three::-webkit-scrollbar,
.four::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.note {
text-align: center;
width: 100px;
height: 30px;
}
.note p{
filter: drop-shadow(0 0 0.75rem black);
}
.document{
text-align: center;
}
.document p{
padding: 0;
margin: 0;
}
.username{
text-align: center;
padding: 0;
margin: 0;
}
.direction{
position: fixed;
bottom : 0;
width: 25vw;
text-align: center;
}
Thanks a lot for the precious help.
i've solved your problem with sockets. See at my solution.
client.js
function columnIndexIsValid(index, columnsQuantity) {
return index >= 0 && index <= columnsQuantity;
}
function fullNameIsValid(fullName) {
return typeof fullName === 'string' && fullName.length > 2;
}
function reloadPage() {
window.location.reload();
}
function rand(min, max) {
return Math.floor(min + Math.random() * (max - 1 - min));
}
function getRandomColour(colours = []) {
const colour = colours[rand(0, colours.length)];
return `#${colour}`;
}
function getUserHtml(user) {
return `<div class="column__users-list__item" data-item-id="${user.id}">${user.fullName}</div>`;
}
function getDrawnUsersNodes() {
return $('.column__item');
}
function canIRenderUsers(usersQuantity) {
const $renderedUsersQuantity = getDrawnUsersNodes().length;
return $renderedUsersQuantity < usersQuantity;
}
function renderUserHtmlToNode($node, html) {
$node.html($node.html() + html);
}
function getColumnUsersList(columnNode) {
const $column = $(columnNode);
return $column.find('.column__users-list');
}
function removeDrawnUserById(userId) {
$(`[data-item-id=${userId}]`).remove();
}
class DrawnUsers {
constructor() {
this.users = new Map();
}
getUserById(id) {
return this.users.get(id);
}
add(id, state) {
this.users.set(id, state);
}
removeById(id) {
this.users.delete(id);
}
exists(id) {
return this.users.has(id);
}
}
class Storage {
static setItem(key, value) {
localStorage.setItem(key, value);
}
static getItem(key) {
return localStorage.getItem(key) || null;
}
}
function generateUserId() {
return `user-${rand(rand(0, 10000), rand(20000, 50000))}`;
}
class UserState {
constructor() {
this.state = {};
}
get() {
return {
data: this.state,
};
}
set fullName(fullName) {
this.state.fullName = fullName;
}
get fullName() {
return this.state.fullName;
}
set id(id) {
this.state.id = id;
}
get id() {
return this.state.id;
}
set columnIndex(columnIndex) {
this.state.columnIndex = columnIndex - 1;
}
get columnIndex() {
return this.state.columnIndex;
}
}
$(document).ready(function () {
const drawnUsers = new DrawnUsers();
const colours = ['F2994A', 'F2C94C', '6FCF97', '2F80ED', '56CCF2', 'DFA2F5'];
const $columns = $('.column');
const $container = $('.container');
const userState = new UserState();
$columns.each(function () {
const $self = $(this);
$self.css({ 'background-color': getRandomColour(colours) });
});
userState.fullName = prompt('Type your fullName');
userState.columnIndex = +prompt('Type your column number');
if (
!fullNameIsValid(userState.fullName) ||
!columnIndexIsValid(userState.columnIndex, $columns.length)
) {
return reloadPage();
}
$container.addClass('active');
const socket = io('ws://localhost:3000');
socket.on('connect', () => {
const generatedUserId = generateUserId();
userState.id = Storage.getItem('userId') || generatedUserId;
Storage.setItem('userId', userState.id);
socket.emit('connected', userState.get());
socket.emit('addUser', userState.get());
socket.on('updateCurrentUsers', ({ data }) => {
const { users } = data;
if (!users || !canIRenderUsers(users.length)) {
return;
}
users.forEach((user) => {
const $column = $columns[user.columnIndex];
if ($column) {
if (!drawnUsers.exists(user.id)) {
drawnUsers.add(user.id);
renderUserHtmlToNode(
getColumnUsersList($column),
getUserHtml(user)
);
}
}
});
});
socket.on('newUser', ({ data }) => {
console.log('[debug] newUser: ', data);
const $column = $columns[data.columnIndex];
if (!$column) {
return;
}
if (drawnUsers.exists(data.id)) {
drawnUsers.removeById(data.id);
removeDrawnUserById(data.id);
} else {
drawnUsers.add(data.id);
renderUserHtmlToNode(getColumnUsersList($column), getUserHtml(data));
}
});
socket.on('disconnect', () => {
socket.open();
});
});
});
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
console.log('[debug] Client was connected successfully to server');
socket.on('connected', (user) => {
console.log('connected user data', user.data);
socket.data = user.data;
const users = Array.from(io.sockets.sockets.values()).map(
({ data }) => data
);
console.log('users', users);
socket.emit('updateCurrentUsers', {
data: {
users,
},
});
});
socket.on('addUser', ({ data }) => {
socket.data.columnIndex = data.columnIndex;
socket.broadcast.emit('newUser', {
data,
});
const users = Array.from(io.sockets.sockets.values()).map(
({ data }) => data
);
socket.broadcast.emit('updateCurrentUsers', {
data: {
users,
},
});
});
});
server.listen(3000, () => {
console.log('listen on 3000');
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./index.css">
<title>Users Columns</title>
</head>
<body>
<div class="container">
<div class="column">
<span class="column__index">#1</span>
<div class="column__users-list"></div>
</div>
<div class="column">
<span class="column__index">#2</span>
<div class="column__users-list"></div>
</div>
<div class="column">
<span class="column__index">#3</span>
<div class="column__users-list"></div>
</div>
<div class="column">
<span class="column__index">#4</span>
<div class="column__users-list"></div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.1/socket.io.js"
integrity="sha512-vGcPDqyonHb0c11UofnOKdSAt5zYRpKI4ow+v6hat4i96b7nHSn8PQyk0sT5L9RECyksp+SztCPP6bqeeGaRKg=="
crossorigin="anonymous"></script>
<script src="./client.js"></script>
</body>
</html>
index.css
html, body {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.container {
display: none;
}
.container.active {
display: flex;
flex-direction: row;
height: 100vh;
}
.container .column {
width: calc(100% / 4);
text-align: center;
padding: 20px 0;
}
.container .column .column__users-list {
display: flex;
flex-direction: column;
}
.container .column .column__index {
color: #FFF;
font-size: 36px;
letter-spacing: 8px;
}
hey) Let's look on that case more attentive, you have created a variable what contains a column index. right? This variable does store inside var variable. That is global variable for your script. I think you need to store each user column info inside each socket. If you don't know, each socket contains some info inside itself like id and other what can be used in your project if you'd like. But for this case you need to do so:
Ask new user what column he would like to choose.
Write to his socket data/info his column index.
When you do broadcast (It's when you send an object of data to each socket in room all each socket at all) just take this column index and draw this user in correct position. But make sure what your var column has a correct value. I can advice you to use const/let in javascript :)

Dynamically create column and row in 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

kendo treeview change datasource on the fly

I have a kendoTreeView connected to OData source as given in the demo on official site. I need to change the dataSource of the kendoTreeView to something else. Here is the html with the script.
When I click on the change button the tree changes but shows all the nodes as undefined. It is not able to show the new dataTextField values. When I revert it back it works even without setting the dataTextField.
I need to either change the dataSource of the tree or destroy the tree, remove it from DOM and then add a new one. Any help or pointers?
<body>
<input type="button" id="expandAllNodes" value="expandAllNodes" />
<input type="button" id="changedatasource" value="changedatasource" />
<input type="button" id="revert" value="revert" />
<span>First Tree</span>
<div id="treeview"></div>
<br/>
<span>Second Tree</span>
<div id="treeview2"></div>
<!--<div id="example" class="k-content">
<div id="treeview" class="demo-section"></div>-->
<script>
</script>
<style scoped>
#example {
text-align: center;
}
.demo-section {
display: inline-block;
vertical-align: top;
width: 320px;
height: 300px;
text-align: left;
margin: 0 2em;
}
</style>
<!--</div>-->
</body>
$(document).ready(function () {
// TreeView bound to Categories > Products > OrderDetails
var viewModel = {
self: this,
OrderDetails: {
type: "odata",
transport: {
read: {
url: function (options) {
return kendo.format("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products({0})/Order_Details", options.ProductID);
}
}
},
schema: {
model: {
hasChildren: function () {
return false;
}
}
}
},
Products: new kendo.data.HierarchicalDataSource({
type: "odata",
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
}
},
schema: {
model: {
id: "ProductID",
hasChildren: "Order_Details",
children: {
type: "odata",
transport: {
read: {
url: function (options) {
return kendo.format("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products({0})/Order_Details", options.ProductID);
}
}
},
schema: {
model: {
hasChildren: function () {
return false;
}
}
}
}
}
}
}),
Categories: new kendo.data.HierarchicalDataSource({
type: "odata",
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Categories"
}
},
schema: {
model: {
hasChildren: "Products",
id: "CategoryID",
children: {
type: "odata",
schema: {
model: {
id: "ProductID",
hasChildren: "Order_Details",
children: {
type: "odata",
transport: {
read: {
url: function (options) {
return kendo.format("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products({0})/Order_Details", options.ProductID);
}
}
},
schema: {
model: {
hasChildren: function () {
return false;
}
}
}
}
}
},
transport: {
read: {
url: function (options) {
return kendo.format("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Categories({0})/Products", options.CategoryID);
}
}
}
}
}
}
})
}
$("#treeview").kendoTreeView({
dataSource: viewModel.Categories,
dataTextField: ["CategoryName", "ProductName", "OrderID"],
checkboxes: {
checkChildren: true
}
});
$("#treeview2").kendoTreeView({
dataSource: viewModel.Products,
dataTextField: ["ProductName", "OrderID"],
checkboxes: {
checkChildren: true
}
});
ko.applyBindings(viewModel);
$("#expandAllNodes").click(function () {
var treeView = $("#kendoTreeView").data("kendoTreeView");
treeView.expand(".k-item");
});
$("#changedatasource").click(function () {
var treeview: kendo.ui.TreeView = $("#treeview").data("kendoTreeView");
//treeview.destroy();
treeview.setOptions({ dataTextField: ["ProductName", "OrderID"] });
treeview.setDataSource(viewModel.Products);
});
$("#revert").click(function () {
var treeview: kendo.ui.TreeView = $("#treeview").data("kendoTreeView");
//treeview.setOptions({ dataTextField: ["CategoryName", "ProductName", "OrderID"] });
treeview.setDataSource(viewModel.Categories);
});
});
Set the datasource to a new instance of a HierarchicalDataSource, see here: http://d585tldpucybw.cloudfront.net/forums/datasource-property-update-and-refresh. Direct link to Dojo by Alex Gyoshev: http://dojo.telerik.com/#gyoshev/iJIhI.