Skip to content

Commit 45f53bf

Browse files
[IMP] awesome_owl: create components: Counter, Card, TodoList (ch 1)
Create Owl Components: - Counter - Todo List - Card (with slots) Demo components on playground.
1 parent fe8cbbb commit 45f53bf

11 files changed

Lines changed: 203 additions & 2 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Card extends Component {
4+
static template = "awesome_owl.Card";
5+
static props = {
6+
title: String,
7+
slots: { type: Object, shape: { default: true } }
8+
};
9+
10+
setup() {
11+
this.state = useState({ isOpen: true });
12+
}
13+
14+
toggleOpen() {
15+
this.state.isOpen = !this.state.isOpen;
16+
}
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.Card">
5+
<div class="card d-inline-block m-2" style="width: 18rem;">
6+
<div class="card-body">
7+
<div class="d-flex justify-content-between">
8+
<h5 class="card-title" t-out="props.title"></h5>
9+
<span role="button" t-on-click="toggleOpen">Toggle</span>
10+
</div>
11+
<p class="card-text" t-if="state.isOpen">
12+
<t t-slot="default"/>
13+
</p>
14+
</div>
15+
</div>
16+
</t>
17+
18+
</templates>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Counter extends Component {
4+
static template = "awesome_owl.Counter";
5+
static props = {
6+
onChange: { type: Function, optional: true }
7+
}
8+
9+
setup() {
10+
this.state = useState({ value: 1 });
11+
}
12+
13+
increment() {
14+
this.state.value++;
15+
if (this.props.onChange) {
16+
this.props.onChange()
17+
}
18+
}
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.Counter">
5+
<div class="m-2 p-2 border d-inline-block">
6+
<span class="me-2">Counter: <t t-esc="state.value"/></span>
7+
<button class="btn btn-primary" t-on-click="increment">Increment</button>
8+
</div>
9+
</t>
10+
11+
</templates>
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
import { Component } from "@odoo/owl";
1+
import { Component, markup, useState } from "@odoo/owl";
2+
import { Card } from "./card/card";
3+
import { Counter } from "./counter/counter";
4+
import { TodoList } from "./todo_list/todo_list";
25

36
export class Playground extends Component {
47
static template = "awesome_owl.playground";
8+
static props = [];
9+
static components = { Card, Counter, TodoList };
10+
11+
setup() {
12+
this.sum = useState({ value: 2 });
13+
}
14+
15+
incrementSum() {
16+
this.sum.value++;
17+
}
518
}

awesome_owl/static/src/playground.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,21 @@
33

44
<t t-name="awesome_owl.playground">
55
<div class="p-3">
6-
hello world
6+
<Counter onChange.bind="incrementSum"/>
7+
<Counter onChange.bind="incrementSum"/>
8+
<p class="m-2">The sum is: <t t-esc="sum.value"/></p>
9+
</div>
10+
<div class="p-3 d-flex align-items-start">
11+
<Card title="'card 1'">
12+
hello world, <b>wow</b> what a great card
13+
<p> ... </p>
14+
</Card>
15+
<Card title="'card 2'">
16+
<Counter />
17+
</Card>
18+
</div>
19+
<div class="p-3">
20+
<TodoList />
721
</div>
822
</t>
923

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Component } from "@odoo/owl";
2+
3+
export class TodoItem extends Component {
4+
static template = "awesome_owl.TodoItem";
5+
static props = {
6+
todo: {
7+
type: Object,
8+
shape: {
9+
id: Number,
10+
description: String,
11+
isCompleted: Boolean,
12+
}
13+
},
14+
toggleState: Function,
15+
removeTodo: Function,
16+
};
17+
18+
onChangeCheckbox() {
19+
this.props.toggleState(this.props.todo.id);
20+
}
21+
22+
onDelete() {
23+
this.props.removeTodo(this.props.todo.id);
24+
}
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.TodoItem">
5+
<div class="m-1">
6+
<input class="me-2" type="checkbox"
7+
t-att-id="props.todo.id"
8+
t-att-checked="props.todo.isCompleted"
9+
t-on-change="onChangeCheckbox"/>
10+
<label t-att-for="props.todo.id"
11+
t-att-class="props.todo.isCompleted ? 'text-muted text-decoration-line-through' : ''">
12+
<t t-esc="props.todo.id"/>. <t t-esc="props.todo.description"/>
13+
</label>
14+
<span class="ms-1 fa fa-remove text-danger pointer" t-on-click="onDelete" role="button"/>
15+
</div>
16+
</t>
17+
18+
</templates>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Component, useState } from "@odoo/owl";
2+
import { TodoItem } from "./todo_item";
3+
import { useAutofocus } from "../utils";
4+
5+
export class TodoList extends Component {
6+
static template = "awesome_owl.TodoList";
7+
static props = [];
8+
static components = { TodoItem };
9+
10+
setup() {
11+
this.todos = useState([
12+
{ id: 1, description: "drink water", isCompleted: true },
13+
{ id: 2, description: "do tutorial", isCompleted: false },
14+
{ id: 3, description: "sleep", isCompleted: false },
15+
]);
16+
this.count = this.todos.length;
17+
useAutofocus("input");
18+
}
19+
20+
addTodo(event) {
21+
if (event.keyCode == 13 && event.target.value != "") {
22+
this.todos.push({
23+
id: ++this.count,
24+
description: event.target.value,
25+
isCompleted: false,
26+
});
27+
event.target.value = "";
28+
}
29+
}
30+
31+
toggleState(todoId) {
32+
const todo = this.todos.find((t) => t.id === todoId);
33+
if (todo) {
34+
todo.isCompleted = !todo.isCompleted;
35+
}
36+
}
37+
38+
removeTodo(todoId) {
39+
const index = this.todos.findIndex((t) => t.id === todoId);
40+
if (index != -1) {
41+
this.todos.splice(index, 1);
42+
}
43+
}
44+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.TodoList">
5+
<div class="d-inline-block border p-3 m-2">
6+
<h4> To-do List </h4>
7+
<input class="form-control mb-3" type="text" placeholder="Add a todo" t-on-keyup="addTodo" t-ref="input"/>
8+
<t t-foreach="todos" t-as="todo" t-key="todo.id">
9+
<TodoItem todo="todo" toggleState.bind="toggleState" removeTodo.bind="removeTodo"/>
10+
</t>
11+
</div>
12+
</t>
13+
14+
</templates>

0 commit comments

Comments
 (0)