Attributes in Web Components do not show up - html

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

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

How to remove style from <html>

I want to remove the style attribute from html: <html style="">
For example:
<html style="--athens-gray:#121212; --alabaster:#1E1E1E; --black:#ffffff; --white:#000000;">
Should be <html>.
This is my script:
const themes = {
dark: {
'--white': '#000000',
},
light: {
'--white': '#ffffff',
},
};
function lighttheme() {
const theme = themes["dark"];
for (var variable in theme) {
document.documentElement.style.setProperty(variable, theme[variable]);
};
}
:root {
--athens-gray: #e9e8ec;
--alabaster: #f8f8f8;
--black: #000000;
--white: #ffffff;
}
body {
background-color: var(--white);
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Settings</title>
</head>
<body>
<button type="button" onClick="lighttheme();">Click Me!</button>
</body>
</html>
You can do that by this code:
document.getElementsByTagName("html")[0].removeAttribute("style")
For example:
const themes = {
dark: {
'--athens-gray': '#121212',
'--alabaster': '#1E1E1E',
'--black': '#ffffff',
'--white': '#000000',
},
light: {
'--athens-gray': '#e9e8ec',
'--alabaster': '#f8f8f8',
'--black': '#000000',
'--white': '#ffffff',
},
};
function lighttheme() {
const theme = themes["dark"];
for (var variable in theme) {
document.documentElement.style.setProperty(variable, theme[variable]);
};
}
function removeStyle(){
document.getElementsByTagName("html")[0].removeAttribute("style");
}
:root {
--athens-gray: #e9e8ec;
--alabaster: #f8f8f8;
--black: #000000;
--white: #ffffff;
}
body {
background-color: var(--white);
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Settings</title>
</head>
<body>
<button type="button" onClick="lighttheme();">Click Me!</button>
<button type="button" onClick="removeStyle()">Remove Style!</button>
</body>
</html>
If I comment javascript code you will see the page's color gets red.

How to change the html body Theme using Kendo ui html5

I'm new to use Kendoui, HTML 5 for web , i have create one small Demo app in html 5,in this i need to change the Theme by dynamically , means when i select the color from Combo-box or Drop-down it should be apply for entire page. I searched in Google but i did not get right solution , please guide me how to do .
Here is the code what fallow sample .
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="Content/kendo/2013.2.716/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="Content/kendo/2013.2.716/kendo.default.min.css" rel="stylesheet" typ e="text/css" />
<script src="Scripts/kendo/2013.2.716/jquery.min.js" type="text/javascript"></script>
<script src="Scripts/kendo/2013.2.716/kendo.all.min.js" type="text/javascript"></script>
<style>
html, body
{
margin: 0;
padding: 0;
}
body
{
font: 12px/1.5 Tahoma,sans-serif;
padding: 2em;
}
span.themeChooser
{
float: right;
}
#tree
{
height: 9em;
}
</style>
</head>
<body class="k-content">
<div id="example" class="k-content">
<input class="themeChooser" value="default" />
<div id="tree">
</div>
<p>
Note: in order for the whole page to be styled, the <body> element has a <code>
k-content</code> class.</p>
</div>
<script>
$(function () {
$("#themeChooser").kendoDropDownList({
dataSource: [
{ text: "Black", value: "black" },
{ text: "Blue Opal", value: "blueopal" },
{ text: "Default", value: "default" },
{ text: "Metro", value: "metro" },
{ text: "Silver", value: "silver" }
],
change: function (e) {
var theme = (this.value() || "default").toLowerCase();
changeTheme(theme);
}
});
// sample widget on the page
$("#tree").kendoTreeView({
dataSource: [
{ text: "foo", expanded: true, items: [
{ text: "bar", selected: true }
]
},
{ text: "baz" }
]
});
// loads new stylesheet
function changeTheme(skinName, animate) {
var doc = document,
kendoLinks = $("link[href*='kendo.']", doc.getElementsByTagName("head")[0]),
commonLink = kendoLinks.filter("[href*='kendo.common']"),
skinLink = kendoLinks.filter(":not([href*='kendo.common'])"),
href = location.href,
skinRegex = /kendo\.\w+(\.min)?\.css/i,
extension = skinLink.attr("rel") === "stylesheet" ? ".css" : ".less",
url = commonLink.attr("href").replace(skinRegex, "kendo." + skinName + "$1" + extension),
exampleElement = $("#example");
function preloadStylesheet(file, callback) {
var element = $("<link rel='stylesheet' media='print' href='" + file + "'").appendTo("head");
setTimeout(function () {
callback();
element.remove();
}, 100);
}
function replaceTheme() {
var oldSkinName = $(doc).data("kendoSkin"),
newLink;
if ($.browser.msie) {
newLink = doc.createStyleSheet(url);
} else {
newLink = skinLink.eq(0).clone().attr("href", url);
}
newLink.insertBefore(skinLink[0]);
skinLink.remove();
$(doc.documentElement).removeClass("k-" + oldSkinName).addClass("k-" + skinName);
}
if (animate) {
preloadStylesheet(url, replaceTheme);
} else {
replaceTheme();
}
}
});
</script>
Thank you .

HTML Progress Bar

How would I add a progress bar to my website, that looks like the one on this website?
Progress Example
It looks like the Apple one!
<progress max="Maximum Value" value="Initial Value" />
See this for more details.
Note that this only works for browsers that support HTML5.
You can use jQuery instead. There in no restriction of HTML5. Also you can apply styles
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Progressbar - Custom Label</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
.progress-label {
float: left;
margin-left: 50%;
margin-top: 5px;
font-weight: bold;
text-shadow: 1px 1px 0 #fff;
}
</style>
<script>
$(function() {
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
progressbar.progressbar({
value: false,
change: function() {
progressLabel.text( progressbar.progressbar( "value" ) + "%" );
},
complete: function() {
progressLabel.text( "Complete!" );
}
});
function progress() {
var val = progressbar.progressbar( "value" ) || 0;
progressbar.progressbar( "value", val + 1 );
if ( val < 99 ) {
setTimeout( progress, 100 );
}
}
setTimeout( progress, 3000 );
});
</script>
</head>
<body>
<div id="progressbar"><div class="progress-label">Loading...</div></div>
</body>
</html>
Source code available here http://jqueryui.com/progressbar/

index.php is not receiving the JSON sent by the backbone Post

I've been trying to understand how Backbone works and communicates with the back-end code, and I have an issue of not being able to receive the JSON I send to my php file.
Here is the code:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css' />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Understanding Backbone</title>
<style type="text/css">
body { padding: 0; margin: 0; background-color: #fff; }
h2 { font-family: Abel, sans-serif; margin: 0; padding: 0 0 5px 0;}
input { background-color: #ddd; border: 0; }
input:active { background-color: #bbb; }
#new-status { margin: 20px; padding: 20px; background-color: #67A9C3; }
#statuses { margin: 20px; padding: 20px; background-color: #92B456; }
</style>
</head>
<body>
<div id="new-status">
<h2>New monolog</h2>
<form>
<textarea id="status" name="status"></textarea>
<br />
<input type="submit" value="Post" />
</form>
</div>
<div id="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
<script src="js/jquery-min.js"></script>
<script src="js/underscore.js"></script>
<script src="js/backbone.js"></script>
<script src="js/main.js"></script>
</body>
</html>
JS:
var Status = Backbone.Model.extend({
url: 'api/index.php'
});
var Statuses = Backbone.Collection.extend({
model: Status
});
var NewStatusView = Backbone.View.extend({
events: {
"submit form": "addStatus"
},
initialize: function(options) {
this.collection.on("add", this.clearInput, this);
},
addStatus: function(e) {
e.preventDefault();
this.collection.create({ text: this.$('textarea').val() });
},
clearInput: function() {
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(options) {
this.collection.on("add", this.appendStatus, this);
},
appendStatus: function(status) {
this.$('ul').append('<li>' + status.escape("text") + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView({ el: $('#new-status'), collection: statuses });
new StatusesView({ el: $('#statuses'), collection: statuses });
});
index.php:
<?php
echo(var_dump($_POST));
?>
This is what I get for the response:
array(0) {
}
I've been breaking my head over this, so please HELP!
After some more research on stackoverflow(awesome community btw) I was able to find that backbone does not send straight post or get to the RESTful api, or whatever the code-behind might be, but instead it is a set of headers. So you have to poke around the $_SERVER global and find out what is being requested. You'll be able to find your request in the $_SERVER["REQUEST_METHOD"], than perform a switch/case to decide what you want to do with that request. The data being sent through (in backbone's case is always a JSON string) is in the HTTP body and to get it out I used the file_get_contents('php://input'), and decode the JSON so that php can work with it.
<?php
$requestMethod = $_SERVER["REQUEST_METHOD"];
switch ($requestMethod)
{
case 'POST': $data = json_decode(file_get_contents('php://input'), true);
echo $data;
break;
}
?>
#orangewarp, I really wanted to understand what was happening under the hood without using a RESTful php framework.
$raw_data = file_get_contents("php://input");
var_dump($raw_data);
if( !empty($raw_data) ){
$data = #json_decode($raw_data, true);
if( $data ){
var_dump($data);
}
}