Telerik blogs
KendoUI

In this step-by-step guide, learn how you can create a Trello-like project management app quickly and easily using Kendo UI.

This is the first post in a two-part series where you will learn how to build the frontend for a Trello-like app. Our app will have a board with lists and the lists will contain cards. The cards can be dragged and dropped within their list or between lists. And users can create new cards as well as edit the content of existing cards. This kind of app can be customized for many different uses cases like a project management tool for software developers or an issue tracker. Our app will be a todo list built using the Kendo UI ListView and Sortable components. Your first task will be to create a board initialized with three lists and a few cards.

Creating the Lists

Our board is essentially a list view within another list view. The first list view we will create are the containers for the cards. We will create an element with the id board in the body of our HTML to inject our lists. Inside the component’s parameters, we will specify the data source and the template to initialize the widget. Our dataSource will be an array of objects that have a listID and name attribute. This example creates three lists:

Trello

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Kanban Board</title>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.bootstrap-v4.min.css">
    <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>
  </head>
<body>
  <div class="board"></div>
  <script>
     $('.board').kendoListView({
    	template: kendo.template($('#listTemplate').html()),
    	dataSource: [
        {listID: 0, name: 'To Do'},
        {listID: 1, name: 'Doing'},
        {listID: 2, name: 'Done'}
      ]
    });
  </script>
</body>
</html>

The list template will have a header that displays the value of the name attribute. Beneath the header will be a container to hold the list of cards. This container will have an id that uses the value of the listID attribute. For our example, if the listID is 1 the element’s id will become list-1. We need to give this element an id so we can reference it when creating the list view for the cards later on. The following is an example of the board’s list template created using a script block. It should be placed before the script where your component is initialized.

<script id="listTemplate" type="text/x-kendo-template">
  <div class="list-wrapper">
    <div class="list-header">
      <span class="list-title">#: name #</span>
    </div>
    <div id="list-#: listID #" class="list"></div>
  </div>
</script>

And this is the associated CSS to style the lists:

<style>
  body {
    font-family: helvetica; 
    color: #444;
  }
 
  .board {
    overflow-x: scroll;
    white-space: nowrap;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: #cd5a91;
  }

  .list-wrapper { 
    width: 16em; 
    background-color: #eee;
    margin: .5em;
    border-radius: 3px;
    box-sizing: border-box;
    display: inline-block;
    vertical-align: top;
  }
 
  .list {
    background-color: #eee;
    border: none;
    padding: .5em;
    margin-bottom: 2em;
    box-sizing: border-box;
  }

  .list-header {
    height: 3em;
    line-height: 3em;
    padding: 0 1em;
  }
 
  .list-title {
    font-weight: bold;
  }
</style>

Creating the Cards

Next, we will create a ListView for the cards. A card will have a cardID and a name. The name is the content that will be displayed inside the card. The first step is defining the template. Again, we will use a script block that’s placed in the body of the HTML.

<script id="cardTemplate" type="text/x-kendo-template">
  <div class="card">#: name #</div>
</script>

And this is the additional styles:

.card {
  box-sizing: border-box;
  position: relative;
  width: 100%;
  min-height: 4em;
  padding: 1em;
  border-radius: 3px;
  margin-bottom: .5em;
  background: #fff;
}

For each list in the board, we will create a list view for the cards. We could create a function to loop through the data and create the components. This would be ideal if we had a variable number of lists. For instance, if we allowed users to create lists as well, then we would not be able to hard code each component. We would need to dynamically create the lists and find which cards belong to each list to insert them into the list view. However, since we are working with a fixed number of lists, I will define each component manually.

$('#list-0').kendoListView({
  template: kendo.template($('#cardTemplate').html()),
  dataSource: [
      { cardID: 0, name: 'Create UI'}
    ]
});

$('#list-1').kendoListView({
  template: kendo.template($('#cardTemplate').html()),
  dataSource: [
    { cardID: 1, name: 'Implement button behavior'  },
    { cardID: 2, name: 'Refactor code' }
  ]
});

$('#list-2').kendoListView({
  template: kendo.template($('#cardTemplate').html())
});

This is now what our board looks like:

Trello

Making the Cards Sortable

To make our cards draggable and droppable between lists we will use the Sortable component. Each of these list views will behave the same so we can give them all the same options. First, we will create a variable named sortableOptions that we will pass to the component’s arguments.

var sortableOptions = {
  filter: '.card',
  container: '.board',
  connectWith: '.list',
  cursor: 'grabbing',
  placeholder: function(element){
    return $('<div class="card"></div>').css({
      background: '#ddd'
    });
  },
  hint: function(element) {
    return element.clone().css({
      width: '15em',
      transform: 'rotate(-5deg)',
      border: '1px solid #eee'
    });
  }
};

The filter option is needed to define which items are sortable. The connectWith option lets us move the cards between the lists. Our placeholder is an empty card element that is slightly darker than the background to give the appearance of a shadow where the card was moved. And the hint is a copy of the card element given a slight tilt. The final part is to initialize each card list view as a Sortable component.

$('#list-0').kendoSortable(sortableOptions);
$('#list-1').kendoSortable(sortableOptions);
$('#list-2').kendoSortable(sortableOptions);

This is what the board looks like while dragging a card:

Trello

Summary

So far we have created a list view for the lists on the board and the cards in the lists. We also made the cards sortable so we could move them around the lists. We could have also made the lists sortable using much of the same code from the card sortable options. The main fields you would need to change is the filter option so that it uses the container for the lists and the hint can be a clone of the element.

In the next article we will implement the behavior to add, edit, and remove cards.

Try out Kendo UI for Yourself

Want to start taking advantage of the more than 70+ ready-made Kendo UI components, like the ones here? You can begin a free trial of Kendo UI today and start developing your apps faster.

Start My Kendo UI Trial

Angular, React, and Vue Versions

Looking for UI component to support specific frameworks? Check out Kendo UI for Angular, KendoReact, or Kendo UI for Vue.

Resources


Alberta Williams
About the Author

Alberta Williams

Alberta is a software developer and writer from New Orleans. Learn more about Alberta at github.com/albertaw.

Related Posts

Comments

Comments are disabled in preview mode.