Skip to content

Instantly share code, notes, and snippets.

@skleinei
Last active December 12, 2018 11:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skleinei/51fd283ac83d1bd4aa46 to your computer and use it in GitHub Desktop.
Save skleinei/51fd283ac83d1bd4aa46 to your computer and use it in GitHub Desktop.
The Scroll Tree jQuery plugin allows Scroll Viewport theme developers to implement lazy loading trees more easily. More info: http://bit.ly/1ANj0QX
(function ($) {
'use strict';
// http://learn.jquery.com/plugins/basic-plugin-creation/
// http://learn.jquery.com/plugins/advanced-plugin-concepts/
$.fn.scrollTree = function (options) {
var DEFAULT_OPTIONS = {
'contextPath': '/',
'css': {
'ancestor': 'active',
'current': 'active',
"leaf": 'leaf',
'loading': 'sp-loading',
'collapsed': 'sp-collapsed',
'expanded': 'sp-expanded',
'error': 'sp-error'
},
'renderChildrenUl': function () {
return '<ul class="nav"></ul>';
},
'renderChildLi': function (child, opts) {
return '<li class="' + opts.css[child.type] + '"><span class="sp-toggle"></span><a href="' + child.link + '">' + child.title + '</a></li>'
}
};
var viewportId = $(this).data('viewportId');
var rootLink = $(this).data('root');
var currentLink = $(this).data('current');
var opts = $.extend(true, DEFAULT_OPTIONS, options);
return this.each(function () {
var $rootUl = $(this);
loadChildren($rootUl, rootLink, currentLink);
setupEventHandling($rootUl);
return this;
});
function loadChildren($ul, parentLink, currentLink) {
var $parentLi = $ul.closest('li');
if ($parentLi) {
$parentLi.removeClass(opts.css.collapsed)
.addClass(opts.css.loading);
}
$.get(opts.contextPath + '/rest/scroll-viewport/1.0/tree/children', {
'viewportId': viewportId,
'root': rootLink,
'parent': parentLink || $parentLi.find('> a').attr('href'),
'current': currentLink || ''
})
.done(function success(children) {
insertChildren($ul, children);
$parentLi.removeClass(opts.css.loading)
.addClass(opts.css.expanded);
})
.fail(function error(jqXHR, textStatus, errorThrown) {
$parentLi.removeClass(opts.css.loading)
.addClass(opts.css.error);
})
;
}
function insertChildren($ul, children) {
$ul.html('');
$.each(children, function (idx, child) {
var $childLi = $(opts.renderChildLi(child, opts)).appendTo($ul);
if (child.children) {
if (child.children.length) {
$childLi.addClass(opts.css.expanded);
var $childrenEl = $(opts.renderChildrenUl()).appendTo($childLi);
insertChildren($childrenEl, child.children);
} else {
$childLi.addClass(opts.css.collapsed);
}
} else {
$childLi.addClass(opts.css.leaf);
}
});
}
function setupEventHandling($rootUl) {
$rootUl.on('click', '.sp-toggle', function () {
var $li = $(this).parent('li');
if ($li.is('.' + opts.css.collapsed)) {
openNode($li);
} else if ($li.is('.' + opts.css.expanded)) {
closeNode($li);
} else {
// we don't have children -> no-op
}
});
}
function openNode($li) {
if ($li.has('ul').length) {
// children have been loaded, just toggle classes
$li.removeClass(opts.css.collapsed)
.addClass(opts.css.expanded);
} else {
// children have to be loaded
var $childrenEl = $(opts.renderChildrenUl()).appendTo($li);
loadChildren($childrenEl);
}
}
function closeNode($li) {
$li
.removeClass(opts.css.expanded)
.addClass(opts.css.collapsed);
}
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment