This code will do that. I've coded it so that if you use manual breaks, you have to then use them to define all your columns break points. This adds predictability and simplicity, avoiding lots of potential difficulties that would arise combining automated and manual breaks (e.g. what if you want an extra long column).
This is useful to allow you to consistently apply columnising on your site, but then in special cases guide the columnizer precisely, without having to go back to the point of creating your column markup manually.
Patch would be as follows..
@@ -39,11 +39,15 @@
// (int) the minimum number of characters to jump when splitting
// text nodes. smaller numbers will result in higher accuracy
// column widths, but will take slightly longer
- accuracy : false
+ accuracy : false,
+ // if we need a 'force-break' class set
+ explicitBreaks : $(this).find('.force-break').length!=0,
};
var options = $.extend(defaults, options);
- $(this).find('h1, h2, h3, h4, h5, h6').addClass('dontend');
+ if (!options.explicitBreaks) {
+ $(this).find('h1, h2, h3, h4, h5, h6').addClass('dontend');
+ }
$(this).find('table, thead, tbody, tfoot, colgroup, caption, label, legend, script, style, textarea, button, object, embed, tr, th, td, li, h1, h2, h3, h4, h5, h6, form').addClass('dontsplit');
$(this).find('br').addClass('removeiflast').addClass('removeiffirst');
@@ -103,14 +107,31 @@
/**
* Create a node that has a height
* less than or equal to height.
- * 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).
+ * Returns a boolean on whether we did some splitting successfully at an optimal point (so we know we don't need to continue to split elements recursively).
*
* @param putInHere, a jQuery element
* @$pullOutHere, a dom element
*/
- function columnize($putInHere, $pullOutHere, $parentColumn, height){
- while($parentColumn.height() < height && $pullOutHere[0].childNodes.length){
- $putInHere.append($pullOutHere[0].childNodes[0]); // Because we're not cloning, jquery will actually move the element
+ function columnize($putInHere, $pullOutHere, $parentColumn, height) {
+ if (options.explicitBreaks) { // We're doing explicit breaks, meaning we only ever break on a force-break node
+ var splitHere = false;
+ while($pullOutHere[0].childNodes.length) {
+ var next = $($pullOutHere[0].childNodes[0]);
+ splitHere = next.hasClass('force-break');
+ if (splitHere) break;
+ var splitUnder = next.find('force-break').length != 0;
+ if (splitUnder) break;
+ $putInHere.append(next); // Because we're not cloning, jquery will actually move the element
+ }
+ if (splitHere) {
+ $($pullOutHere[0].childNodes[0]).remove();
+ return true; // No further splits needs
+ }
+ return false; // Will need to go down to split recursively
+ } else{
+ while($parentColumn.height() < height && $pullOutHere[0].childNodes.length) {
+ $putInHere.append($pullOutHere[0].childNodes[0]); // Because we're not cloning, jquery will actually move the element
+ }
}
if($putInHere[0].childNodes.length == 0) return false;
@@ -190,27 +210,29 @@
- if($clone.is("img") && $parentColumn.height() < height + 20){ // Images are easy to handle, just shift them
+ if((options.explicitBreaks) && ($clone.hasClass('force-break'))) { // Explicit break
+ $cloneMe.remove();
+ } else if((!options.explicitBreaks) && ($clone.is("img") && $parentColumn.height() < height + 20)) { // Images are easy to handle, just shift them
$cloneMe.remove();
- }else if(!dontsplit && $parentColumn.height() < height + 20){ // If this is a viable split point, do it
+ }else if((!options.explicitBreaks) && (!dontsplit && $parentColumn.height() < height + 20)) { // If this is a viable split point, do it
$cloneMe.remove(); // Remove from from
- }else if($clone.is("img") || dontsplit){ // Can't split, we'll just have to let it all stay where it is
+ }else if((!options.explicitBreaks) && ($clone.is("img") || dontsplit)) { // Can't split, we'll just have to let it all stay where it is
$clone.remove(); // Remove from to (i.e. undo copy). Stays at from.
@@ -228,9 +230,13 @@
}else{ // Look deeper for split point
$clone.empty();
if(!columnize($clone, $cloneMe, $parentColumn, height)) {
- if($cloneMe.children().length) {
+ if($cloneMe.children().length != 0 ) {
split($clone, $cloneMe, $parentColumn, height);
}
+ } else {
+ // Case where explicit break might be at end of list item, we need to not copy over shell of this list item
+ if ((options.explicitBreaks) && ($cloneMe[0].nodeName.toLowerCase()=='li') && ($cloneMe[0].childNodes.length == 1) && ($cloneMe[0].childNodes[0].nodeType == 3) && ($cloneMe[0].childNodes[0].nodeValue.replace(/\s*/g,'') == ''))
+ $cloneMe.first().remove();
}
if($clone.get(0).childNodes.length == 0) {
// it was split, but nothing is in it :(. No deeper to go.
@@ -311,7 +317,7 @@
var needsDeepSplit = !columnize($col, $destroyable, $col, targetHeight);
if (needsDeepSplit) {
// do a split, but only if the last item in the column isn't a "dontend"
- if(!$destroyable.contents().find(":first-child").hasClass("dontend")) {
+ if(options.explicitBreaks || !$destroyable.contents().find(":first-child").hasClass("dontend")) {
split($col/*put in here*/, $destroyable/*pull out here*/, $col, targetHeight);
}else{
// alert("not splitting a dontend");
@@ -278,43 +299,46 @@
- // Any "dontend" stuff needs to be yonked off our current column and put back onto the start of $destroyable. Loop whilst we need to keep doing this.
- while(checkDontEndColumnOnConstraints($col.contents(":last").length != 0 && $col.contents(":last").get(0))){
- var $lastKid = $col.contents(":last");
- $lastKid.remove();
- $destroyable.prepend($lastKid);
+
+ if (!options.explicitBreaks) {
+ // Any "dontend" stuff needs to be yonked off our current column and put back onto the start of $destroyable. Loop whilst we need to keep doing this.
+ while(checkDontEndColumnOnConstraints($col.contents(":last").length != 0 && $col.contents(":last").get(0))) {
+ var $lastKid = $col.contents(":last");
+ $lastKid.remove();
+ $destroyable.prepend($lastKid);
+ }
That patch isn't going to apply. I ran it off from my own (hopefully temporary) fork of columnizer, but I manually chopped it about a bit. But the changes here work if applied manually.