Skip to content

Commit 89b5919

Browse files
committed
[IMP] awesome_owl: chapter 1 Owl components
1 parent 74759a4 commit 89b5919

11 files changed

Lines changed: 185 additions & 6 deletions

File tree

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

36
export class Playground extends Component {
4-
static template = "awesome_owl.playground";
7+
static template = "awesome_owl.Playground";
8+
static components = { Counter, Card, TodoList };
9+
static props = [];
10+
11+
setup() {
12+
this.str1 = "<div class='text-primary'>some content</div>";
13+
this.str2 = markup("<div class='text-primary'>some content</div>");
14+
this.sum = useState({value: 2})
15+
}
16+
17+
incrementSum() {
18+
this.sum.value++;
19+
}
520
}
Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1-
<?xml version="1.0" encoding="UTF-8" ?>
1+
<?xml version="1.0" encoding="UTF-8"?>
22
<templates xml:space="preserve">
3-
4-
<t t-name="awesome_owl.playground">
3+
<t t-name="awesome_owl.Playground">
54
<div class="p-3">
65
hello world
6+
<Counter onChange.bind="incrementSum" />
7+
<Counter onChange.bind="incrementSum" />
8+
<div>The sum is: <t t-esc="sum.value"/></div>
79
</div>
10+
<div>
11+
<Card title="'card 1'">
12+
content of card 1
13+
</Card>
14+
<Card title="'card 2'">
15+
<Counter />
16+
</Card>
17+
</div>
18+
<TodoList />
819
</t>
9-
1020
</templates>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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: { id: Number, description: String, isCompleted: Boolean },
9+
},
10+
toggleState: { type: Function },
11+
removeTodo: { type: Function },
12+
};
13+
14+
onChange() {
15+
this.props.toggleState(this.props.todo.id);
16+
}
17+
18+
onDelete() {
19+
this.props.removeTodo(this.props.todo.id);
20+
}
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.TodoItem">
4+
<div class="form-check">
5+
<input class="form-check-input" type="checkbox" t-att-id="props.todo.id" t-att-checked="props.todo.isCompleted" t-on-change="onChange"/>
6+
<label t-att-for="props.todo.id" t-att-class="props.todo.isCompleted ? 'text-decoration-line-through text-muted' : '' ">
7+
<t t-esc="props.todo.id"/>.
8+
<t t-esc="props.todo.description"/>
9+
</label>
10+
<span role="button" class="fa fa-trash ms-3 text-danger" t-on-click="onDelete"/>
11+
</div>
12+
</t>
13+
</templates>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Component, useState } from "@odoo/owl";
2+
import { TodoItem } from "./todo_item"
3+
import { useAutoFocusInput } from "../utils"
4+
5+
export class TodoList extends Component {
6+
static template = "awesome_owl.TodoList";
7+
static components = { TodoItem };
8+
static props = [];
9+
10+
11+
setup() {
12+
this.todo_id = 0;
13+
this.todos = useState([]);
14+
useAutoFocusInput("input");
15+
}
16+
17+
addTodo(ev) {
18+
if (ev.keyCode !== 13 || ev.target.value.length === 0) {
19+
return
20+
}
21+
this.todos.push({ id: this.todo_id++, description: ev.target.value, isCompleted: false });
22+
ev.target.value = "";
23+
}
24+
25+
toggleTodo(todoId) {
26+
const todo = this.todos.find(e => e.id === todoId);
27+
if (todo) {
28+
todo.isCompleted = !todo.isCompleted;
29+
}
30+
}
31+
removeTodo(todoId) {
32+
const todo_index = this.todos.findIndex((elem) => elem.id === todoId);
33+
if (todo_index >= 0) {
34+
this.todos.splice(todo_index, 1);
35+
}
36+
}
37+
}
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+
<t t-name="awesome_owl.TodoList">
4+
<div class="d-inline-block border p-2 m-2">
5+
<input class="form-control mb-3" type="text" placeholder="Enter a new task" t-on-keyup="addTodo" t-ref="input"/>
6+
<t t-foreach="todos" t-as="todo" t-key="todo.id">
7+
<TodoItem todo="todo" toggleState.bind="toggleTodo" removeTodo.bind="removeTodo"/>
8+
</t>
9+
</div>
10+
</t>
11+
</templates>

0 commit comments

Comments
 (0)