⏲️ Est. time to complete: 25 min. ⏲️
As a user, I want to have a cleaner interface for my tasks and move the details, edit and recommendation buttons over to a tabbed interace to reduce clutter
- A tabbed interface should be added to the main page with the following tabs: Details, Edit, Recommendations that get displayed when selecting an item from the primary list.
- The Details tab should display the task details
- The Edit tab should allow the user to edit the task
- The Recommendations tab should display the recommendations for the task
- The Details, Edit and Recommendations buttons should be removed from the main list
- The interface should look something like this:
no resources at this time
In order to complete this user story you will need to complete the following tasks:
Open Visual Studio Code (either locally in the project directory that you setup or through your Codespace). Visual Studio Code should have your completed solution from the end of Sprint 1 or if you prefer you can use the starting reference application from here by copying it over into your local directory or Codespace.
To get a tabbed-type interface working and functional in the web application, you will need to make the following changes:
- Add a tabbed user interface element to the main page
- Update the styles for the tabbed interface
- Update the application so that you can select a task by clicking on it in the list
- Remove the Details, Edit, and Recommendations buttons from the main list
First, we will add the tabbed user interface element to the index.html
file. To do this, add the following code right below the <div class="col-5">
and before the {% if g.todo != None and g.selectedTab == g.TabEnum.RECOMMENDATIONS %}
:
with the following code:
{% if g.selectedTab != g.TabEnum.NONE %}
<ul class="nav nav-tabs">
<li class="nav-item">
<a id="details-tab" class="nav-link" aria-current="page" href="{{ url_for('details', id=g.todo.id) }}">Details</a>
</li>
<li class="nav-item">
<a id="edit-tab" class="nav-link" href="{{ url_for('edit', id=g.todo.id) }}">Edit</a>
</li>
<li class="nav-item">
<a id="recommendations-tab" class="nav-link" href="{{ url_for('recommend', id=g.todo.id) }}">Recommendations</a>
</li>
</ul>
{% endif %}
This code will add a tabbed interface component on top of the right panel of the main page. The tabbed interface will have three tabs: Details, Edit, and Recommendations. The tabs will link to the appropriate routes in the application.
We will then need to update the styles for the application . Open the style.css
file and add the following code:
.card {
border-top: none !important;
}
.nav-link {
background-color: white;
}
.highlighted-item {
background-color: #f2f2f2;
}
This code will update the syles for the tabbed inferface and highlighted items in the application. The code does the following:
- The
card
class will have the top border removed from the previous Details, Edit and Recommendation panes so that it lines up directly below the tabbed interface and looks like one piece. - The
nav-link
class is part of the tabbed interface and will have a white background color. - The
highlighted-item
class will have a light gray background color and will be used in an upcoming step for highlighting tasks items.
If you run the application now you will see that the Details, Edit, and Recommendations have been added to the tabbed interface on the right panel of the main page. You can click on the tabs to view the different sections of the task details, edit, and recommendations.
Note however that the user interface is still not complete
- the Details, Edit, and Recommendations buttons are still visible on the main list
- you can't select a task by clicking on it in the main list,
- the selected task is not highlighted when the button's are pressed
- and the tabbed interface really doesn't show which tab is active.
We will address these in the next set of steps.
Before we remove the buttons, we need to update the application so that we can select a task by clicking on it in the list otherwise there wouldn't be a way to get to the Details, Edit, and Recommendations tabs. Open the index.html
file and replace the <li id="task-{{ todo.id }}" data-id="{{ todo.id }}" class="list-group-item d-flex justify-content-between">
with the following code:
<li id="task-{{ todo.id }}" data-id="{{ todo.id }}" class="list-group-item d-flex justify-content-between" onclick="showDetails(this)">
This code adds a showDetails function to the task item in the list. The showDetails function will be used to select a task by clicking on it and will be implemented in the next step.
We now need to implement the showDetails function as well as several other functions to help with highlighting the selected item and visually showing the right tab. Open the app.js
file and replace the handleClick
function
window.handleClick = function (event, cb) {
event.stopPropagation();
const rootUrl = window.location.origin;
const cbId = cb.id;
const cbChecked = cb.checked;
window.location.href = `${rootUrl}/completed/${cbId}/${cbChecked}`;
};
with the following code:
const HIGHLIGHTEDITEM = 'highlighted-item';
const currentPath = window.location.pathname;
// Set the active tab based on the URL
const setActiveTab = (tabId) => {
const tabElement = document.getElementById(tabId);
if (tabElement) {
tabElement.classList.add('active');
}
};
switch (true) {
case currentPath.includes('/edit'):
setActiveTab('edit-tab');
break;
case currentPath.includes('/completed'):
setActiveTab('completed-tab');
break;
case currentPath.includes('/details'):
setActiveTab('details-tab');
break;
case currentPath.includes('/recommend'):
setActiveTab('recommendations-tab');
break;
default:
break;
}
const highlightedItemId = localStorage.getItem(HIGHLIGHTEDITEM);
console.log('highlightedItemId', highlightedItemId);
if (highlightedItemId) {
const highlightedItem = document.getElementById(highlightedItemId);
if (highlightedItem) {
highlightedItem.classList.add(HIGHLIGHTEDITEM);
}
}
window.clearHighlight = function() {
localStorage.removeItem(HIGHLIGHTEDITEM);
};
window.showDetails = function(li) {
highlight(li);
const rootUrl = window.location.origin;
const dataId = li.getAttribute('data-id');
window.location.href = `${rootUrl}/details/${dataId}`;
};
window.handleClick = function(event, cb) {
event.stopPropagation();
const rootUrl = window.location.origin;
const cbId = cb.id;
const cbChecked = cb.checked;
window.location.href = `${rootUrl}/completed/${cbId}/${cbChecked}`;
clearHighlight();
};
window.highlight = function(element) {
const highlightedItemId = localStorage.getItem(HIGHLIGHTEDITEM);
if (highlightedItemId) {
const highlightedItem = document.getElementById(highlightedItemId);
if (highlightedItem) {
highlightedItem.classList.remove(HIGHLIGHTEDITEM);
}
}
const closestListItem = element.closest('li');
closestListItem.classList.add(HIGHLIGHTEDITEM);
localStorage.setItem(HIGHLIGHTEDITEM, closestListItem.id);
};
This code implements the following:
- adds a showDetails function that will be called when a task item is clicked. The function will highlight the selected task item and then redirect the user to the Details tab for the selected task.
- The highlight function will add a class to the selected task item to visually differentiate it from the other task items.
- The setActiveTab function will set the active tab based on the URL.
- The handleClick function will be called when the checkbox is clicked and will redirect the user to the completed tab for the selected task.
- The clearHighlight function will remove the highlighted class from the selected task item.
If you run the application now you will see that you can select a task by clicking on it in the list. The selected task will be highlighted and the Details tab will be displayed in the right panel. The details tab name will also show in black font to show that it is highlight. These changes are somewhat subtle but enhance the overall user experience and help the end user see where they are at in the application.
Note however, that the Details, Edit, and Recommendations buttons are still visible on the main list. We will remove these in the next step.
Next, we need to remove the Details, Edit, and Recommendations buttons from the main list. Open the index.html
file and remove the following code from the <li id="task-{{ todo.id }}" data-id="{{ todo.id }}" class="list-group-item d-flex justify-content-between" onclick="showDetails(this)">
:
<button type="submit" class="btn btn-success" formaction="{{ url_for('details', id=todo.id) }}" formmethod="GET">Details</button>
<button type="submit" class="btn btn-success" formaction="{{ url_for('edit', id=todo.id) }}" formmethod="GET">Edit</button>
<button type="submit" class="btn btn-success" formaction="{{ url_for('recommend', id=todo.id) }}" formmethod="GET">Recommendations</button>
This code will remove the Details, Edit, and Recommendations buttons from each task on the main list. The tabs on the right panel will now be the only way to access the Details, Edit, and Recommendations sections of the task.
Run the application again and you will see that the Details, Edit, and Recommendations buttons have been removed from the main list. This will help to reduce clutter and provide a cleaner interface for users to interact with.
If you add a new task you may notice that the highlighting is not removed from the previously selected task. This is because the highlighted class is not being removed when a new task is created. To fix this, we need to make an update <button ...>Add</button>
tag in the index.html
within the <form action="/add" method="post" class="my-4">
with the following code:
<button type="submit" class="btn btn-success" onclick="clearHighlight()">Add</button>
This code will add an onclick
event to the Add button that will call the clearHighlight
function when the button is clicked. The clearHighlight
function will remove the highlighted class from the selected task item.
If you run the application now you will see that the Details, Edit, and Recommendations buttons have been removed from the main list. You can select a task by clicking on it in the list and the selected task will be highlighted. The Details, Edit, and Recommendations tabs will be displayed in the right panel. You can click on the tabs to view the different sections of the task details, edit, and recommendations. If you add a new task, the highlighting will be removed from the previously selected task.
Note
To stop the server simply hit CTRL-C
in the terminal window where the web server is running.
🎉 Hooray! You have successfully added a tabbed interface to the main page of your application. This will help to reduce clutter and provide a cleaner interface for users to interact with.
Note
📄For the full source code for this exercise please see here.