patternjavascriptMinor
Algorithmic simplification of Miller Columns
Viewed 0 times
algorithmicmillercolumnssimplification
Problem
Background
Unsatisfied with existing implementations of Miller Columns (used to edit hierarchical data), I decided to re-invent the wheel.
Problem
Most of the existing implementations are too complex, offer extraneous functionality, reliance on complex (or unavailable) frameworks, have numerous dependencies, are riddled with severe bugs, or require non-hierarchical data.
Source
The source code has two parts. The JavaScript code performs a breadth-first traversal of an arbitrarily nested set of lists and wraps them into a consecutive, flattened hierarchy surrounded by
`(function( $ ) {
$.fn.millerColumns = function() {
var $list = $(this).first();
var $columns = $(this);
// Breadth-first traversal to rearrange list items into
// consecutively ordered div wrapper elements.
while( ($list = $list.children()).length ) {
$list.each( function( index, element ) {
var $parent = $(element).parent();
if( $(element).is( "li" ) ) {
$parent = $($parent).parent();
}
// Store the parent id for showing child columns.
var id = $($parent).attr( "id" );
if( $(element).is( "ul" ) ) {
// The parent element shall be marked as 0.
if( id === undefined ) {
id = 0;
}
var $item = $("li#" + id);
$item.addClass( "parent" );
$item.on( "click", function() {
// Hide everything.
$("div.column[data-parent!=0]").addClass( "collapsed" );
$("li").removeClass( "selection" );
// The "id" for the clicked list item becomes the start of
// the ancestral chain.
var $child = $("div.column[data-parent=" + id + "]" );
$child.removeClass( "collapsed" );
var $li = $("li.parent[id=" + id + "]");
var $ancestor = $li.parent().
Unsatisfied with existing implementations of Miller Columns (used to edit hierarchical data), I decided to re-invent the wheel.
Problem
Most of the existing implementations are too complex, offer extraneous functionality, reliance on complex (or unavailable) frameworks, have numerous dependencies, are riddled with severe bugs, or require non-hierarchical data.
Source
The source code has two parts. The JavaScript code performs a breadth-first traversal of an arbitrarily nested set of lists and wraps them into a consecutive, flattened hierarchy surrounded by
div tags. The CSS code places the divs in left-floating columns (and applies superficial presentation items).`(function( $ ) {
$.fn.millerColumns = function() {
var $list = $(this).first();
var $columns = $(this);
// Breadth-first traversal to rearrange list items into
// consecutively ordered div wrapper elements.
while( ($list = $list.children()).length ) {
$list.each( function( index, element ) {
var $parent = $(element).parent();
if( $(element).is( "li" ) ) {
$parent = $($parent).parent();
}
// Store the parent id for showing child columns.
var id = $($parent).attr( "id" );
if( $(element).is( "ul" ) ) {
// The parent element shall be marked as 0.
if( id === undefined ) {
id = 0;
}
var $item = $("li#" + id);
$item.addClass( "parent" );
$item.on( "click", function() {
// Hide everything.
$("div.column[data-parent!=0]").addClass( "collapsed" );
$("li").removeClass( "selection" );
// The "id" for the clicked list item becomes the start of
// the ancestral chain.
var $child = $("div.column[data-parent=" + id + "]" );
$child.removeClass( "collapsed" );
var $li = $("li.parent[id=" + id + "]");
var $ancestor = $li.parent().
Solution
A few observations :
- You should be able to write this so that it doesn't rely on
id. The code should be able to detect the hierarchy without being told.
- Several chaining simplifications are possible - eg.
var $breadcrumb = $("div.breadcrumb").empty()
- Vars should be declared up front in their respective functions, in a single
varstatement.
- Combined assignment and test is bad practice and makes code hard to read -
while( ($list = $list.children()).length ) {.
$ancestor.data('parent')is much more efficient than$ancestor.attr('data-parent')The former involves only javascript while the latter involves the DOM.
- The need to clone jQuery objects is rare - As far as I can see,
$($parent)will simplify to$parentwithout consequence.
Context
StackExchange Code Review Q#70788, answer score: 3
Revisions (0)
No revisions yet.