Log in
Sign up
Documentation
  • - Quick start guides
  • - How Jumpydoll works
  • - Tutorials
  • - Java/Spring Boot tutorial
  • - Step 1: Introduction
  • - Step 2: Setting up the project
  • - Step 3: Building the first API endpoint
  • - Step 4: Storing data in MongoDB Atlas
  • - Step 5: Adding more API endpoints
  • - Step 6: Creating a user interface
  • - Step 7: Conclusion

Step 6: Creating a user interface - Java/Spring Boot tutorial

  • Adding the frontend
  • Testing the UI
  • Pushing the changes
Adding the frontend

In order to make it easy to use your to-do list, you can make a website that makes the HTTP requests instead of using curl. In the future, we will update this guide with more details on how the frontend code works.

The HTML file is responsible for defining the layout of the website. It also imports the Javascript file. The Javascript file is responsible for running code and handling interaction. It waits for the user to press a button, and makes the corresponding HTTP call using the fetch method. After calling a write API endpoint, it reads all the data again so the list remains up-to-date.

src/main/resources/static/index.html

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">

        <script src="index.js"></script>
        <title>Jumpydoll Spring Boot app</title>
    </head>
    <body>
        <div class="container" style="max-width: 50em">
            <h1>Todo List</h1>
            <div class="spinner-border" role="status" id="loading">
                <span class="visually-hidden">Loading...</span>
            </div>
            <ul class="list-group mb-2" id="itemList"></ul>
            <form id="addItemForm">
                <div class="input-group flex-nowrap">
                    <input type="text" class="form-control" id="description"></input>
                    <button class="btn btn-primary" type="submit" id="addButton">Add</button>
                </div>
            </form>


        </div>
    </body>
</html>
src/main/resources/static/index.js

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('addItemForm').addEventListener('submit', (e) => {
    e.preventDefault()
    const description = document.getElementById('description').value;
    const postBody = {
      description,
      finished: false,
    }
    document.getElementById("addButton").disabled = true;
    fetch('api/tasks', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(postBody),
    }).then(res => res.json())
      .then(body => {
        document.getElementById('description').value = '';
        document.getElementById("addButton").disabled = false;
        refreshList();
      });
  })
  refreshList();
})

function refreshList() {
  document.getElementById('loading').style.display = 'block';
  document.getElementById('itemList').style.display = 'none';
  document.getElementById('addItemForm').style.display = 'none';
  fetch('api/tasks/')
    .then(res => res.json())
    .then(body => {
      const itemList = document.getElementById('itemList');
      while (itemList.firstChild) {
        itemList.removeChild(itemList.firstChild)
      }
      body.forEach((item) => createItem(itemList, item));
      document.getElementById('loading').style.display = 'none';
      document.getElementById('itemList').style.display = 'block';
      document.getElementById('addItemForm').style.display = 'block';
    })
}

function createItem(itemList, todoItem) {
  const element = document.createElement("li")

  const deleteButton = document.createElement("button");
  deleteButton.setAttribute('class', 'btn btn-light ms-auto');
  const deleteButtonIcon = document.createElement("i");
  deleteButtonIcon.setAttribute('class', 'bi bi-trash-fill');
  deleteButton.appendChild(deleteButtonIcon);
  deleteButton.addEventListener('click', createDeleteHandler(todoItem.id));

  const checkBox = document.createElement("input");
  checkBox.setAttribute('type', 'checkbox');
  checkBox.setAttribute('class', 'form-check-input me-1');
  checkBox.checked = todoItem.finished;
  checkBox.addEventListener('change', createCompletedHandler(todoItem));

  element.id = todoItem.id;

  const flex = document.createElement('div');
  flex.setAttribute('class', 'd-flex')
  flex.appendChild(checkBox);
  if (todoItem.finished) {
    const text = document.createTextNode(todoItem.description);
    const strike = document.createElement("s");
    strike.appendChild(text);
    flex.appendChild(strike);
  } else {
    const text = document.createTextNode(todoItem.description);
    flex.appendChild(text);
  }
  flex.appendChild(deleteButton);
  element.append(flex);

  if (todoItem.finished) {
    element.setAttribute('class', 'list-group-item list-group-item-secondary');
  } else {
    element.setAttribute('class', 'list-group-item');
  }

  itemList.appendChild(element);
}

function createCompletedHandler(todoItem) {
  return function (e) {
    fetch(`api/tasks/${todoItem.id}`, {
      method: 'PUT',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ ...todoItem, finished: !todoItem.finished }),
    }).then(res => {
      refreshList();
    });
  }
}

function createDeleteHandler(id) {
  return function (e) {
    fetch(`api/tasks/${id}`, {method: 'DELETE'})
      .then(res => {
        refreshList();
      });
  }
}
Testing the UI

Run the application again in your IDE. Now when you visit http://localhost:8080/jumpydoll-todo-list/ again in your browser, you will see the new frontend UI. You can add an item, mark it as complete, and delete an item. Now all of the API endpoints can be called through the web browser using buttons.

Pushing the changes

In your IDE, add the two new files to Git and create a commit with the message Add the frontend website. Push the changes to GitHub again. After the changes are done building, you should see your new website on Jumpydoll!

Step 5: Adding more API endpointsStep 7: Conclusion
Try Jumpydoll and host your own project

• Sign up with a GitHub account
• No setup required - start right in your browser
• Start your first project in 5 minutes
Get started for free

Jumpydoll

About

Project Gallery

Sign up

Contact

Email: [email protected]

© 2022