Trello Like Drag and Drop Cards for Project Management Software

Last modified on July 17th, 2018 by Vincy.

Effective project management is a critical need for a project success. To ensure that, we cannot depend only on the human resources for managing projects. Managers need to be armed with the best project management software.

In this competitive fast moving world, we need a rapid, never dying, efficient routine for managing projects. The project management software should play an efficient role by enabling the people managing the projects. There are too many project management software out there in the market and I am not going to recommend one in this article. But we are going to see a killer feature that is  dominating the project management software industry these days. 

Trello-Like-Drag-and-Drop-Cards-for-Project-Management-Software

View Demo

Project management systems like Trello, Mingle have the interactive card-like status-based grouping of projects and tasks. This card-based task grouping is intuitive to use.

Many of the project management software applications, provides the project management functionality with the traditional list-based design methodology. That is, by having a long list task managed in a tabular form and controls to perform CRUD via HTML forms.

With my personal opinion and expertise, I found the card-based interface comfortable to organize the tasks. In this tutorial, let us see how to implement cards with drag and drop using PHP, that can be used in a project management software.

Trello Like Drag and Drop Cards for Project Management Code Overview

This tutorial is going to be a series on building a good project management software from the scratch. In this post, I have taken the most interesting part of this journey, that is to create the interactive task board with jQuery drag and drop feature. In the upcoming article, we will see about task add/edit by using inline insert and edit methodologies. In PHP code, the project’s tasks are retrieved from the database and grouped together on the status based. The task board interface will display status lanes with the task cards. These task cards could be moved from one status to another by drag and drop to change the status of the tasks.

Database Script

The database tables tbl_task and tbl_status structure and data can be imported by using this script.

--
-- Table structure for table `tbl_status`
--

