Todo list using PyScript🌴!! - Trying out PyScript🔥

Todo list using PyScript🌴!! - Trying out PyScript🔥

Hi, Rinz Here

Today we are going to build a Todo list using Python without JavaScript!!

yes, It is possible using PyScript

What is PyScript❓

You may already know this!!! It is one of the Trending Tech on Twitter

It is a JavaScript Framework that will help your ditch JavaScript.

lol, That's right

"PyScript is a framework that allows users to create rich Python applications in the browser using HTML’s interface. PyScript aims to give users a first-class programming language that has consistent styling rules, is more expressive, and is easier to learn." - pyscript.net

need to know more. Check the blog by Adeboye Daniel

Will, it really Ditch JavaScript❓

Let's Check out✈️

Let's Try it 🧎‍♂️

Before we start Let's try it

Create an Html file
and You can access PyScript by connecting to PyScript CDN

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Todo App</title>
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
    <!-- ! Now, we can run python code in py-script tag !  -->
    <py-script> print('Hello, World!') </py-script>
</body>
</html>

That's it The PyScript, Hello World 😉!!

Todo List 😈

We have built the Hello, World project using PyScript

Now let's try , by we can build a Todo list only with PyScript

Let's Begin with HTML 🌐

let's do HTML first 👋

<body>
    <div>
      <!-- create Todo -->
      <div>
        <h1>Todo App</h1>
      </div>
      <div>
        <input type="text" id="new-todo" />
        <button id="add-todo" onclick="addTodo">Add Todo</button>
        <!-- This button triggers the add todo function -->
      </div>

      <!-- todo list  -->
      <div id="todo-list">
        <h2>Todo List</h2>
      </div>

      <template id="todo-template">
        <section class="todo">
          <label>
            <input type="checkbox" />
            <p></p>
          </label>
        </section>
      </template>
    </div>
</body>

It's just a simple template✔️

Let's go-to real the stuff 😉!!

Try it in JavaScript 😌

Let's try to build a todo app with JavaScript first ✏️

then We can change it to PyScript 🔛

      // Todos Array
      let todos = [];
      // Grabbing Elements
      let todoList = document.getElementById("todo-list");
      let todoInput = document.getElementById("new-todo");
      let addTodoBtn = document.getElementById("add-todo");

      function addTodo() {
        //   Create a new todo
        let todoID = `todo-${todos.length}`;
        let todo = {
          id: todoID,
          content: todoInput.value,
          done: false,
        };
        // adding it to the todos array
        todos.push(todo);

        let todoTemplate = document.getElementById("todo-template");
        // Creating todo element by cloning the template
        todoHTML = todoTemplate.content.cloneNode(true);
        todoHTML.id = todoID;

        todoHTML.querySelector("p").innerText = todo.content;
        let todoChecked = todoHTML.querySelector("input");

        todoList.appendChild(todoHTML);

        // check the todo
        todoChecked.addEventListener("change", function () {
          todo.done = !todo.done;
          if (todo.done) {
            todoHTML.classList.add("line-through");
          } else {
            todoHTML.classList.remove("line-through");
          }
        });

        //   clear the input
        todoInput.value = "";
      }

      addTodoBtn.addEventListener("click", () => {
        console.log(todoInput.value.length);
        if (todoInput.value.length > 0) addTodo();
      });

It's python time 😈

It's python time

Let's begin❕

Wait, It is hard to code python inside an HTML file I don't get Intellisense...

PyScript is providing a way to link python files with HTML. Like we do in JavaScript ... using the py-script tag itself

<py-script src="/todo.py"></py-script>

And Let's Start by

  • Grabbing the Template ✊‍

define the task template that will be used to render new templates to the page

# grab elements using Id
todo_template = Element("todo-template").select('.todo', from_content=True)
todo_list = Element("todo-list")
todo_input = Element("new-todo")
add_todo_btn = Element("add-todo")

