diff --git a/samples/index.html b/samples/index.html index 3e12ddb..da79710 100644 --- a/samples/index.html +++ b/samples/index.html @@ -22,6 +22,7 @@

About

sample 12 - shows mix of automatic columns and manual column breaks.

sample 13 - shows only manual column breaks.

sample 14 - shows column break inside of a dontsplit item.

+

sample 16 - show usage of `allowLongDontSplit` options.

 

GitHub Issues

diff --git a/samples/sample16.html b/samples/sample16.html new file mode 100644 index 0000000..1d74cb1 --- /dev/null +++ b/samples/sample16.html @@ -0,0 +1,264 @@ + + + + + + Columnizer JQuery Plugin sample page 3 + + + + + + + + + +
+

Rendering example without `allowLongDontSplit`

+

Columnizer not able to handle such case correctly, as a result - no columns

+ +
+
+

Rendering example with `allowLongDontSplit`

+ +
+ + diff --git a/src/jquery.columnizer.js b/src/jquery.columnizer.js index f5c9955..2637eb9 100644 --- a/src/jquery.columnizer.js +++ b/src/jquery.columnizer.js @@ -1,16 +1,18 @@ -// version 1.6.0 -// http://welcome.totheinter.net/columnizer-jquery-plugin/ -// created by: Adam Wulf @adamwulf, adam.wulf@gmail.com +/*! + jQuery.columnizer plugin, version 1.6.0 + http://welcome.totheinter.net/columnizer-jquery-plugin/ + created by: Adam Wulf @adamwulf, adam.wulf@gmail.com +*/ (function($){ $.fn.columnize = function(options) { - this.cols =[]; - this.offset= 0; + this.cols =[]; + this.offset= 0; this.before=[]; - this.lastOther=0; + this.lastOther=0; this.prevMax =0; - this.debug=0; + this.debug=0; this.setColumnStart =null; this.elipsisText=''; @@ -27,7 +29,7 @@ overflow : false, // this function is called after content is columnized doneFunc : function(){}, - // if the content should be columnized into a + // if the content should be columnized into a // container node other than it's own node target : false, // re-columnizing when images reload might make things @@ -35,6 +37,15 @@ ignoreImageLoading : true, // should columns float left or right columnFloat : "left", + // allow last column to be shorter than the rest + // this relaxes the columnizer algorithm a bit, to allow correct solution, + // when there are long 'dontsplit' blocks. + lastCanBeLowest : false, + // Allow to insert long dontsplit blocks into a column, + // even if column ends up higher than desired height. + // This might help finding a columnize solution in case + // we need to split a set of long dontsplit blocks + allowLongDontSplit : false, // ensure the last column is never the tallest column lastNeverTallest : false, // (int) the minimum number of characters to jump when splitting @@ -47,7 +58,7 @@ // default to empty string for backwards compatibility cssClassPrefix : "", elipsisText:'...', - debug:0, + debug:0 }; options = $.extend(defaults, options); @@ -65,8 +76,8 @@ } if(options.debug) { // assert is off by default this.debug=options.debug; - } - + } + /** * appending a text node to a will * cause a jquery crash. @@ -151,7 +162,7 @@ * is a text node, then it will try to split that text node. otherwise * it will leave the node in $pullOutHere and return with a height * smaller than targetHeight. - * + * * Returns a boolean on whether we did some splitting successfully at a text point * (so we know we don't need to split a real element). return false if the caller should * split a node if possible to end this column. @@ -246,7 +257,7 @@ } /** - * Split up an element, which is more complex than splitting text. We need to create + * Split up an element, which is more complex than splitting text. We need to create * two copies of the element with it's contents divided between each */ function split($putInHere, $pullOutHere, $parentColumn, targetHeight){ @@ -283,6 +294,7 @@ appendSafe($putInHere, $clone); $cloneMe.remove(); }else if($clone.get(0).nodeType == 1 && !$clone.hasClass(prefixTheClassName("dontend"))){ + var parentColumnHeightBeforeAppend = $parentColumn.height(); appendSafe($putInHere, $clone); if($clone.is("img") && $parentColumn.height() < targetHeight + 20){ // @@ -294,10 +306,15 @@ // pretty close fit, and we're not allowed to split it, so just // add it to the column, remove from pullOutHere, and be done $cloneMe.remove(); + }else if(options.allowLongDontSplit && $cloneMe.hasClass(prefixTheClassName("dontsplit")) && parentColumnHeightBeforeAppend < 20){ + // + // we have a long dontsplit block, while the parent column is empty - we have to insert it, + // otherwise there won't be any solution, cause one of our columns will anyway be too tall. + $cloneMe.remove(); }else if($clone.is("img") || $cloneMe.hasClass(prefixTheClassName("dontsplit"))){ // // it's either an image that's too tall, or an unsplittable node - // that's too tall. leave it in the pullOutHere and we'll add it to the + // that's too tall. leave it in the pullOutHere and we'll add it to the // next column $clone.remove(); }else{ @@ -310,13 +327,13 @@ // this node may still have non-text nodes to split // add the split class and then recur $cloneMe.addClass(prefixTheClassName("split")); - + //if this node was ol element, the child should continue the number ordering if($cloneMe.get(0).tagName == 'OL'){ var startWith = $clone.get(0).childElementCount + $clone.get(0).start; $cloneMe.attr('start',startWith+1); } - + if($cloneMe.children().length){ split($clone, $cloneMe, $parentColumn, targetHeight); } @@ -465,7 +482,7 @@ } // - // We loop as we try and workout a good height to use. We know it initially as an average + // We loop as we try and workout a good height to use. We know it initially as an average // but if the last column is higher than the first ones (which can happen, depending on split // points) we need to raise 'adjustment'. We try this over a few iterations until we're 'solid'. // @@ -545,7 +562,7 @@ } if(options.overflow && !scrollHorizontally){ var IE6 = false; - /*@cc_on + /*@cc_on @if (@_jscript_version < 5.7) IE6 = true; @end @@ -582,6 +599,7 @@ var min = 10000000; var max = 0; var lastIsMax = false; + var lastIsMin = false; var numberOfColumnsThatDontEndInAColumnBreak = 0; $inBox.children().each(function($inBox){ return function($item){ var $col = $inBox.children().eq($item); @@ -589,12 +607,16 @@ if(!endsInBreak){ var h = $col.height(); lastIsMax = false; + lastIsMin = false; totalH += h; if(h > max) { max = h; lastIsMax = true; } - if(h < min) min = h; + if(h < min) { + min = h; + lastIsMin = true; + } numberOfColumnsThatDontEndInAColumnBreak++; } }; @@ -606,6 +628,10 @@ // all columns end in a column break, // so we're done here loopCount = maxLoops; + }else if(options.lastCanBeLowest && lastIsMin){ + // lastColumn is allowed to be shorter than others + // so we're done here + loopCount = maxLoops; }else if(options.lastNeverTallest && lastIsMax){ // the last column is the tallest // so allow columns to be taller @@ -684,8 +710,8 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { // if the first LI in the current column is split, decrement, as we want the same number/key if( $($cols[this.offset]).find($tag1+':first li.split').length ) { var $whereElipsis=$($cols[this.offset-1]).find($tag1+':last li:last'); - if( this.elipsisText==='' || - $($cols[this.offset-1]).find($tag1+':last ~ div').length || + if( this.elipsisText==='' || + $($cols[this.offset-1]).find($tag1+':last ~ div').length || $($cols[this.offset-1]).find($tag1+':last ~ p').length ) { ; } else { @@ -708,7 +734,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { } // an item in split between two columns. it only holds one key... if($($cols[this.offset]).find($tag1+':first >li.split >'+$tag1).length==0) { - $tint--; + $tint--; } } if($rest==1) { @@ -769,7 +795,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { $list.attr('start', $tint); } } - return 0; + return 0; } if(typeof $targetId === 'undefined') { $targetId=false; } @@ -780,7 +806,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { var $target =''; this.prevMax =1; - + if($targetClass) { $target ="."+$targetClass; } else { @@ -788,7 +814,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { } var $tag1 = $searchTag.toLowerCase(); var $tag2 = $searchTag.toUpperCase(); - + this.cols = $($target); if(this.debug) { console.log("There are "+this.cols.length+" items, looking for "+$tag1); @@ -803,7 +829,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { console.log("iterating "+this.offset+"...[of "+this.cols.length+"]"); } // if the first column again, nothing to the left of you, do nothing... - if(this.offset % $colno==0) { + if(this.offset % $colno==0) { if(this.debug) { console.log("First column (in theory..)"); } @@ -811,7 +837,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { this.prevMax = 1; continue; } - + this.before = $(this.cols[this.offset-1]).find($tag1+':last'); // if there are no occurences of the searchTag, do nothing if(this.before.length) { @@ -836,7 +862,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { break; } } - + this.nest =1; if($(this.cols[this.offset]).find(">"+$tag1+':first li '+$tag1+":first").length) { this.nest = 2; @@ -846,7 +872,7 @@ $.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) { $list = $(this.cols[this.offset]).find($tag1+':first li '+$tag1+":first"); if($list.length) { // I hope the two columns have same nesting, or its busted - + this.before= $(this.cols[this.offset-1]).find(">"+$tag1+':last li '+$tag1+":last"); this.prevMax= 0; this.nest =1;