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;