Reputation: 61
I've cloned a repository which focuses on creating a To-Do application using ES6 and Polymer 3. I'm trying to implement a button which turns the background color containing a string green upon click. I've tried doing this, but I keep failing to get the desired result.
Example code:
static get properties() {
return {
list: {type: Array},
todo: {type: String},
};
}
constructor() {
super();
this.list = [
this.todoItem('buy cereal'),
this.todoItem('buy milk')
];
this.todo = '';
this.createNewToDoItem = this.createNewToDoItem.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handleInput = this.handleInput.bind(this);
}
todoItem(todo) {
return {todo}
}
createNewToDoItem() {
this.list = [
...this.list,
this.todoItem(this.todo)
];
this.todo = '';
}
//Right here is where I tried to implement the background color change.
checkItem() {
checkItem = document.getElementById('checkItem'),
checkItem.addEventListener('click', () => {
this.list = this.list.filter(this.todo)
document.body.style.backgroundColor = 'green';
});
}
deleteItem(indexToDelete) {
this.list = this.list.filter((toDo, index) => index !== indexToDelete);
}
render() {
return html`
${style}
<div class="ToDo">
<h1>Grocery List</h1>
<h1 class="ToDo-Header">What do I need to buy today?</h1>
<div class="ToDo-Container">
<div class="ToDo-Content">
${repeat(
this.list,
(item, key) => {
return html`
<to-do-item
item=${item.todo}
.deleteItem=${this.deleteItem.bind(this, key)}
></to-do-item>
`;
}
)}
</div>
I'd be eternally thankful if someone helped me out. I've created two JSFiddle links which show the code I've worked on thus far:
Link 1: https://jsfiddle.net/r2mxzp1c/ (Check line 42-49)
Link 2: https://jsfiddle.net/zt0x5u94/ (Check line 13 & 22-24)
Upvotes: 1
Views: 341
Reputation: 21
You should try to make the reactive templating work for you by defining presentation details in terms of your element's properties.
For example, this is a stripped-down approach to the same problem:
class TestElement extends LitElement{
static get properties() {
return {
'items': { 'type': Array }
};
}
constructor() {
super();
// set up a data structure I can use to selectively color items
this.items = [ 'a', 'b', 'c' ].map((name) =>
({ name, 'highlight': false }));
}
render() {
return html`<ol>${
this.items.map((item, idx) =>
html`<li
@click="${ () => this.toggle(idx) }"
style="background: ${ item.highlight ? '#0f0' : '#fff' }">
${ item.name }
</li>`)
}</ol>`;
}
toggle(idx) {
// rendering won't trigger unless you replace the whole array or object
// when using properties of those types. alternatively, mutate with the
// usual .push(), .splice(), etc methods and then call `this.requestUpdate()`
this.items = this.items.map((item, jdx) =>
jdx === idx ? { ...item, 'highlight': !item.highlight } : item
);
}
}
https://jsfiddle.net/rzhofu81/305/
I define the template such that the elements are colored the way I want depending on an aspect of their state (the "highlight" attribute of each entry in the list), and then I focus the interaction on updating the state to reflect what the user is doing.
Upvotes: 0
Reputation: 607
I'm not sure about the approach. But this link might help you https://stackblitz.com/edit/web-components-zero-to-hero-part-one?file=to-do-app.js
from this guy: https://stackblitz.com/@thepassle
Upvotes: 1