Expense Tracker App Part-2

2023-05-21

So in this post I am going to build the basic HTML / CSS layout for the expense tracker. I have used these languages in the past, so I am not an expert. Consequently, this post is going to be in a write-as-I-implement format.

Directory structure

I am going to use the guidelines here to organize the app’s HTML/CSS resources. Additionally, I will store the backend hosting resources, like docker configs, in a separate folder on the same level as the HTML/CSS root folder. TL; DR, here’s the structure:

└── expense_tracker_app
    ├── app
    │   ├── css
    │   ├── img
    │   └── js
    └── docker

Implementing user inputs

So I see the need for the following inputs:

  1. Amount - numeric type - For entering transaction amount
  2. Date - date type (does this exist?) - For entering the date of transaction. Should default to current date
  3. Category - string type - For attaching a ‘bucket’ for the expense type
  4. Account - string type - For selecting the account from where the money is deducted
  5. Notes - string type - Any long-form type clarifications needed for the expense

In HTML we can setup a form as follows:

<form>
.... form elements
</form>

The form elements can have different types. The ones I intend to use are as follows:

<input type="text"> # For single line text input in notes
<input type="datetime-local"> # For transaction date in local timezone
<input type="number"> # For transaction amount
<input type="radio"> # For selecting one of many choices. Probably start with this for account and category selection
<input type="button"> # For submitting the info

Small detail, the form elements should be enclosed in <label> tags to show the field names like so:


<label> 
  Name:
  <input type="text" name="name"/>
</label>

<!-- OR -->

<label for="appt">Select a time:</label>
<input type="time" id="appt" name="appt"> <!-- Notice the name in id is same as label's for -->

Even after implementing all this, the formatting is weird, so need to use tables to format them in a more structured format. This is the reference code I used.

Reading data from input form

Now that the basic structure is set up, next step is to actually read the inputs so as to be able to later write it to a db or something. There are several languages which can be used to do this and I don’t really know which one’s ‘best’ - but I am going with JavaScript since it is a language I am vaguely familiar with.

The <form> tag has an action attribute which allows us to determine what happens when the form is submitted. This can either be a direct HTTPS request or can be attached to a JS callback.

I realize that I need a backend service which can receive the HTTPS requests from the front end, write to the database and then send a response back. I was initially thinking that I can write to the database directly from the client-side JS - but that’s not how things work. It actually makes sense - since we would want to validate the request contents before writing to the DB anyways.

So the plan is to use the client-side JS to maybe implement some basic validation, send the request to the backend service and then display the results. I can implement the backend in either python or JS. Not sure. Client-side JS is also useful for testing.

flowchart LR html["HTML"] --> client_js["Client side JS"]; client_js --> backend_service["Backend Service (JS / Python?)"]; backend_service --> database[("Transaction Database")];

Client side JS

Last step for today is to verify I can implement client-side JS by simply echoing the contents of the form. JS in a file can be loaded into an HTML page using the <script> tag. This is a good overview on how to access the form data in client-side JS.

After implementing the client side JS to read the form, this is what the end result looks like:

Current UI layout