Solusi Tutorial Owl Components - Todo List

Solusi untuk tutorial https://www.odoo.com/documentation/18.0/developer/tutorials/discover_js_framework/01_owl_components.html untuk bagian Todo List.


buat file static/src/todo_list/todo_list.js

import { Component, useState } from "@odoo/owl";
import { TodoItem } from "./todo_item";
import { useAutofocus } from "../utils";

export class TodoList extends Component {
    static template = "awesome_owl.TodoList";
    static components = { TodoItem };

    setup() {
        this.nextId = 0;
        this.todos = useState([]);
        useAutofocus("input")
    }

    addTodo(ev) {
        if (ev.keyCode === 13 && ev.target.value != "") {
            this.todos.push({
                id: this.nextId++,
                description: ev.target.value,
                isCompleted: false
            });
            ev.target.value = "";
        }
    }

    toggleTodo(todoId) {
        const todo = this.todos.find((todo) => todo.id === todoId);
        if (todo) {
            todo.isCompleted = !todo.isCompleted;
        }
    }

    removeTodo(todoId) {
        const todoIndex = this.todos.findIndex((todo) => todo.id === todoId);
        if (todoIndex >= 0) {
            this.todos.splice(todoIndex, 1);
        }
    }
}


buat file static/src/todo_list/todo_list.xml

<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
    <t t-name="awesome_owl.TodoList">
        <div class="d-inline-block border p-2 m-2">
            <input class="form-control mb-3" type="text" placeholder="Add a todo" t-on-keyup="addTodo" t-ref="input"/>
            <t t-foreach="todos" t-as="todo" t-key="todo.id">
                <TodoItem todo="todo" toggleState.bind="toggleTodo" removeTodo.bind="removeTodo"/>
            </t>
        </div>
    </t>
</templates>


buat file static/src/todo_list/todo_item.js

import { Component } from "@odoo/owl";

export class TodoItem extends Component {
    static template = "awesome_owl.TodoItem";
    static props = {
        todo: {
            type: Object,
            shape: { id: Number, description: String, isCompleted: Boolean }
        },
        toggleState: Function,
        removeTodo: Function,
    };

    onChange() {
        this.props.toggleState(this.props.todo.id);
    }

    onRemove() {
        this.props.removeTodo(this.props.todo.id);
    }
}


buat file static/src/todo_list/todo_item.xml

<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
    <t t-name="awesome_owl.TodoItem">
        <div class="form-check">
            <input class="form-check-input" type="checkbox" t-att-id="props.todo.id" t-att-checked="props.todo.isCompleted" t-on-change="onChange"/>
            <label t-att-for="props.todo.id" t-att-class="props.todo.isCompleted ? 'text-decoration-line-through text-muted' : '' ">
                <t t-esc="props.todo.id"/>.
                <t t-esc="props.todo.description"/>
            </label>
            <span role="button" class="fa fa-trash ms-3 text-danger" t-on-click="onRemove"/>
        </div>
    </t>
</templates>


buat file static/src/utils.js

import { useRef, onMounted } from "@odoo/owl";

export function useAutofocus(refName) {
    const ref = useRef(refName);
    onMounted(() => {
        ref.el.focus();
    });
}


Comments

Popular posts from this blog

Solusi Tutorial Owl Components - Counter

Odoo Development Setup menggunakan Windows dan Docker