CREATE TABLE `tbl_status` (
  `id` int(11) NOT NULL,
  `status_name` varchar(55) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `tbl_status`
--

INSERT INTO `tbl_status` (`id`, `status_name`) VALUES
(1, 'New'),
(2, 'In Progress'),
(3, 'Pending'),
(4, 'Done');

--
-- Table structure for table `tbl_task`
--

CREATE TABLE `tbl_task` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `project_name` varchar(255) NOT NULL,
  `status_id` int(11) NOT NULL,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `tbl_task`
--

INSERT INTO `tbl_task` (`id`, `title`, `description`, `project_name`, `status_id`, `created_at`) VALUES
(1, 'Tutorial CRUD', 'CRUD Job for the Tutorial functionality', 'StartTuts', 1, '2018-07-12 18:45:01'),
(2, 'Listing with Filtering and Pagination', 'Tutorial listing with search filter option and pagination links', 'StartTuts', 2, '2018-07-12 18:44:54'),
(3, 'Sorting and Change Ordering', 'Enabling dynamic sorting and change the list order with AJAX  ', 'StartTuts', 1, '2018-07-12 18:44:58'),
(4, 'Client-side and server-side Validation', 'Validating user data with client and the server side validation mechanism.', 'StartTuts', 3, '2018-07-12 18:44:56');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_status`
--
ALTER TABLE `tbl_status`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `tbl_task`
--
ALTER TABLE `tbl_task`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_status`
--
ALTER TABLE `tbl_status`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

--
-- AUTO_INCREMENT for table `tbl_task`
--
ALTER TABLE `tbl_task`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
COMMIT;

Interactive Task Board UI

In this section, we are going to create the task board user interface by fetching database results using PHP code. The task board is the horizontally scrollable interface where the status lanes are displayed. On each status lanes, the draggable tasks cards are placed vertically. The tasks and the statuses on the task board UI are dynamic from the database. So, the statuses and the tasks under each status are fetched by querying the database with the SELECT statement. 

<?php
require_once "ProjectManagement.php";

$projectName = "StartTuts";
$projectManagement = new ProjectManagement();
$statusResult = $projectManagement->getAllStatus();
?>
<html>
<head>
<title>Trello Like Drag and Drop Cards for Project Management Software</title>
<link rel="stylesheet"
    href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<h1>Trello Like Drag and Drop Cards for Project Management Software</h1>
        <div class="task-board">
            <?php
            foreach ($statusResult as $statusRow) {
                $taskResult = $projectManagement->getProjectTaskByStatus($statusRow["id"], $projectName);
                ?>
                <div class="status-card">
                    <div class="card-header">
                        <span class="card-header-text"><?php echo $statusRow["status_name"]; ?></span>
                    </div>
                    <ul class="sortable ui-sortable"
                        id="sort<?php echo $statusRow["id"]; ?>"
                        data-status-id="<?php echo $statusRow["id"]; ?>">
                <?php
                if (! empty($taskResult)) {
                    foreach ($taskResult as $taskRow) {
                        ?>
                
                     <li class="text-row ui-sortable-handle"
                            data-task-id="<?php echo $taskRow["id"]; ?>"><?php echo $taskRow["title"]; ?></li>
                <?php
                    }
                }
                ?>
                                                 </ul>
                </div>
                <?php
            }
            ?>
        </div>
</body>
</html>

This is the CSS used apply the styles for the task board HTML elements.

<style>
body {
    font-family: arial;
}
h1 {
    font-weight: normal;
}
.task-board {
    background: #2c7cbc;
    display: inline-block;
    padding: 12px;
    border-radius: 3px;
    width: 850px;
    white-space: nowrap;
    overflow-x: scroll;
    min-height: 300px;
}

.status-card {
    width: 250px;
    margin-right: 8px;
    background: #e2e4e6;
    border-radius: 3px;
    display: inline-block;
    vertical-align: top;
    font-size: 0.9em;
}

.status-card:last-child {
    margin-right: 0px;
}

.card-header {
    width: 100%;
    padding: 10px 10px 0px 10px;
    box-sizing: border-box;
    border-radius: 3px;
    display: block;
    font-weight: bold;
}

.card-header-text {
    display: block;
}

ul.sortable {
    padding-bottom: 10px;
}

ul.sortable li:last-child {
    margin-bottom: 0px;
}

ul {
    list-style: none;
    margin: 0;
    padding: 0px;
}

.text-row {
    padding: 8px 10px;
    margin: 10px;
    background: #fff;
    box-sizing: border-box;
    border-radius: 3px;
    border-bottom: 1px solid #ccc;
    cursor: pointer;
    font-size: 0.8em;
    white-space: normal;
    line-height: 20px;
}

.ui-sortable-placeholder {
    visibility: inherit !important;
    background: transparent;
    border: #666 2px dashed;
}
</style>

jQuery Drag and Drop to Move Task Cards between Status Lanes

This jQuery script is used to enable drag and drop feature and to handle the mouse event in this regard. The status lane elements are connected as sortable elements by using connectWith property of the jQuery library function. It will allow the user to move the task cards between the sortable parent elements which are here the status lanes. On receiving the card element, the AJAX call will be sent to the PHP to change the status of the tasks appropriately.

<script>
	$(function() {
		var url = 'edit-status.php';
		$('ul[id^="sort"]').sortable(
				{
					connectWith : ".sortable",
					receive : function(e, ui) {
						var status_id = $(ui.item).parent(".sortable").data(
								"status-id");
						var task_id = $(ui.item).data("task-id");
						$.ajax({
							url : url + '?status_id=' + status_id + '&task_id='
									+ task_id,
							success : function(response) {
							}
						});
					}

				}).disableSelection();
	});
</script>

The edit-status.php file is used to change the task status on dropping the task card on a status lanes. On the drop event, this PHP file is requested via AJAX by passing the task id and the status id. The AJAX parameters are received in the PHP file and passed to the ProjectManagement model class function which creates and triggers the task status update.

<?php 
require_once "ProjectManagement.php";
$projectManagement = new ProjectManagement();

$status_id = $_GET["status_id"];
$task_id = $_GET["task_id"];

$result = $projectManagement->editTaskStatus($status_id, $task_id);
?>

PHP ProjectManagement Model Class

This is the PHP ProjectManagement Model class code. It contains functions to create the database query to be used for processing data fetching and status changing actions on the task entity. The query statement and the params are sent to the DBcontroller class function to execute database actions by using MySQLi prepared statement.

<?php
require "DBController.php";
class ProjectManagement {
    function getProjectTaskByStatus($statusId, $projectName) {
        $db_handle = new DBController();
        $query = "SELECT * FROM tbl_task WHERE status_id= ? AND project_name = ?";
        $result = $db_handle->runQuery($query, 'is', array($statusId, $projectName));
        return $result;
    }
    
    function getAllStatus() {
        $db_handle = new DBController();
        $query = "SELECT * FROM tbl_status";
        $result = $db_handle->runBaseQuery($query);
        return $result;
    }
    
    function editTaskStatus($status_id, $task_id) {
        $db_handle = new DBController();
        $query = "UPDATE tbl_task SET status_id = ? WHERE id = ?";
        $result = $db_handle->update($query, 'ii', array($status_id, $task_id));
        return $result;
    }
}
?>

DBController.php

This PHP file has the functions to handle the DAO operations like database read and update by establishing the connection.

<?php
class DBController {
	private $host = "localhost";
	private $user = "root";
	private $password = "test";
	private $database = "db_project_management";
	private $conn;
	
    function __construct() {
        $this->conn = $this->connectDB();
	}	
	
	function connectDB() {
		$conn = mysqli_connect($this->host,$this->user,$this->password,$this->database);
		return $conn;
	}
	
    function runBaseQuery($query) {
        $result = $this->conn->query($query);	
        if ($result->num_rows > 0) {
            while($row = $result->fetch_assoc()) {
                $resultset[] = $row;
            }
        }
        return $resultset;
    }
    
    
    
    function runQuery($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
        $result = $sql->get_result();
        
        if ($result->num_rows > 0) {
            while($row = $result->fetch_assoc()) {
                $resultset[] = $row;
            }
        }
        
        if(!empty($resultset)) {
            return $resultset;
        }
    }
    
    function bindQueryParams($sql, $param_type, $param_value_array) {
        $param_value_reference[] = & $param_type;
        for($i=0; $i<count($param_value_array); $i++) {
            $param_value_reference[] = & $param_value_array[$i];
        }
        call_user_func_array(array(
            $sql,
            'bind_param'
        ), $param_value_reference);
    }
    
    function insert($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
    }
    
    function update($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
    }
}
?>

Trello Like Project Management Task Board Output

The task board with the card like task data elements are listed under the appropriate status as shown in the below screenshot. The status lanes are plotted on the task board which is scrollable horizontally.

Trello Like Drag and Drop-Cards-for-Project-Management-Software-Output

View Demodownloads

This PHP code tutorial was published on July 17, 2018.

↑ Back to Top

Share this Article