Tutorial: Build a Todo App

Today we will be creating a very simple Todo application using the Pogo stack. This comprises of HTML, JavaScript, and PostgreSQL. We will be:

  • Making an application to create and finish todos
  • Storing todos in a Postgres database
  • Using HTML and vanilla javascript for the Frontend
  • Enabling CRUD functionality

While the application is simple in its own right, the concepts here can apply to much more advanced apps.

What We'll Be Building

Base Setup

Initial Setup

Make sure you've followed the steps in our set up guide including installing Postgres, Golang and downloading Pogo.

File Structure

We are going to keep the file structure very simple. Create a folder called pogo_todo. This will be the root of your project.

Inside pogo_todo you will need two folders. One called app and the other called pogocore (this should contain the pogo core files you downloaded in the setup instructions).

Your structure should look like this:

Pogo To do app starting directory structure

Database Setup

In the terminal navigate to your newly created app folder cd path/to/pogo_todo/app.

Next we'll set up a test user and create an empty database with some helper functions. Type psql in terminal and run the following:

(If you get the response "command not found", you'll need to add psql to your path.)

create role test;
alter role test createdb login;
create database db_todo owner test;
\password test
\c db_todo test
\i ../pogocore/seed/seed.sql

Now, we'll create a table to contain the todo items. All we need is an id for each item, its name, and whether or not it has been checked / completed.

create table todos
(
   id serial,
   name varchar,
   is_checked boolean
);

Let's add some sample data to loop through later. Run the below to add a few todo items.

insert into todos (name, is_checked) values
   ('Exercise', false),
   ('Drink green tea', true),
   ('Learn Pogo', false)
;

That's it, your database is ready to rock!

Server Setup

Inside your app folder create a file called: pogo_server_config.txt. This will contain the configuration for your app.

#
# Configuration settings for PoGoStack Server
#
# NOTE: parameters and values below MUST be split by just one space (no tabs, no multiple spaces)
#

### Mandatory parameters ###

config_connection_string user=test password=test dbname=db_todo sslmode=disable
config_default_page index
allow index

### Optional parameters ###

config_server_name PoGoToDo
#config_listen_address localhost:4200
#config_authentication_type basic

For the final part you'll want to set up your build script and save it in your app folder as compile-all.sh.

#!/bin/bash
PATH=$PATH:/Applications/Postgres.app/Contents/Versions/9.4/bin
go build ../pogocore/pogo_compiler.go
find . -type f -name "*.pogo" > all_pogos.txt 2>/dev/null
for i in `cat all_pogos.txt |sort` ; do ./pogo_compiler $i > $i.pgsql ; (psql -ddb_todo -Utest -q -f $i.pgsql ; rm $i.pgsql) & done
wait
rm pogo_compiler all_pogos.txt

Your directory structure should now have two new files in the app folder and look like this:

Pogo To do app directory structure with config files

Building the app!

For the sake of getting up and running quickly we'll be using Bootstrap to style our Todo app.

Create a file called index.html inside your app folder with the the following markup

<!doctype html>
<html>
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->

<title>Pogo Todo App</title>

<!-- STYLES -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"><!-- load bootstrap -->

</head>
<body>
   <div class="container-fluid">

      <!-- HEADER AND TODO COUNT -->
      <div class="jumbotron text-center">
         <h1>I'm a Todo-aholic <span class="label label-info">1</span></h1>
      </div>

      <!-- TODO LIST -->
      <div id="todo-list" class="row">
         <div class="col-sm-4 col-sm-offset-4">

            <!-- TODOS -->
            <div class="checkbox">
               <label for="to_do_item_1">
                  <input id="to_do_item_1" type="checkbox" name="to_do_item"> Checkboxes text
               </label>
            </div>

         </div>
      </div>

      <!-- FORM TO CREATE TODOS -->
      <div id="todo-form" class="row">
         <div class="col-sm-8 col-sm-offset-2 text-center">

         <form>
            <div class="form-group">
               <input type="text" class="form-control input-lg text-center"
                  placeholder="What do you have to do?">
            </div>

            <button type="submit" class="btn btn-primary btn-lg">Add</button>
         </form>
      </div>
   </div>

</div>

</body>
</html>

You can view this in the browser if you like, but as you'll see there isn't much to it right now. Let's get interactive!

Creating Pogo files

This is where things might seem to start pretty wild. Add the following code block as the first thing on your index.html page.

#
#
#

index

<?
   r record;
?><%

%>

Replace:

<div class="checkbox">
   <label for="to_do_item_1">
      <input id="to_do_item_1" type="checkbox" name="to_do_item"> Checkboxes text
   </label>
</div>

with:

<% for r in (select * from todos order by id) loop %>

<div class="checkbox">
   <label for="to_do_item_<%= r.id %>">
      <input id="to_do_item_<%= r.id %>"
         type="checkbox"
         <% if r.is_checked then %>checked="checked"<% end if; %>
         name="to_do_item"> <%= r.name %>
   </label>
</div>

<% end loop; %>

Change the file extension on your index page from .html to .pogo

If you use Sublime Text, switching to php syntax by hitting CMD + SHIFT + p and typing ss php will syntax highlight .pogo files

Your directory structure should now now look like this:

Pogo To do app final directory structure

Now we want to use the file you created above to compile your code. To do this, use the terminal to navigate to your app folder and run ./compile-all.sh. Easy!

For Mac users if you're getting an error when trying to compile you may first need to run: chmod +x compile-all.sh - you'll only need to do this the first time.

If you're using Sublime Text you can set up build scripts to automate compilation.

To get the server going run the following in a new terminal window: export GOPATH=~/gocode ; go run ../pogocore/pogo_server.go.

In your chosen browser navigate to localhost:4200. You should now see a list of todos rendered straight from the database!

Remember, each time you want to view a change you've made to your code, you'll need to recompile, but you won't have to restart your server.

Creating a new Todo

You can use any Javascript library / framework that you like, but here at Pogo we're a fan of keeping things as clean as possible so we'll be using vanilla Javascript for our interactions.

We opt to use our event triggers inline for a number of reasons.

  1. When reading the mark up, you'll know what the interaction is supposed to do
  2. The ability to pass server side code easily into our functions

Add the following lines to the header, this is Pogo parameters section:

#
#
#

index

p_action varchar (none)
p_name varchar (none)

<?
   r record;
?><%

%>

Then also add the following code, this is our CRUD section:

#
#
#

index

p_action varchar (none)
p_name varchar (none)

<?
   r record;
?><%

/* begin CRUD */
if p_action = 'add' and p_name != '(none)' then
   insert into todos (name, is_checked) values
   (
      p_name,
      false
   );
   return pogo_redirect('index');
end if;
/* end CRUD */
%>

Add the following bits to the form:

<form>
   <input type="hidden" name="p_action" value="add">
   <div class="form-group">
      <input type="text" class="form-control input-lg text-center"
         name="p_name"
         placeholder="What do you have to do?">
   </div>
   <button type="submit" class="btn btn-primary btn-lg">Add</button>
</form>

Save, compile by running ./compile-all.sh and refresh the page. Adding new todos should now work!

Ticking/unticking todos

Add two more parameters:

#
#
#

index

p_action varchar none
p_name varchar none
p_id integer 0
p_checked integer 0

Then also add the following code to the CRUD section:

if p_action = 'tick' and p_id > 0 then
   update todos
   set is_checked = (p_checked = 1)
   where id = p_id
   ;
   return pogo_redirect('index');
end if;

Add this line to the checkbox tag:

<input id="to_do_item_<%= r.id %>"
   type="checkbox"
   <% if r.is_checked then %>checked="checked"<% end if; %>
   onclick="f_tick(<%= r.id %>, this.checked);"
   name="to_do_item"> <%= r.name %>

And add this form underneath the for loop (after the closing "end loop" line):

<form name="form_tick">
   <input type="hidden" name="p_action" value="tick">
   <input type="hidden" name="p_id" value="0">
   <input type="hidden" name="p_checked" value="0">
</form>

The last step is to add this function into the head tag:

<script>
   function f_tick(p_id, p_checked)
   {
      form_tick.p_id.value = p_id;
      form_tick.p_checked.value = (p_checked) ? 1 : 0;
      form_tick.submit();
   }
</script>

Save, compile by running ./compile-all.sh, and refresh the page. Ticking and unticking todos should now work!

Showing number of outstanding todos:

Now that we can mark todos as completed, let's show how many are left to complete.

<!-- HEADER AND TODO COUNT -->
<div class="jumbotron text-center">
   <h1>I'm a Todo-aholic <span class="label label-info">
      <%= (select count(1) from todos where (not is_checked)) %>
   </span></h1>
</div>

As always, save, compile running ./compile-all.sh, refresh the page, and see the number change when you tick/untick todos.

You can download complete source code of our To-Do App here (yep, just one file, just 100 lines!)

Continue to part 2 to set up a team list. This will follow on to assigning todos to team members.