Assignment 2.1: Task Board (JavaScript)

Written by Michael, with huge help from Kashif Nazir

Due Tue May 2 11:59pm PT

Submissions not accepted after Thu May 4 11:59pm PT.

Backstory: Word of your awesome web dev skills is starting to make the rounds! As you work on your grand plans for taking over the world fixing Axess, you realize it's going to take a lot of work...and planning. Sure, you could use an off-the-shelf tool for this, but where's the fun in that? After all, with the countless web dev tutorials out there that use a to-do list as their example, maybe you should give it a try too.

In this assignment, you will write the (JavaScript) logic for a web app that tracks tasks and organizes projects. The organization system is based on a widely used system called >kanban and implemented in tools like GitHub project boards and Jira Software boards.

Learning goals

Through this assignment, you will

Overview

When you are finished, your app will look something like this:

Screenshot of complete app. See below for description
Sample of complete app. (Click to enlarge)

The "board" is divided into three "columns" (which are currently just headings), each containing a number of "cards." On the top is a set of controls for adding a new card. Cards have a title, a description, and a (background) color. They can be moved within and between columns and deleted, and their descriptions can be edited.

For this assignment, you won't do too much to lay out the board, columns, and cards. We will return to this in assignment 2.2, to make the app look more like a typical Kanban board. See part 4 for the specific requirements for styling in this assignment.

To get started, download the starter code, extract it, and run npm install and npm start as usual.

The assignment is divided into four parts: the first three are to implement the logic for the app, and the last is to add a handful of style rules. Each part is meant to be independently testable before moving onto the next.

Part 1: Adding cards

Review the contents of index.html, which contains the page structure for the task board. Do not modify the HTML file; your JavaScript must work with the HTML structure as given. You will implement the logic for the app in the various .js files. We have added the imports we anticipate you'll need.

The logic for this task will be split between the App and Card classes, which have the following public interfaces:

These classes don't have any public properties/instance variables. In particular, this means a card's title or color cannot be changed after it is created. You are free to add any private instance variables and methods.

Your task is to enable adding cards to the board, as follows:

  1. Add cards via the addCard method:
    • Cards should be created by duplicating the template card defined at the end of the HTML.
    • Set the card's title and background color as passed in. You can assume title will not be empty. You do not need to validate the passed-in color; any CSS color name or specification will work when set from JavaScript (and invalid colors/empty string will be ignored by the browser).
    • The card should show "(No description)" because the description starts out empty.
    • The card is added to the end (bottom) of the specified column.
  2. Set a card's description via setDescription:
    • Calling setDescription on a card changes its description to the passed in value.
    • As noted above, if a card's description is ever empty, the default text "(No description)" is shown in the card instead.
  3. Add cards via the form:
    • When the user clicks "Add" or presses Enter in either of the text boxes, create a new card with the specified title and color (and empty description).
    • If the user did not enter a title, an error message should be shown to the user. This should happen automatically because the title input is marked required (see note if it doesn't).
    • Add the newly-created card to the end of the "To Do" column.
    • After the card is added, clear the inputs in the add form.

Some notes and tips:


Part 2: Editing and deleting cards

Your next task (which will have you work exclusively in Card) is to implement the edit and delete buttons, as follows:

  1. Delete cards: Clicking on the delete button for a card removes it from the board.
  2. Edit card descriptions:
    • When the user clicks the edit button on a card, hide the current description and show the <textarea> to let them enter a new description.
    • The text box should be filled in with the current description (which may be empty). It should be focused, with all text selected at the start.
    • When the user clicks or tabs away from the text box, set the card's description to what the user entered, and return the card to its normal state (text box hidden, description shown).

Notes for this task:


Part 3: Moving cards

The final piece of functionality in this app is moving cards around on the board. Moving a card is a two-step process:

  1. When the user clicks on the move button of a card, the card is "selected for moving," and a number of "Move Here" buttons appear.
  2. When the user clicks on a "Move Here" button, the selected card is moved to the spot where the button is.

You'll implement a class (in mover.js) to abstract away this logic. (You'll also need to modify App and Card in this part to integrate this.) Mover's public interface is as follows:

Your task is as follows:

  1. Initialization:
    • Initialize a Mover instance in App. Pass this instance to Card when adding it (via the previously-unused mover parameter in addToCol). Card should store this for later use.
    • There should only be one Mover instance for the entire run time of the app--do not create a new one for each card.
  2. Starting a move:
    • When the user clicks a card's move button, give the card the (CSS) class "moving".
    • Add a button after the columnTitle and after each card in the board. (This means a column with N cards will have N + 1 move here buttons.
    • Each button should have the moveHere class, and its text is defined in the constant at the top of mover.js.
  3. Completing a move:
    • When the user clicks on a move here button, move the selected card from its current position to where the clicked button is.
    • The card stops being selected, and all move here buttons are removed.
    • The card may end up in the same place it started if the move here button directly above or below it is clicked. That is expected (and should work without a special case).
  4. Canceling a move:
    • In some cases, you will want to "cancel" any move that has been started but not completed. This means unselecting any card that has been selected for moving, and removing all of the move here buttons.
    • Cancel any incomplete move in the following cases: (1) a card is added, (2) a card is deleted, (3) before another move is started.

Some tips and notes:


Part 4: Styling cards (a bit

Your final task is to add a bit of CSS to the page. For the time being, we'll focus on a few very specific changes. In assignment 2.2, we will revisit this app, adding more CSS to tidy things up, adjust the spacing between elements, and handle the overall page layout.

styles.css (already linked in the HTML) starts with a few rules. Review them, then add rules to do the following:

  • Fonts for interactors: Change the font size of all <input>, <button>, and <textarea> elements so it is the same as normal text. Also change <textarea>s to use the same font family as the rest of the page (at least on some browsers/OSes, it defaults to a monospace font).
  • Card selected for moving: A card selected for moving should have a 2px solid black border.
  • Edit description text box: Make the text box for editing descriptions expand to the full width of the page, have a height of 5 times the font size, and have the same background color as the rest of the card.
  • Whitespace in descriptions: Change the whitespace handling for the description so that newlines and multiple/leading spaces will show up. The text should still wrap if it is too long to fit on one line.
  • Card buttons: The card buttons (edit, move, delete) should use the card's background color and have no border. When the user moves their mouse over the buttons, their cursor should change to a "pointer" hand, and the button's background should become translucent (use rgba(0, 0, 0, 0.25) as the color).
  • Move here buttons: Similar to the card buttons, these should also have no background/border and use the pointer hand cursor. They should also use a small font size. When not hovered, their text color should be gray. When hovered, they get a #e0e0e0 background and their text becomes its normal color (black).
  • Note that the background, border, and cursor don't apply to the "Add" button.

Here is an image of these styles:

Screenshot of styles (including move here buttons)
App with styles (and move here buttons)

Some notes and tips for this part:

Submitting

When you are finished, please submit your assign2 folder (without node_modules of course!) to Paperless.