DEV Community

loading...
Cover image for Cardable: Basic Kanban Board made with Javascript and Rails

Cardable: Basic Kanban Board made with Javascript and Rails

merlumina
A software developer-in-training currently in the Part Time Software Engineering program at Flatiron School
・3 min read

Today I'm going to talk about Cardable, my Javascript project for Phase 4 of Flatiron School's Software Engineering Program. Cardable is a basic kanban board (similar to Trello) single-page application built using Javascript for the frontend and Rails API for the backend. The frontend is styled using a node-sass installation of Bulma CSS.

Backend

Models

Cardable has only two models, Columns and Cards, with a basic association whereby a Column has-many Cards. I wanted a very simple application where a user could create and move cards around columns, all handled by Javascript, so the models don't have any additional methods.

Controllers

My columns controller contains only the #index method:

  def index
    columns = Column.all
    render json: columns, include: [:cards]
  end
Enter fullscreen mode Exit fullscreen mode

I chose not to implement adding/removing/editing columns, so I only needed to be able to get all columns to display them. I chose to render JSON with associated Cards; this way, when initially loading the webpage, the application only needs to make a single GET request to /columns in order to build all the Column and Card instances.

My cards controller had basic implementations of #index, #create, #update, and #destroy methods.

Frontend

Classes

My Column and Card classes were structured similarly with the following characteristics:

  • Constructor methods that take in a JSON response from a GET fetch request and instantiate a Javascript Object
  • A static method for retrieving all instances of the class
  • Methods that essentially correspond to each method in the corresponding Rails controller. Both Column and Card have a method that build HTML structure for the model and render the instances to the page (using the GET response data from /columns). Additionally, Card has methods for POSTing, PATCHing, and DELETEing data, allowing the user to create new cards in a column, move cards to a different column, and delete cards.

I added a separate method to Column to create a form that would be added to each column and used to create new cards.

Running the Application

My index.js file is fairly simple, containing a fetch request to /columns that first instantiates Column and Card objects and then renders them to the page. It also has several methods for handling dragging-and-dropping (adapted from the MDN documentation). The important thing I needed to add to the drag-and-drop functionality was to trigger a PATCH request when a Card gets dropped so the Column it belongs to can get updated in the database when moving to a different column. This was handled accordingly:

//index.js

const cardToUpdate = Card.all().find(card => card.id == movingCard.getAttribute('id').slice(-1)); // find the Card instance with the id that matches the id of the element being dropped
cardToUpdate.moveColumn(el);

//card.js
moveColumn(el) { // el is the div the card is being dropped onto and is passed in from the drop method in index.js
  const columnId = el.id.slice(-1); // gets the id of the column the card is being moved to
  const cardId = this.id; // gets the id of the card
  const data = {
    id: cardId,
    column_id: columnId
  }
  fetch('http://localhost:3000/cards/' + this.id, {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json"
    },
    body: JSON.stringify(data) // sends the card id and column id to the API to get updated in the database
  })
  .then(response => response.json())
  .then(card => {
    if (card) { // if we get a response back, update the column_id of our Javascript Card instance
    this.column_id = columnId;
    }
  });
Enter fullscreen mode Exit fullscreen mode

Discussion (0)