ChatiumFor developersPlaygroundPricing
Sign in

What this code does

This code is an example of a web application for creating, editing, and deleting tasks using Heap and JSX for rendering HTML.

Our code is conditionally divided into three components:

  • Client-side
  • Database
  • Server-side

Let's go through them in order.

Client-side

import {jsx} from '@app/html-jsx'

The first line allows us to use HTML as markup. By default, TypeScript files include AppUI, which is suitable for creating mobile screens, but we will write this application in HTML.

app.html("/", async (ctx) => {
  let notes = await Notes.findAll(ctx, { order: { title: "asc" } });
  return (
    <html>
      ...
      <body>
        <h1>Task List</h1>
        <form id="addTaskForm" title="Create Task">
          <div>
            <input
              id="taskTitle"
              name="title"
              placeholder="Describe the task"
              required
            />
          </div>
          <div class="margin">
            <button onclick={`createTask('${createRoute.url()}')`}>
              Create Task
            </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"
                >
                  Delete
                </button>
              </div>
            );
          })}
        </div>
      </body>
    </html>
  );
});

The code within app.html registers an application handler that returns the page content when a user accesses this file.

This fragment is responsible for displaying the main page of the application:

  • A request is made to the database to retrieve all tasks (Notes.findAll), sorted by title.
  • HTML markup is generated with a field for entering a new task and a button to create it.

For each task in the list, the following are displayed:

  • The task title.
  • A checkbox that shows the task status (completed or not).
  • A button to delete the task.

preview

Database

import { Heap } from "@app/heap";

In the import, we also include the Heap library, which is used for creating, using, and storing data.
You can read more about it here.

const Notes = Heap.Table("note", {
  title: Heap.String(),
  completed: Heap.Boolean(),
});

This code declares a Notes table for storing tasks, note. Each task has two fields:

  • title: Title
  • completed: Task status

table

Server-side

In this part, we define the routes that will interact with the client-side.

// Route for creating a task
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;
});

// Route for toggling the task status
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;
});

// Route for deleting a task
const deleteRoute = app.post("/delete/:id/submit", async (ctx, req) => {
  await Notes.delete(ctx, req.params.id);
  return;
});

On the client side, JavaScript is used to dynamically create tasks, change their status, and delete them.

  • When the "Create Task" button is clicked, the createTask function is called, which makes a POST request to create a new task using createRoute.
  • When the checkbox state changes, the checkTask function is called, which updates the task status via the toggleRoute.
  • When the "Delete" button is clicked, the deleteTask function is called, which deletes the task via the deleteRoute.

Script

We also need to include a JS file to make it easier to call functions.

For this, we have the script.js file.

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();
};

To open this file, you need to enter the following address in your browser: https://<account.domain>/chtm/plugin/

Next step: Let's register our plugin