{"id":240,"date":"2009-08-12T15:25:34","date_gmt":"2009-08-12T23:25:34","guid":{"rendered":"http:\/\/www.zackgrossbart.com\/hackito\/?p=240"},"modified":"2014-05-22T13:11:52","modified_gmt":"2014-05-22T21:11:52","slug":"slidegrid","status":"publish","type":"post","link":"https:\/\/www.zackgrossbart.com\/hackito\/slidegrid\/","title":{"rendered":"Create Your Own Sliding Resizable Grid"},"content":{"rendered":"<p><a href=\"https:\/\/github.com\/zgrossbart\/slidegrid\"><img decoding=\"async\" style=\"position: absolute; top: 0; right: 0; border: 0;\" src=\"https:\/\/camo.githubusercontent.com\/38ef81f8aca64bb9a64448d0d70f1308ef5341ab\/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67\" alt=\"Fork me on GitHub\"><\/a><\/p>\n<p>\n    I&#8217;ve focused on web programming for a while now, but I still miss <a href=\"http:\/\/java.sun.com\/docs\/books\/tutorial\/uiswing\/layout\/gridbag.html\">GridBagLayout<\/a>.  GridBag is a Java <a href=\"http:\/\/en.wikipedia.org\/wiki\/Layout_manager\">layout manager<\/a> and one of the best form layout managers I&#8217;ve used in any language.  It makes it possible to create forms where any screen size is the perfect size.\n<\/p>\n<p>\n    There are a few different layout managers you can use with JavaScript, but they are mostly simple.  I tend to skip them and just do the layout by hand using CSS.  That&#8217;s why I was so excited when I saw the website for the English design firm <a href=\"http:\/\/www.zaum.co.uk\/\">Zaum &#038; Brown<\/a>.  If you follow the link resize your browser window after the page loads.\n<\/p>\n<div class=\"sourcebox\">\n    See it<br \/><a href=\"http:\/\/zgrossbart.github.io\/slidegrid\/\"> in Action<\/a>\n<\/div>\n<p>\n    Your browser window is always the perfect size for the Zaum &#038; Brown website.  I really liked the effect so I&#8217;ve created an improved and simplified version of a <a href=\"\/slidegrid\">sliding resizable grid<\/a> and released it under the <a href=\"http:\/\/www.apache.org\/licenses\/LICENSE-2.0\">Apache License 2.0<\/a>.\n<\/p>\n<h2>The HTML<\/h2>\n<p>\n    The HTML for this grid is very simple.  It uses three classes, <code>slidegrid<\/code>, <code>cell<\/code>, and <code>bigcell<\/code>.  Check it out:\n<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">&lt;div class=\"slidegrid\"&gt;\r\n    &lt;div class=\"cell bigcell\"&gt;Big Cell 1&lt;\/div&gt;\r\n    &lt;div class=\"cell\"&gt;Cell 2&lt;\/div&gt;\r\n    &lt;div class=\"cell\"&gt;Cell 3&lt;\/div&gt;\r\n    &lt;div class=\"cell\"&gt;Cell 4&lt;\/div&gt;\r\n    ...\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n    The grid starts with the <code>slidegrid<\/code> class.  This class is just a marker for the JavaScript code in <a href=\"\/slidegrid\/slidegrid.js\">slidegrid.js<\/a>.  After it finds <code>slidegrid<\/code> the JavaScript looks for <code>cell<\/code> classes underneath the <code>slidegrid<\/code>.  I made mine <code>div<\/code> tags, but they could contain any other content.\n<\/p>\n<p>\n    <code>slidegrid<\/code> and <code>cell<\/code> would be enough for something simple, but I wanted to get a little fancy so I added the <code>bigcell<\/code> class.  Every <i>big cell<\/i> is twice as large as a normal cell.\n<\/p>\n<h2>The JavaScript<\/h2>\n<div class=\"sourcebox\">\n    Get the <br \/><a href=\"https:\/\/github.com\/zgrossbart\/slidegrid\">source code<\/a>\n<\/div>\n<p>\n    The JavaScript for this code is also relatively simple, and much of the credit for that goes to <a href=\"http:\/\/www.jquery.com\">JQuery<\/a>.  The most important function here is <code>alignGrid<\/code>.  It does all the heavy lifting of iterating through the <code>div<\/code> tags and lining them up in the grid.\n<\/p>\n<p>\n    Here&#8217;s a simplified version of the function.  There is some extra handling in the real code for big cells, but I&#8217;ll let you find that on your own.\n<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">jQuery(\".slidegrid\").each(function() {\r\n        \r\n    var cols = Math.floor($(window).width() \/ ((cellWidth + padding) * \r\n        getComputedEm(jQuery(this))));\r\n    \r\n    jQuery(this).css(\"position\", \"relative\");\r\n    \r\n    var children = jQuery(this).children(\"div\");\r\n    \r\n    for (var i = 0; i < children.length; i++) {\r\n        \r\n        styleCell(children.eq(i), x, y, cellWidth, cellHeight, hasDrawn);\r\n    }\r\n    \r\n    if ((count % cols) == 0) {\r\n        <span class=\"code_comment\">\r\n        \/* \r\n         * This means it is time to bump down to the next row\r\n         *\/\r\n         <\/span>\r\n        curCol = 0;\r\n        curRow++;\r\n        x = 0;\r\n        y += cellHeight + padding;\r\n    } else {\r\n        x += cellWidth + padding;\r\n        curCol++;\r\n    }\r\n    \r\n    count++;\r\n});<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n    When you resize the page we&#8217;re using an animation effect to show the cells moving.  The animation is defined in the <code>styleCell<\/code> function.  JQuery makes custom animation effects very easy so this function is very small.\n<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">function styleCell(cell, x, y, cellWidth, cellHeight, <span class=\"code_comment\">\/*boolean*\/<\/span>animate) {\r\n    if (animate) {\r\n        <span class=\"code_comment\">\/*\r\n         * We only want to do the animation when the resize happens.\r\n         *\/<\/span>\r\n        cell.animate({ \r\n            left: x + \"em\",\r\n            top: y + \"em\"\r\n            }, 500, \"swing\" );\r\n    } else {\r\n        cell.css({\r\n            width: cellWidth + \"em\",\r\n            height: cellHeight + \"em\",\r\n            position: \"absolute\",\r\n            left: x + \"em\",\r\n            top: y + \"em\"\r\n        });\r\n    }\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n    The last step is to make sure we redo the layout of the grid when the window is resized.  For that we add a little bit of code to the document&#8217;s <code>ready<\/code> function.\n<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">\r\n$(document).ready(function() {\r\n    alignGrid(10, 10, 1);\r\n    \r\n    <span class=\"code_comment\">\/*\r\n     * Redraw the grid when the page size changes\r\n     *\/<\/span>\r\n    $(window).bind(\"resize\", resizeWindow);\r\n    function resizeWindow(e) {\r\n        var newWindowHeight = $(window).height();\r\n        alignGrid(10, 10, 1);\r\n    }\r\n});\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n    This makes sure we align the grid the first time and then change it whenever the window is resized.  That is really all it takes.\n<\/p>\n<h2>Get Creative<\/h2>\n<p>\n    This is a simple mechanism, but it is powerful. The <code>div<\/code> tags are flexible enough to add almost any content.  Please make use of this code and post a comment if you do so we can all check it out.\n<\/p>\n<p>\n    &hellip;and maybe one day I&#8217;ll feel ambitious enough to try to write GridBagLayout for JavaScript.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve focused on web programming for a while now, but I still miss GridBagLayout. GridBag is a Java layout manager and one of the best form layout managers I&#8217;ve used in any language. It makes it possible to create forms where any screen size is the perfect size. There are a few different layout managers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,7,21,20],"tags":[],"_links":{"self":[{"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/240"}],"collection":[{"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/comments?post=240"}],"version-history":[{"count":26,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/240\/revisions"}],"predecessor-version":[{"id":1174,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/240\/revisions\/1174"}],"wp:attachment":[{"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/media?parent=240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/categories?post=240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/tags?post=240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}