JavaScript Alternative...

let todoTemplate = document.getElementById("todo-template");
let todoList = document.getElementById("todo-list");
let todoInput = document.getElementById("new-todo");
let addTodoBtn = document.getElementById("add-todo");
  • Todos Array 🎞️

An array to store todos

todos = []
  • Create a Todo ✔️
# create todo
todo_id = f"todo-{len(todos)}"
todo = {"id": todo_id, "content": todo_input.element.value, "done": False}
todos.append(todo)
  • Create a todo element by cloning the template And Appending it to the TodoList Element ✏️
# add the task element to the page as new node in the list by cloning from a template
todoHtml = todo_template.clone(todo_id, to=todo_list)
todoHtmlContent = todoHtml.select('p')
todoHtmlContent.element.innerText = todo['content']
todoHtmlCheck = todoHtml.select('input')
todo_list.element.appendChild(todoHtml.element)

JavaScript Version

let todoTemplate = document.getElementById("todo-template");
// Creating todo element by cloning the template
todoHTML = todoTemplate.content.cloneNode(true);
todoHTML.id = todoID;
todoHTML.querySelector("p").innerText = todo.content;
let todoChecked = todoHTML.querySelector("input");
todoList.appendChild(todoHTML);
  • Check the todo And Attaching it as Onclick 🖱️
def check_todo(evt=None):
  todo['done'] = not todo['done']
  if todo['done']:
    todoHtmlContent.element.style.textDecoration = "line-through"
  else:
    todoHtmlContent.element.style.textDecoration = "none"

JavaScript ...

todoChecked.onClick = () => {
  todo.done = !todo.done;
  if (todo.done) {
    todoHTML.classList.add("line-through");
  } else {
    todoHTML.classList.remove("line-through");
  }
};
  • Clear the Input ❕
todo_input.clear()

Add Todo Function 😉

We had created Todo, TodoHtml, and Function to check todo and more we have to trigger this function when submit button is clicked

So We have to make a function from these

def add_todo(*ags, **kws):
    # create todo
    todo_id = f"todo-{len(todos)}"
    todo = {"id": todo_id, "content": todo_input.element.value, "done": False}
    todos.append(todo)

    todoHtml = todo_template.clone(todo_id, to=todo_list)
    todoHtmlCheck = todoHtml.select('input')
    todoHtmlContent = todoHtml.select('p')
    todoHtmlContent.element.innerText = todo['content']
    todo_list.element.appendChild(todoHtml.element)

    def check_todo(evt=None):
        todo['done'] = not todo['done']
        if todo['done']:
            # add_class(taskHtmlContent, "line-through")
            todoHtmlContent.element.style.textDecoration = "line-through"
        else:
            # remove_class(taskHtmlContent, "line-through")
            todoHtmlContent.element.style.textDecoration = "none"

    todo_input.clear()
    todoHtmlCheck.element.onclick = check_todo

OnClick 🖱️

We have to run the add_todo function when we click the submit button

For that,

  • We can do as we did for the check box
add_todo_btn = Element("add-todo")
submit_btn.element.onclick = add_todo

or

  • We can use the alternative way directly in HTML
        <!-- Normal -->
        <button id="add-todo" onclick="addTodo">Add Todo</button>
        <!-- PyScript -->
        <button id="add-todo" pys-onClick="add_todo">Add Todo</button>

We have done all the functionalities

Let's add some styling...

I am doing this using Vanilla CSS check out the code on Repo

Will it replaces JavaScript ❕❓❓

We have figured out that

With PyScript we can do almost everything javascript does😉

So

Absolutely It will not replace Javascript for Now ❕❕

Now it is just an Experimental project.

That's All 💫

Thank you for reading !!

Check out the Repo for source code...

Bye 👋👋

Did you find this article valuable?

Support Rinshin Jalal by becoming a sponsor. Any amount is appreciated!