summaryrefslogtreecommitdiff
path: root/assets/js/board.js
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-05-17 17:35:39 -0400
committerFrédéric Guillot <fred@kanboard.net>2014-05-17 17:35:39 -0400
commit5e4b40665fa11ce0fd0fe957a19e2b7e63f47446 (patch)
treeb0e458788f84c03608154866ec3e964ec89ccb14 /assets/js/board.js
parent09da5720e8dccaa2437a7b25d992eaa104753684 (diff)
Rewrite board drag and drop with jquery (touch devices, IE, auto-update)
Diffstat (limited to 'assets/js/board.js')
-rw-r--r--assets/js/board.js301
1 files changed, 73 insertions, 228 deletions
diff --git a/assets/js/board.js b/assets/js/board.js
index 948ebf01..eab3916b 100644
--- a/assets/js/board.js
+++ b/assets/js/board.js
@@ -1,259 +1,102 @@
(function () {
- function handleItemDragStart(e)
- {
- this.style.opacity = '0.4';
-
- dragSrcItem = this;
- dragSrcColumn = this.parentNode;
-
- e.dataTransfer.effectAllowed = 'copy';
- e.dataTransfer.setData('text/plain', this.innerHTML);
- }
-
- function handleItemDragEnd(e)
- {
- // Restore styles
- removeOver();
- this.style.opacity = '1.0';
-
- dragSrcColumn = null;
- dragSrcItem = null;
- }
-
- function handleItemDragOver(e)
- {
- if (e.preventDefault) e.preventDefault();
-
- e.dataTransfer.dropEffect = 'copy';
-
- return false;
- }
-
- function handleItemDragEnter(e)
- {
- if (dragSrcItem != this) {
- removeOver();
- this.classList.add('over');
- }
- }
+ var checkInterval = null;
- function handleItemDrop(e)
+ // Setup the board
+ function board_load_events()
{
- if (e.preventDefault) e.preventDefault();
- if (e.stopPropagation) e.stopPropagation();
-
- // Drop the element if the item is not the same
- if (dragSrcItem != this) {
-
- var position = getItemPosition(this);
- var item = createItem(e.dataTransfer.getData('text/plain'));
-
- if (countColumnItems(this.parentNode) == position) {
- this.parentNode.appendChild(item);
- }
- else {
- this.parentNode.insertBefore(item, this);
+ $(".column").sortable({
+ connectWith: ".column",
+ placeholder: "draggable-placeholder",
+ stop: function(event, ui) {
+ board_save();
}
+ });
- dragSrcItem.parentNode.removeChild(dragSrcItem);
-
- saveBoard();
- }
-
- dragSrcColumn = null;
- dragSrcItem = null;
-
- return false;
- }
-
-
- function handleColumnDragOver(e)
- {
- if (e.preventDefault) e.preventDefault();
-
- e.dataTransfer.dropEffect = 'copy';
-
- return false;
- }
+ var interval = parseInt($("#board").attr("data-check-interval"));
- function handleColumnDragEnter(e)
- {
- if (dragSrcColumn != this) {
- removeOver();
- this.classList.add('over');
+ if (interval > 0) {
+ checkInterval = window.setInterval(board_check, interval * 1000);
}
}
- function handleColumnDrop(e)
+ // Stop events
+ function board_unload_events()
{
- if (e.preventDefault) e.preventDefault();
- if (e.stopPropagation) e.stopPropagation();
-
- // Drop the element if the column is not the same
- if (dragSrcColumn != this) {
-
- var item = createItem(e.dataTransfer.getData('text/plain'));
- this.appendChild(item);
- dragSrcColumn.removeChild(dragSrcItem);
-
- saveBoard();
- }
-
- return false;
+ clearInterval(checkInterval);
}
- function saveBoard()
+ // Save and refresh the board
+ function board_save()
{
var data = [];
- var projectId = document.getElementById("board").getAttribute("data-project-id");
- var cols = document.querySelectorAll('.column');
-
- [].forEach.call(cols, function(col) {
-
- var task_limit = col.getAttribute("data-task-limit");
+ var projectId = $("#board").attr("data-project-id");
- if (task_limit != "" && task_limit != "0") {
-
- task_limit = parseInt(task_limit);
-
- if (col.children.length > task_limit) {
- col.classList.add("task-limit-warning");
- }
- else {
- col.classList.remove("task-limit-warning");
- }
-
- var counter = document.getElementById("task-number-column-" + col.getAttribute("data-column-id"));
- if (counter) counter.innerHTML = col.children.length;
- }
+ board_unload_events();
- [].forEach.call(col.children, function(item) {
+ $(".column").each(function() {
+ var columnId = $(this).attr("data-column-id");
+ $("#column-" + columnId + " .task").each(function(index) {
data.push({
- "task_id": item.firstElementChild.getAttribute("data-task-id"),
- "position": getItemPosition(item),
- "column_id": col.getAttribute("data-column-id")
- })
+ "task_id": parseInt($(this).attr("data-task-id")),
+ "position": index + 1,
+ "column_id": parseInt(columnId)
+ });
});
});
- var xhr = new XMLHttpRequest();
- xhr.open("POST", "?controller=board&action=save&project_id=" + projectId, true);
-
- xhr.onreadystatechange = function(response) {
-
- if (this.readyState == this.DONE) {
- try {
- var response = JSON.parse(this.responseText);
-
- if (response.result == false) {
- window.alert('Unable to update the board');
- }
- else if (response.refresh == true) {
- window.location = "?controller=board&action=show&project_id=" + projectId;
- }
- }
- catch (e) {}
+ $.ajax({
+ url: "?controller=board&action=save&project_id=" + projectId,
+ data: {positions: data},
+ type: "POST",
+ success: function(data) {
+ $("#board").remove();
+ $("#main").append(data);
+ board_load_events();
+ applyFilter(getSelectedUserFilter(), hasDueDateFilter());
}
- };
-
- xhr.send(JSON.stringify(data));
+ });
}
- function getItemPosition(element)
+ // Check if a board have been changed by someone else
+ function board_check()
{
- var i = 0;
-
- while ((element = element.previousSibling) != null) {
+ var projectId = $("#board").attr("data-project-id");
+ var timestamp = $("#board").attr("data-time");
- if (element.nodeName == "DIV" && element.className == "draggable-item") {
- i++;
- }
+ if (projectId != undefined && timestamp != undefined) {
+ $.ajax({
+ url: "?controller=board&action=check&project_id=" + projectId + "&timestamp=" + timestamp,
+ statusCode: {
+ 200: function(data) {
+ $("#board").remove();
+ $("#main").append(data);
+ board_unload_events();
+ board_load_events();
+ applyFilter(getSelectedUserFilter(), hasDueDateFilter());
+ }
+ }
+ });
}
-
- return i + 1;
- }
-
- function countColumnItems(element)
- {
- return element.children.length;
- }
-
- function createItem(html)
- {
- var item = document.createElement("div");
- item.className = "draggable-item";
- item.draggable = true;
- item.innerHTML = html;
- item.ondragstart = handleItemDragStart;
- item.ondragend = handleItemDragEnd;
- item.ondragenter = handleItemDragEnter;
- item.ondragover = handleItemDragOver;
- item.ondrop = handleItemDrop;
-
- return item;
}
- function removeOver()
- {
- // Remove column over
- [].forEach.call(document.querySelectorAll('.column'), function (col) {
- col.classList.remove('over');
- });
-
- // Remove item over
- [].forEach.call(document.querySelectorAll('.draggable-item'), function (item) {
- item.classList.remove('over');
- });
- }
-
- // Drag and drop events
-
- var dragSrcItem = null;
- var dragSrcColumn = null;
-
- var items = document.querySelectorAll('.draggable-item');
-
- [].forEach.call(items, function(item) {
- item.addEventListener('dragstart', handleItemDragStart, false);
- item.addEventListener('dragend', handleItemDragEnd, false);
- item.addEventListener('dragenter', handleItemDragEnter, false);
- item.addEventListener('dragover', handleItemDragOver, false);
- item.addEventListener('drop', handleItemDrop, false);
- });
-
- var cols = document.querySelectorAll('.column');
-
- [].forEach.call(cols, function(col) {
- col.addEventListener('dragenter', handleColumnDragEnter, false);
- col.addEventListener('dragover', handleColumnDragOver, false);
- col.addEventListener('drop', handleColumnDrop, false);
- });
-
- [].forEach.call(document.querySelectorAll('[data-task-id]'), function (item) {
- item.addEventListener('click', function() {
- window.location.href = '?controller=task&action=show&task_id=' + item.getAttribute('data-task-id');
- });
- });
-
- // Filtering
-
+ // Get the selected user id
function getSelectedUserFilter()
{
- var select = document.getElementById("form-user_id");
- return select.options[select.selectedIndex].value;
+ return $("#form-user_id").val();
}
+ // Return true if the filter is activated
function hasDueDateFilter()
{
- var dateFilter = document.getElementById("filter-due-date");
- return dateFilter.classList.contains("filter-on");
+ return $("#filter-due-date").hasClass("filter-on");
}
+ // Apply user or date filter (change tasks opacity)
function applyFilter(selectedUserId, filterDueDate)
{
- [].forEach.call(document.querySelectorAll('[data-task-id]'), function (item) {
+ $("[data-task-id]").each(function(index, item) {
var ownerId = item.getAttribute("data-owner-id");
var dueDate = item.getAttribute("data-due-date");
@@ -271,22 +114,24 @@
});
}
- var userFilter = document.getElementById("form-user_id");
- var dateFilter = document.getElementById("filter-due-date");
-
- if (userFilter) {
- userFilter.onchange = function() {
+ // Load filter events
+ function filter_load_events()
+ {
+ $("#form-user_id").change(function() {
applyFilter(getSelectedUserFilter(), hasDueDateFilter());
- };
- }
-
- if (dateFilter) {
+ });
- dateFilter.onclick = function(e) {
- dateFilter.classList.toggle("filter-on");
+ $("#filter-due-date").click(function(e) {
+ $(this).toggleClass("filter-on");
applyFilter(getSelectedUserFilter(), hasDueDateFilter());
e.preventDefault();
- };
+ });
}
+ // Initialization
+ $(function() {
+ board_load_events();
+ filter_load_events();
+ });
+
}());