Этот код представляет собой пример веб-приложения для создания, редактирования и удаления задач с использованием Heap и JSX для отображения HTML.
Наш код условно разбит на три состовляющие:
Начнем по порядку
import {jsx} from '@app/html-jsx'
Первая строчка позволяет подключить HTML в качестве разметки. По умолчанию в typescript-файлах включен AppUI, подходящий для создания мобильных экранов, но это приложение мы напишем на HTML
app.html("/", async (ctx) => {
let notes = await Notes.findAll(ctx, { order: { title: "asc" } });
return (
<html>
...
<body>
<h1>Список задач</h1>
<form id="addTaskForm" title="Создать задачу">
<div>
<input
id="taskTitle"
name="title"
placeholder="Опишите задачу"
required
/>
</div>
<div class="margin">
<button onclick={`createTask('${createRoute.url()}')`}>
Создать задачу
</button>
</div>
</form>
<div id="addTaskList">
{notes.map((note) => {
return (
<div
id="list"
class="list"
>
<div class='task-container'>
<input
class="task-checkbox"
type="checkbox"
checked={note.completed}
onchange={`checkTask('${toggleRoute({
id: note.id,
}).url()}')`}
/>
<span class="task-text">{note.title}</span>
</div>
<button
onclick={`deleteTask('${deleteRoute({ id: note.id }).url()}')`}
type="button"
class="delete"
>
Удалить
</button>
</div>
);
})}
</div>
</body>
</html>
);
});
Код, который находится в app.html
, регистрирует хендлер приложения, возвращающий контент страницы, когда к этому файлу обращается пользователь.
Этот фрагмент отвечает за отображение главной страницы приложения:
Для каждой задачи из списка отображаются:
import { Heap } from "@app/heap";
В import
мы так же подключаем библиотеку Heap, которая используется для создания, использования и хранения данных.
Подробнее об этом можно прочитать тут
const Notes = Heap.Table("note", {
title: Heap.String(),
completed: Heap.Boolean(),
});
Этим кодом мы объявляем таблицу Notes
для хранения задач, note.
У каждой задачи есть два поля:
В этой части мы прописываем маршруты, которые будут взаимодействовать с клиентской частью
// Маршрут для создания задачи
const createRoute = app.post("/create", async (ctx, req) => {
ctx.account.log("click", { json: req });
await Notes.create(ctx, {
title: req.body.title,
completed: false,
});
return;
});
// Маршрут для изменения статуса задачи
const toggleRoute = app.post("/toggle/:id", async (ctx, req) => {
ctx.account.log("done");
let note = await Notes.getById(ctx, req.params.id);
await Notes.update(ctx, { id: note.id, completed: !note.completed });
return;
});
// Маршрут для удаления задачи
const deleteRoute = app.post("/delete/:id/submit", async (ctx, req) => {
await Notes.delete(ctx, req.params.id);
return;
});
На клиентской стороне используется JavaScript для динамического создания задач, изменения их статуса и удаления.
createTask
, которая делает POST-запрос на создание новой задачи, с помощью createRoute
.checkTask
, которая обновляет статус задачи через маршрут toggleRoute
.deleteTask
, которая удаляет задачу через маршрут deleteRoute
.Так же нам нужно подключить JS-файл, чтобы удобнее было вызывать функции.
Для этого у нас есть файл script.js
const createTask = async(url)=> {
const title = document.getElementById('taskTitle').value
const response = await fetch(url, {
method: 'POST',
body: new URLSearchParams({
title: title,
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
location.reload();
};
const checkTask = async(url)=> {
const response = await fetch(url, {
method: 'POST',
body: {},
});
location.reload();
};
const deleteTask = async(url)=> {
const response = await fetch(url, {
method: 'POST',
body: {},
});
location.reload();
};
Чтобы открыть этот файл, надо ввести в браузере адрес: https://<домен.аккаунта>/chtm/plugin/