/*jslint vars: true, browser: true, white: true */ /*global jQuery, IQVOC */ IQVOC.treeview = (function($) { "use strict"; function Treeview(container) { this.container = container.jquery ? container : $(container); $(container).each(function() { var url = $(this).data('url'); var container = this; var dragabbleSupport = $(container).data('dragabble'); var polyhierarchySupport = $(container).data('polyhierarchy-support'); var saveLabel = $(container).data('save-label'); var copyLabel = $(container).data('copy-label'); var undoLabel = $(container).data('undo-label'); // build tree data from html markup var data = $(this).children('li').map(function() { var item = $(this); return { label: item.children('a').html(), load_on_demand: item.data('has-children'), locked: item.data('locked'), id: item.attr('id'), url: item.children('a').attr('href'), update_url: item.data('update-url'), glance_url: item.data('glance-url'), published: item.data('published'), additionalText: item.children('span.additional_info').html() }; }); $(this).tree({ dragAndDrop: dragabbleSupport ? true : false, autoEscape: false, selectable: false, useContextMenu: false, closedIcon: $(''), openedIcon: $(''), data: data, dataUrl: function(node) { var uri = URI(url).addQuery('root', node.id); return uri.normalize().toString(); }, onCreateLi: function(node, $li) { var link = buildLink(node.url, node.name); $li.find('.jqtree-title').replaceWith(link); // add aditional info if present (e.g. for collections) if (node.additionalText) { link.after(' ', node.additionalText); } // mark published/unpublished items if (typeof node.published !== 'undefined' && !node.published) { // modify draft link var href = URI(link.attr('href')); link.attr('href', href.addQuery('published', 0)); link.addClass('unpublished'); } else { link.addClass('published'); } if (link[0]) { var teaserLink = buildTeaserLink(node, link[0]); $li.find('.jqtree-element').append(teaserLink); } if (dragabbleSupport) { // mark locked items if (node && node.locked) { // add icon only to the first element of the collection. // the second one could be a nodelist for parents nodes. $li.find('.jqtree-element').append(' '); } if (node && !node.locked) { // add icon only to the first element of the collection. // the second one could be a nodelist for parents nodes. $li.find('.jqtree-element').append(' '); } } if(node.moved) { $li.data({ 'node-id': node.id, 'old-parent-node-id': node.old_parent_id, 'new-parent-node-id': node.target_node_id, 'old-previous-sibling-id': node.old_previous_sibling_id, 'update-url': node.update_url, 'glance-url': node.glance_url }); var saveButton = $(''); var copyButton = $(''); var undoButton = $(''); // add icon only to the first element of the collection. // the second one could be a nodelist for parents nodes. $li.find('.jqtree-element').append(saveButton, undoButton); if(polyhierarchySupport) { saveButton.after(copyButton); } } }, onIsMoveHandle: function($element) { // dom element which acts as move handle return ($element.is('.fa-arrows')); }, onCanMoveTo: function(moved_node, target_node, position){ // prevent node movement inside parent node if (moved_node.parent === target_node.parent && position === 'after'){ return false; } // prevent locked node movement else if (moved_node.locked === true || target_node.locked === true) { return false; } // only drop node inside nodes, no ordering else if (position === 'after') { return false; } else { return true; } } }); }); // mark moved nodes $('#content > ul.hybrid-treeview').on('tree.move', function(event) { var moved_node = event.move_info.moved_node; $(this).tree('updateNode', moved_node, { moved: true, target_node_id: event.move_info.target_node.id }); if (moved_node.getPreviousSibling() !== null) { $(this).tree('updateNode', moved_node, {old_previous_sibling_id: moved_node.getPreviousSibling().id}); } if (moved_node && moved_node.parent.id) { $(this).tree('updateNode', moved_node, {old_parent_id: moved_node.parent.id}); } }); // save/copy moved node $('#content > ul.hybrid-treeview').on('click', 'button.node-btn', function(event) { var $tree = $('#content > ul.hybrid-treeview'); var treeAction = $(this).data('tree-action'); var updateUrl = $(this).closest('li').data('update-url'); var movedNodeId = $(this).closest('li').data('node-id'); var oldParentNodeId = $(this).closest('li').data('old-parent-node-id'); var oldPreviousSiblingId = $(this).closest('li').data('old-previous-sibling-id'); var newParentNodeId = $(this).closest('li').data('new-parent-node-id'); $.ajax({ url : updateUrl, type : 'PATCH', data : { tree_action: treeAction, moved_node_id: movedNodeId, old_parent_node_id: oldParentNodeId, new_parent_node_id: newParentNodeId }, statusCode: { 200: function(response) { // mark moved node to draft var newNodeId = response.new_node_id; setToDraft(movedNodeId, newNodeId, $tree); // add node to old parent, necessary to see both node directly after movement, // this is not necessary if you refresh the page if (treeAction === 'copy') { var node = $tree.tree('getNodeById', movedNodeId); if (oldPreviousSiblingId) { var old_previous_sibling = $tree.tree('getNodeById', oldPreviousSiblingId); $tree.tree('addNodeAfter', node, old_previous_sibling); } else if (oldParentNodeId) { var old_parent_node = $tree.tree('getNodeById', oldParentNodeId); $tree.tree('appendNode', node, old_parent_node); } } } } }); }); // reset moved node $('#content > ul.hybrid-treeview').on('click', 'button.reset-node-btn', function(event) { var $tree = $('#content > ul.hybrid-treeview'); var nodeId = $(this).closest('li').data('node-id'); var oldPreviousSiblingId = $(this).closest('li').data('old-previous-sibling-id'); var oldParentNodeId = $(this).closest('li').data('old-parent-node-id'); moveToOldPosition(nodeId, oldPreviousSiblingId, oldParentNodeId, $tree); }); function setToDraft(nodeId, newNodeId, $tree) { if (nodeId) { var moved_node = $tree.tree('getNodeById', nodeId); $tree.tree('updateNode', moved_node, { id: newNodeId, moved: false, published: false }); } } function moveToOldPosition(nodeId, oldPreviousSiblingId, oldParentNodeId, $tree) { var node = $tree.tree('getNodeById', nodeId); if (oldPreviousSiblingId) { var old_previous_sibling = $tree.tree('getNodeById', oldPreviousSiblingId); $tree.tree('moveNode', node, old_previous_sibling, 'after'); } else if (oldParentNodeId) { var oldParentNode = $tree.tree('getNodeById', oldParentNodeId); $tree.tree('moveNode', node, oldParentNode, 'inside'); } $tree.tree('updateNode', node, {moved: false}); } function buildLink(url, label) { var link = $('') link.attr('href', url) .addClass('tree-element-link') .html(label); return link; } function buildTeaserLink(node, link) { if (node && !node.glance_url) { return; } var teaserLink = $('') teaserLink.addClass('tree-element-teaser-link') .attr('href', node.glance_url) .append($('')) teaserLink.click(function(ev) { ev.preventDefault(); var modal = $("#concept-teaser-modal"); var target = $(this).attr("href"); $.get(target, function(data) { modal.html(data); modal.modal(); }); }); return teaserLink; } } return function(selector) { return new Treeview(selector); }; }(jQuery));