BulkUpdater work.
[order_line_extra.git] / TableDnD / index.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2         "http://www.w3.org/TR/html4/loose.dtd">
3 <html>
4 <head>
5     <title>Table Drag and Drop jQuery plugin</title>
6     <link rel="stylesheet" href="tablednd.css" type="text/css"/>
7     <link rel="stylesheet" href="//google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" type="text/css"/>
8 </head>
9 <body>
10 <div id="page">
11 <h1>Table Drag and Drop jQuery plugin</h1>
12 <p>This page contains documentation and tests for the TableDnD jQuery plug-in. For more information and
13 to post comments, please go to <a href="http://www.isocra.com/2008/02/table-drag-and-drop-jquery-plugin/">isocra.com</a>.
14 </p>
15 <p>If you have issues or bug reports, then you can post them at the <a href="http://plugins.jquery.com/project/issues/TableDnD">TableDnD plug page</a>
16 at plugins.jquery.com</p>
17
18 <h2>How do I use it?</h2>
19 <ol>
20         <li>Since TableDnD is a jquery pligin you will need to include jquery in your page first.
21     <p>No need for any downloads simply reference <a href="https://developers.google.com/speed/libraries/devguide#jquery">jQuery from the Google CDN</a> (Content Distribution Network) At the time of this writing the latest release was 1.8.2.
22     All scripts are included at the bottom of the page, to facilitate quicker rendering of the HTML for more responsive pages.
23     The following is the way we are linking to jQuery in the examples and this method can be recommended for use in your implementations too.</p>
24     <pre class="prettyprint">&lt;script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"&gt;&lt;/script&gt;</pre></li>
25     <li>We will also need a copy of the <a href="/articles/jquery.tablednd.js.zip">TableDnD plugin</a> (current version 0.9) which you can reference in the normal fashion, anywhere after jQuery.</li>
26         <li>In true jQuery style, the typical way to initialise the tabes is in the <code class="prettyprint">$(document).ready</code> code black function. Use a selector to select your table and then call <code class="prettyprint">tableDnD()</code>. You can optionally specify a set of properties (described below).</li>
27 </ol>
28
29 <h2>A basic table</h2>
30 <div class="tableDemo">
31 <div id="debug" style="float:right;"></div>
32 <table id="table-1" cellspacing="0" cellpadding="2">
33     <tr id="1"><td>1</td><td>One</td><td>some text</td></tr>
34     <tr id="2"><td>2</td><td>Two</td><td>some text</td></tr>
35     <tr id="3"><td>3</td><td>Three</td><td>some text</td></tr>
36     <tr id="4"><td>4</td><td>Four</td><td>some text</td></tr>
37     <tr id="5"><td>5</td><td>Five</td><td>some text</td></tr>
38     <tr id="6"><td>6</td><td>Six</td><td>some text</td></tr>
39 </table>
40 </div>
41 <p>The HTML for the table is very straight forward (no Javascript, pure HTML):</p>
42
43 <pre class="prettyprint">
44 &lt;table id=&quot;table-1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot;&gt;
45     &lt;tr id=&quot;1&quot;&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;One&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
46     &lt;tr id=&quot;2&quot;&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Two&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
47     &lt;tr id=&quot;3&quot;&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Three&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
48     &lt;tr id=&quot;4&quot;&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Four&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
49     &lt;tr id=&quot;5&quot;&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Five&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
50     &lt;tr id=&quot;6&quot;&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Six&lt;/td&gt;&lt;td&gt;some text&lt;/td&gt;&lt;/tr&gt;
51 &lt;/table&gt;
52 </pre>
53 <p>To add in the "draggability" all we need to do is add a line to the <code class="prettyprint">$(document).ready(...)</code> function
54 as follows:</p>
55 <pre class="prettyprint">
56 <span class="comment">&lt;script type=&quot;text/javascript&quot;&gt;</span>
57 $(document).ready(function() {
58     <span class="comment">// Initialise the table</span>
59     $(&quot;#table-1&quot;).tableDnD();
60 });
61 <span class="comment">&lt;/script&gt;</span>
62 </pre>
63 <p>In the example above we're not setting any parameters at all so we get the default settings. There are a number
64         of parameters you can set in order to control the look and feel of the table and also to add custom behaviour
65         on drag or on drop. The parameters are specified as a map in the usual way and are described below:</p>
66
67 <h2>Settings</h2>
68 <dl>
69         <dt>onDragStyle</dt>
70         <dd>This is the style that is assigned to the row during drag. There are limitations to the styles that can be
71                 associated with a row (such as you can't assign a border&mdash;well you can, but it won't be
72                 displayed). (So instead consider using <code class="prettyprint">onDragClass</code>.) The CSS style to apply is specified as
73                 a map (as used in the jQuery <code class="prettyprint">css(...)</code> function).</dd>
74         <dt>onDropStyle</dt>
75         <dd>This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations
76                 to what you can do. Also this replaces the original style, so again consider using onDragClass which
77                 is simply added and then removed on drop.</dd>
78         <dt>onDragClass</dt>
79         <dd>This class is added for the duration of the drag and then removed when the row is dropped. It is more
80                 flexible than using onDragStyle since it can be inherited by the row cells and other content. The default
81                 is class is <code class="prettyprint">tDnD_whileDrag</code>. So to use the default, simply customise this CSS class in your
82                 stylesheet.</dd>
83         <dt>onDrop</dt>
84         <dd>Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table
85             and the row that was dropped. You can work out the new order of the rows by using
86             <code class="prettyprint">table.tBodies[0].rows</code>.</dd>
87         <dt>onDragStart</dt>
88         <dd>Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the
89                 table and the row which the user has started to drag.</dd>
90         <dt>scrollAmount</dt>
91         <dd>This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the
92                 window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2,
93                 FF3 beta)</dd>
94 </dl>
95
96 <h2>OnDrag custom table</h2>
97 <p>This second table has has an onDrop function applied as well as an onDragClass. The javascript to set this up is
98 as follows:</p>
99
100 <pre class="prettyprint">
101 $(document).ready(function() {
102
103         // Initialise the first table (as before)
104         $("#table-1").tableDnD();
105
106         // Make a nice striped effect on the table
107         $("#table-2 tr:even').addClass('alt')");
108
109         // Initialise the second table specifying a dragClass and an onDrop function that will display an alert
110         $("#table-2").tableDnD({
111             onDragClass: "myDragClass",
112             onDrop: function(table, row) {
113             var rows = table.tBodies[0].rows;
114             var debugStr = "Row dropped was "+row.id+". New order: ";
115             for (var i=0; i&lt;rows.length; i++) {
116                 debugStr += rows[i].id+" ";
117             }
118                 $(table).parent().find('.result').text(debugStr);
119             },
120                 onDragStart: function(table, row) {
121                         $(table).parent().find('.result').text("Started dragging row "+row.id);
122                 }
123         });
124 });
125 </pre>
126 <div class="tableDemo">
127 <table id="table-2" cellspacing="0" cellpadding="0">
128     <tr id="2.1"><td>1</td><td>One</td><td><input type="text" name="one" value="one"/></td><td><input type="radio" name="rone" value="V" />V</td><td><input type="radio" name="rone" value="C" checked="checked" />C</td><td><input type="radio" name="rone" value="N" />N</td></tr>
129     <tr id="2.2"><td>2</td><td>Two</td><td><input type="text" name="two" value="two"/></td><td><input type="radio" name="rtwo" value="V" />V</td><td><input type="radio" name="rtwo" value="C" checked="checked" />C</td><td><input type="radio" name="rtwo" value="N" />N</td></tr>
130     <tr id="2.3"><td>3</td><td>Three</td><td><input type="text" name="three" value="three"/></td><td><input type="radio" name="rthree" value="V" />V</td><td><input type="radio" name="rthree" value="C" checked="checked" />C</td><td><input type="radio" name="rthree" value="N" />N</td></tr>
131     <tr id="2.4"><td>4</td><td>Four</td><td><input type="text" name="four" value="four"/></td><td><input type="radio" name="rfour" value="V" />V</td><td><input type="radio" name="rfour" value="C" checked="checked" />C</td><td><input type="radio" name="rfour" value="N" />N</td></tr>
132     <tr id="2.5"><td>5</td><td>Five</td><td><input type="text" name="five" value="five"/></td><td><input type="radio" name="rfive" value="V" />V</td><td><input type="radio" name="rfive" value="C" checked="checked" />C</td><td><input type="radio" name="rfive" value="N" />N</td></tr>
133     <tr id="2.6"><td>6</td><td>Six</td><td><input type="text" name="six" value="six"/></td><td><input type="radio" name="rsix" value="V" />V</td><td><input type="radio" name="rsix" value="C" checked="checked" />C</td><td><input type="radio" name="rsix" value="N" />N</td></tr>
134     <tr id="2.7"><td>7</td><td>Seven</td><td><input type="text" name="seven" value="7"/></td><td><input type="radio" name="rseven" value="V" />V</td><td><input type="radio" name="rseven" value="C" checked="checked" />C</td><td><input type="radio" name="rseven" value="N" />N</td></tr>
135     <tr id="2.8"><td>8</td><td>Eight</td><td><input type="text" name="eight" value="8"/></td><td><input type="radio" name="reight" value="V" />V</td><td><input type="radio" name="reight" value="C" checked="checked" />C</td><td><input type="radio" name="reight" value="N" />N</td></tr>
136     <tr id="2.9"><td>9</td><td>Nine</td><td><input type="text" name="nine" value="9"/></td><td><input type="radio" name="rnine" value="V" />V</td><td><input type="radio" name="rnine" value="C" checked="checked" />C</td><td><input type="radio" name="rnine" value="N" />N</td></tr>
137     <tr id="2.10"><td>10</td><td>Ten</td><td><input type="text" name="ten" value="10"/></td><td><input type="radio" name="rten" value="V" />V</td><td><input type="radio" name="rten" value="C" checked="checked" />C</td><td><input type="radio" name="rten" value="N" />N</td></tr>
138     <tr id="2.11"><td>11</td><td>Eleven</td><td><input type="text" name="eleven" value="11"/></td><td><input type="radio" name="releven" value="V" />V</td><td><input type="radio" name="releven" value="C" checked="checked" />C</td><td><input type="radio" name="releven" value="N" />N</td></tr>
139     <tr id="2.12"><td>12</td><td>Twelve</td><td><input type="text" name="twelve" value="12"/></td><td><input type="radio" name="rtwelve" value="V" />V</td><td><input type="radio" name="rtwelve" value="C" checked="checked" />C</td><td><input type="radio" name="rtwelve" value="N" />N</td></tr>
140     <tr id="2.13"><td>13</td><td>Thirteen</td><td><input type="text" name="thirteen" value="13"/></td><td><input type="radio" name="rthirteen" value="V" />V</td><td><input type="radio" name="rthirteen" value="C" checked="checked" />C</td><td><input type="radio" name="rthirteen" value="N" />N</td></tr>
141     <tr id="2.14"><td>14</td><td>Fourteen</td><td><input type="text" name="fourteen" value="14"/></td><td><input type="radio" name="rfourteen" value="V" />V</td><td><input type="radio" name="cfourteen" value="C" checked="checked" />C</td><td><input type="radio" name="rfourteen" value="N" />N</td></tr>
142 </table>
143     <div class="result">&nbsp;</div>
144 </div>
145 <h2>Communicating with the back-end</h2>
146 <p>Generally once the user has dropped a row, you need to inform the server of the new order. To do this, we've
147         added a method called <code class="prettyprint">serialize()</code>. It takes no parameters but knows the current table from the
148         context. The method returns a string of the form <code class="prettyprint"><i>tableId</i>[]=<i>rowId1</i>&amp;<i>tableId</i>[]=<i>rowId2</i>&amp;<i>tableId</i>[]=<i>rowId3</i>...</code>
149         You can then use this as part of an Ajax load.
150 </p>
151 <p>
152     Since version 0.9, instead of manually creating the serialized data string we instead use <a href="http://api.jquery.com/jQuery.param/">jQuery's param method</a> which has the added benefit of url encoding the data string as well.
153 </p>
154 <p>This third table demonstrates calling the serialize function inside onDrop (as shown below). It also
155         demonstrates the "nodrop" class on row 3 and "nodrag" class on row 5, so you can't pick up row 5 and
156         you can't drop any row on row 3 (but you can drag it).</p>
157 <pre class="prettyprint">
158     $('#table-3').tableDnD({
159         onDrop: function(table, row) {
160             alert($.tableDnD.serialize());
161         }
162     });
163 </pre>
164 <div class="tableDemo">
165 <div id="AjaxResult" style="float: right; width: 250px; border: 1px solid silver; padding: 4px; font-size: 90%">
166         <h3>Ajax result</h3>
167         <p>Drag and drop in this table to test out serialise and using JQuery.load()</p>
168 </div>
169 <table id="table-3" cellspacing="0" cellpadding="2">
170     <tr id="3.1"><td>1</td><td>One</td><td><input type="text" name="one" value="one"/></td></tr>
171     <tr id="3.2"><td>2</td><td>Two</td><td><input type="text" name="two" value="two"/></td></tr>
172     <tr id="3.3" class="nodrop"><td>3</td><td>Three (Can't drop on this row)</td><td><input type="text" name="three" value="three"/></td></tr>
173     <tr id="3.4" class="nodrop"><td>4</td><td>Four (Can't drop on this row)</td><td><input type="text" name="four" value="four"/></td></tr>
174     <tr id="3.5"><td>5</td><td>Five</td><td><input type="text" name="five" value="five"/></td></tr>
175     <tr id="3.6" class="nodrag"><td>6</td><td>Six (Can't drag this row)</td><td><input type="text" name="six" value="six"/></td></tr>
176     <tr id="3.7"><td>7</td><td>Seven</td><td><input type="text" name="seven" value="seven"/></td></tr>
177 </table>
178     <div class="result"></div>
179 </div>
180 <h2>Multiple tbody table</h2>
181 <p>This table has multiple TBODYs. The functionality isn't quite working properly. You can only drag the rows inside their
182 own TBODY, you can't drag them outside it. Now this might or might not be what you want, but unfortunately if you then drop a row outside its TBODY you get a Javascript error because inserting after a sibling doesn't work. This will be fixed in the next version. The header rows all have the classes "nodrop" and "nodrag" so that they can't be dragged or dropped on.</p>
183 <div class="tableDemo">
184 <table id="table-4" cellspacing="0" cellpadding="2">
185         <thead>
186                 <tr id="4.0" class="nodrop nodrag"><th>H1</th><th>H2</th><th>H3</th></tr>
187         </thead>
188         <tbody>
189         <tr id="4.1"><td>4.1</td><td>One</td><td><input type="text" name="one" value="one"/></td></tr>
190         <tr id="4.2"><td>4.2</td><td>Two</td><td><input type="text" name="two" value="two"/></td></tr>
191         <tr id="4.3"><td>4.3</td><td>Three</td><td><input type="text" name="three" value="three"/></td></tr>
192         <tr id="4.4"><td>4.4</td><td>Four</td><td><input type="text" name="four" value="four"/></td></tr>
193         <tr id="4.5"><td>4.5</td><td>Five</td><td><input type="text" name="five" value="five"/></td></tr>
194         <tr id="4.6"><td>4.6</td><td>Six</td><td><input type="text" name="six" value="six"/></td></tr>
195         </tbody>
196         <tbody>
197                 <tr id="5.0" class="nodrop nodrag"><th>H1</th><th>H2</th><th>H3</th></tr>
198         <tr id="5.1"><td>5.1</td><td>One</td><td><input type="text" name="one" value="one"/></td></tr>
199         <tr id="5.2"><td>5.2</td><td>Two</td><td><input type="text" name="two" value="two"/></td></tr>
200         <tr id="5.3"><td>5.3</td><td>Three</td><td><input type="text" name="three" value="three"/></td></tr>
201         <tr id="5.4"><td>5.4</td><td>Four</td><td><input type="text" name="four" value="four"/></td></tr>
202         <tr id="5.5"><td>5.5</td><td>Five</td><td><input type="text" name="five" value="five"/></td></tr>
203         <tr id="5.6"><td>5.6</td><td>Six</td><td><input type="text" name="six" value="six"/></td></tr>
204         </tbody>
205         <tbody>
206                 <tr id="6.0" class="nodrop nodrag"><th>H1</th><th>H2</th><th>H3</th></tr>
207         <tr id="6.1"><td>6.1</td><td>One</td><td><input type="text" name="one" value="one"/></td></tr>
208         <tr id="6.2"><td>6.2</td><td>Two</td><td><input type="text" name="two" value="two"/></td></tr>
209         <tr id="6.3"><td>6.3</td><td>Three</td><td><input type="text" name="three" value="three"/></td></tr>
210         <tr id="6.4"><td>6.4</td><td>Four</td><td><input type="text" name="four" value="four"/></td></tr>
211         <tr id="6.5"><td>6.5</td><td>Five</td><td><input type="text" name="five" value="five"/></td></tr>
212         <tr id="6.6"><td>6.6</td><td>Six</td><td><input type="text" name="six" value="six"/></td></tr>
213         </tbody>
214 </table>
215 </div>
216 <h2>Identify rows</h2>
217 <p>
218 The following table demonstrates the use of the default regular expression. The rows have IDs of the
219 form table5-row-1, table5-row-2, etc., but the regular expression is <code class="prettyprint">/[^\-]*$/</code> (this is the same
220 as used in the <a href="http://plugins.jquery.com/project/NestedSortable">NestedSortable</a> plugin for consistency).
221 This removes everything before and including the last hyphen, so the serialised string just has 1, 2, 3 etc.
222 You can replace the regular expression by setting the <code class="prettyprint">serializeRegexp</code> option, you can also just set it
223 to null to stop this behaviour.
224 </p>
225 <pre class="prettyprint">
226     $('#table-5').tableDnD({
227         onDrop: function(table, row) {
228             alert($.tableDnD.serialize());
229         },
230         dragHandle: ".dragHandle"
231     });
232 </pre>
233 <div class="tableDemo">
234 <table id="table-5" cellspacing="0" cellpadding="2">
235     <tr id="table5-row-1"><td class="dragHandle">&nbsp;</td><td>1</td><td>One</td><td>some text</td></tr>
236     <tr id="table5-row-2"><td class="dragHandle">&nbsp;</td><td>2</td><td>Two</td><td>some text</td></tr>
237     <tr id="table5-row-3"><td class="dragHandle">&nbsp;</td><td>3</td><td>Three</td><td>some text</td></tr>
238     <tr id="table5-row-4"><td class="dragHandle">&nbsp;</td><td>4</td><td>Four</td><td>some text</td></tr>
239     <tr id="table5-row-5"><td class="dragHandle">&nbsp;</td><td>5</td><td>Five</td><td>some text</td></tr>
240     <tr id="table5-row-6"><td class="dragHandle">&nbsp;</td><td>6</td><td>Six</td><td>some text</td></tr>
241 </table>
242     <div class="result"></div>
243 </div>
244 <p>In fact you will notice that I have also set the dragHandle on this table. This has two effects: firstly only
245 the cell with the drag handle class is draggable and secondly it doesn't automatically add the <code class="prettyprint">cursor: move</code>
246 style to the row (or the drag handle cell), so you are responsible for setting up the style as you see fit.</p>
247 <p>Here I've actually added an extra effect which adds a background image to the first cell in the row whenever
248 you enter it using the jQuery <code class="prettyprint">hover</code> function as follows:</p>
249 <pre class="prettyprint">
250     $("#table-5 tr").hover(function() {
251           $(this.cells[0]).addClass('showDragHandle');
252     }, function() {
253           $(this.cells[0]).removeClass('showDragHandle');
254     });
255 </pre>
256 <p>This provides a better visualisation of what you can do to the row and where you need to go to drag it (I hope).</p>
257
258 <h2>Meta table (auto configure)</h2>
259
260 <script type="text/javascript">
261     function inline_sprintlist_ondrop(table, row) {
262         var result = $(table).parent().find('.result'),
263             pre = $('<pre class="prettyprint">');
264
265         result.html(pre.text($.tableDnD.jsonize(true)));
266         prettyPrint();
267 //            pre.text($(table).tableDnD.jsonize())
268 //        return true;
269         //// '<div class="indent">&nbsp;</div>',
270     }
271 </script>
272 <div class="tableDemo">
273
274 <table id="table-6"
275        data-table="dnd"
276        cellspacing="0"
277        cellpadding="2"
278        style=""
279
280
281        data-ondragstyle="display: block; z-index: 5; background-color: #7777cc;"
282
283        data-ondragclass=""
284     >
285     <tr id="6-1"><td>Basic example with extra fancy</td></tr>
286     <tr id="6-2"><td>row styles bot this trick really</td></tr>
287     <tr id="6-3"><td>only works with single column</td></tr>
288     <tr id="6-4"><td>because it looses the corumn</td></tr>
289     <tr id="6-5"><td>width when displaying a table</td></tr>
290     <tr id="6-6"><td>in block style unfortunately</td></tr>
291 </table>
292
293 <table
294         id="sprintlist_table"
295         cellspacing="0" cellpadding="10"
296         data-table="dnd"
297         data-ondragstart="$(table).parent().find('.result').text('data-ondragstart');"
298         data-ondrop="inline_sprintlist_ondrop(table, row);"
299         data-serializeregexp="^.*sprints$|[^\_]*$"
300         data-ondragclass="sprintlist-drag"
301         data-ondragstyle=""
302         data-ondropstyle=""
303         data-scrollamount="100"
304         data-sensitivity="1"
305         data-hierarchylevel="2"
306         data-indentartifact="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
307         data-autowidthadjust="1"
308         data-autocleanrelations="1"
309         data-jsonpretifyseparator="    "
310         data-serializeparamname="sprintlist"
311         data-draghandle=""
312
313     >
314     <thead id="sprintlist_header">
315         <tr><th class="name">Name</th><th class="start_date">Start Date</th><th class="end_date">End Date</th><th class="actions">Actions</th></tr>
316     </thead>
317     <tbody>
318         <tr id="present_sprints" class="group_heading nodrag"><td colspan="4">Present Sprints</td></tr>
319         <tr id="sprint_145664"><td>First round - in sprint</td><td>2012-09-19</td><td>2012-09-27</td>
320             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
321         <tr id="future_sprints" class="group_heading nodrag"><td colspan="4">Future Sprints</td></tr>
322         <tr id="sprint_145665" class="toggler_row"><td>Second round</td><td>2012-09-28</td><td>2012-10-04</td>
323             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
324         <tr id="sprint_145975" class="toggler_row"><td>Third round</td><td>2012-10-04</td><td>2012-10-11</td>
325             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
326         <tr id="sprint_145965" class="toggler_row"><td>Fourth round</td><td>2012-10-13</td><td>2012-10-20</td>
327             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
328         <tr id="sprint_145966" class="toggler_row"><td>Release prep</td><td>2012-10-20</td><td>2012-10-27</td>
329             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
330         <tr id="sprint_145964" class="toggler_row"><td>Fifth run</td><td>2012-10-27</td><td>2012-11-03</td>
331             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
332         <tr id="sprint_145974" class="toggler_row"><td>Sixth run</td><td>2012-11-03</td><td>2012-11-10</td>
333         <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
334         <tr id="sprint_145985" class="toggler_row"><td>Seventh run</td><td>2012-11-10</td><td>2012-11-17</td>
335             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
336         <tr id="sprint_145976" class="toggler_row"><td>Release 2 prep</td><td>2012-11-17</td><td>2012-11-24</td>
337             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
338         <tr id="past_sprints" class="group_heading nodrag"><td colspan="4">Past Sprints</td></tr>
339         <tr id="sprint_145996" class="toggler_row"><td>Backlog creation - complete</td><td>2012-09-01</td><td>2012-09-08</td>
340             <td class="small_buttons"><div><button onclick="return false;">Edit</button><button onclick="return false;">Delete</button></div></td></tr>
341         <tr id="no_sprints" class="group_heading nodrag"><td colspan="4">No Sprints</td></tr>
342     </tbody>
343 </table>
344   <a class="toggle-json6" href="#">Hide JSON</a><div id="json6" class="result"></div>
345 </div>
346
347 <h2>Hierarchy table</h2>
348 <p>This table allows row order to be dragged horizontally and placed in a hierarchy under a parent row (since version 0.9). We also get a chance to look at the new jsonize method for JSON serialized form of the data. </p>
349 <p>In the onDrop event handler we pass the JSON as data to jquery through a HTTP POST ajax call to the server:</p>
350 <pre class="prettyprint">
351     $.post("server/ajaxJSONTest.php", $.tableDnD.jsonize(), function (data) {
352         $('#table-7-response').html('<br>'+ data);
353     });
354 </pre>
355 <p>On the back-end we have a PHP example that simply retrieves the JSON POST data from the built in stream php://input, decodes the payload and proceeds to build the hierarchy through recursion.</p>
356 <p>To keep the data simple and also stay compatible with the http variable methods as mentioned previously the data structure is formed with separate collections. If a parent has children the children first level are listed and if any of the children have subsequent children an additional collection is created for the first level of these.</p>
357 <p>The following hierarchy for example would generate 3 collections:</p>
358 <ul>
359     <li>7.00 <ul>
360         <li>7.01</li>
361         <li>7.02<ul><li>7.03</li></ul></li>
362     </ul></li>
363     <li>7.04</li>
364 </ul>
365 <p>In JSON the dataset looks like this:</p>
366 <a class="toggle-json7" href="#">Hide JSON</a><pre id="json7" class="prettyprint">
367 {
368         "table-7": [
369                 "7.00",
370                 "7.04"
371         ],
372         "7.00": [
373                 "7.01",
374                 "7.02"
375         ],
376         "7.02": [
377                 "7.03"
378         ]
379 }
380 </pre>
381 <p>We use the setting hierarchyLevel to indicate how many levels are supported, the example uses 4 levels deep. When populating the table you can use the the data-leve tag to indicate at which level the current row is represented at.</p>
382
383 <div class="hierarchyDemo">
384     <div style="float: right; width: 450px; border: 1px solid silver; padding: 4px; font-size: 90%">
385         <div id="table-7-response" style="float: right; margin-left: 20px">
386             <h3>Ajax result</h3>
387             <p>Drag and drop in this table to test out hierarcies and using JSON payload.</p>
388         </div>
389     </div>
390
391     <table id="table-7" cellspacing="0" cellpadding="2">
392         <tr id="7.00">               <td>7.0 One</td><td><input type="text" name="one" value="one"/></td></tr>
393         <tr id="7.01" data-level="1"><td>7.1 Two</td><td><input type="text" name="two" value="two"/></td></tr>
394         <tr id="7.02" data-level="1"><td>7.2 Three</td><td><input type="text" name="three" value="three"/></td></tr>
395         <tr id="7.03" data-level="2"><td>7.3 Four</td><td><input type="text" name="four" value="four"/></td></tr>
396         <tr id="7.04">               <td>7.4 Five</td><td><input type="text" name="five" value="five"/></td></tr>
397         <tr id="7.05" data-level="1"><td>7.5 Six</td><td><input type="text" name="six" value="six"/></td></tr>
398         <tr id="7.06" data-level="2"><td>7.6 Seven</td><td><input type="text" name="seven" value="seven"/></td></tr>
399         <tr id="7.07" data-level="3"><td>7.7 Eight</td><td><input type="text" name="eight" value="eight"/></td></tr>
400         <tr id="7.08" data-level="4"><td>7.8 Nine</td><td><input type="text" name="nine" value="nine"/></td></tr>
401         <tr id="7.09" data-level="2"><td>7.9 Ten</td><td><input type="text" name="ten" value="ten"/></td></tr>
402         <tr id="7.10" data-level="2"><td>7.0 One</td><td><input type="text" name="one" value="one"/></td></tr>
403         <tr id="7.11">               <td>7.1 Two</td><td><input type="text" name="two" value="two"/></td></tr>
404         <tr id="7.12">               <td>7.2 Three</td><td><input type="text" name="three" value="three"/></td></tr>
405         <tr id="7.13">               <td>7.3 Four</td><td><input type="text" name="four" value="four"/></td></tr>
406         <tr id="7.14">               <td>7.4 Five</td><td><input type="text" name="five" value="five"/></td></tr>
407         <tr id="7.15" data-level="1"><td>7.5 Six</td><td><input type="text" name="six" value="six"/></td></tr>
408         <tr id="7.16" data-level="2"><td>7.6 Seven</td><td><input type="text" name="seven" value="seven"/></td></tr>
409         <tr id="7.17" data-level="1"><td>7.7 Eight</td><td><input type="text" name="eight" value="eight"/></td></tr>
410         <tr id="7.18" data-level="2"><td>7.8 Nine</td><td><input type="text" name="nine" value="nine"/></td></tr>
411         <tr id="7.19">               <td>7.9 Ten</td><td><input type="text" name="ten" value="ten"/></td></tr>
412     </table>
413   <a class="toggle-json77" href="#">Hide JSON</a><div id="json77" class="result"></div>
414 </div>
415
416 <h2>Version History</h2>
417 <table class="versionHistory">
418         <tr><td>0.2</td><td style="white-space: nowrap;">2008-02-20</td><td>First public release</td></tr>
419         <tr><td>0.3</td><td>2008-02-27</td><td>Added onDragStart option<br/>Made the scroll amount configurable (default is 5 as before)</td></tr>
420         <tr><td>0.4</td><td>2008-03-28</td><td>Fixed the scrollAmount so that if you set this to zero then it switches off this functionality<br/>Fixed the auto-scrolling in IE6 thanks to Phil<br/>Changed the NoDrop attribute to the class "nodrop" (so any row with this class won't allow dropping)<br/>Changed the NoDrag attribute to the class "nodrag" (so any row with this class can't be dragged)<br/>Added support for multiple TBODYs--though it's still not perfect<br/>Added onAllowDrop to allow the developer to customise this behaviour<br/>Added a serialize() method to return the order of the rows in a form suitable for POSTing back to the server</td></tr>
421     <tr><td>0.5</td><td>2008-06-04</td><td>Changed so that if you specify a dragHandle class it doesn't make the whole row<br/>draggable<br/>Improved the serialize method to use a default (and settable) regular expression.<br/>Added tableDnDupate() and tableDnDSerialize() to be called when you are outside the table</td></tr>
422     <tr><td>0.6</td><td>2011-12-02</td><td>Support for touch devices</td></tr>
423     <tr><td>0.7</td><td>2012-04-09</td><td>DenisH - Code cleanup, </td></tr>
424     <tr><td>0.8</td><td>2012-09-13</td><td>Minified version of 0.8dev release - LightDot</td></tr>
425     <tr><td>0.9</td><td>2012-10-21</td><td>Changelog from different contributors:
426         <table style="width: 700px; margin-top: 10px; font-size: 90%;" cellpadding="0" cellspacing="0">
427           <tr><td style="white-space: nowrap;">2012-01-24</td><td>Daniel Bøndergaard</td><td>Don't include blank ids in serialization</td></tr>
428           <tr><td>2012-05-08</td><td>Matt Snider</td><td style="white-space: nowrap;">Major refactor and optimization, dispersed codebase merge, , Hierarchy DnD</td></tr>
429           <tr><td>2012-06-04</td><td>Vyacheslav Salakhutdinov</td><td>Remove alert with "has Touch"</td></tr>
430           <tr><td>2012-06-11</td><td>AndreZteel</td><td>Major refactor and optimization, dispersed codebase merge, , Hierarchy DnD</td></tr>
431           <tr><td>2012-06-11</td><td>Daniel Franz</td><td>Global footprint reduction by limiting variable scope</td></tr>
432           <tr><td>2012-06-07</td><td>Andrew Nagy</td><td>Added jsonize for JSON Serialization.</td></tr>
433           <tr><td>2012-07-12</td><td>Adam Hodges</td><td>Multiple &lt;tbody&gt; issues fixed</td></tr>
434           <tr><td>2012-09-16</td><td>nickl-</td><td>Major refactor and optimization including code reduction, code cleanup and normalization, dispersed codebase merge, Hierarchy DnD, jQuery object modifiers, improved scope reduction, style enhancements, improved event handling and state awareness, motion sensitivity thresholds and direction detection, relation integrity, refactored data serialization, </td></tr>
435           <tr><td>2012-10-21</td><td>nickl-</td><td>JQuery via CDN, documentation updates, Added code pretifier and other style adjustments</td></tr>
436           <tr><td>2012-03-23</td><td>nickl-</td><td>Added auto init support and ability to configure DnD via data attributes, improved data integrity and common points of failure, optimization and style clean-up. Added license and attribution.</td></tr>
437         </table>
438     </td></tr>
439 </table>
440 </div>
441
442 <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
443 <script type="text/javascript" src="//google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"></script>
444 <script type="text/javascript" src="js/jquery.tablednd.js"></script>
445 <script type="text/javascript">
446     $(document).ready(function() {
447         prettyPrint();
448         // Initialise the first table (as before)
449         $("#table-1").tableDnD();
450         // Make a nice striped effect on the table
451         table_2 = $("#table-2");
452         table_2.find("tr:even").addClass("alt");
453         // Initialise the second table specifying a dragClass and an onDrop function that will display an alert
454         table_2.tableDnD({
455             onDragClass: "myDragClass",
456             onDrop: function(table, row) {
457                 var rows = table.tBodies[0].rows;
458                 var debugStr = "Row dropped was "+row.id+". New order: ";
459                 for (var i=0; i<rows.length; i++) {
460                     debugStr += rows[i].id+" ";
461                 }
462                 $(table).parent().find('.result').text(debugStr);
463             },
464             onDragStart: function(table, row) {
465                 $(table).parent().find('.result').text("Started dragging row "+row.id);
466             }
467         });
468
469         $('#table-3').tableDnD({
470             onDragStart: function(table, row) {
471                 $(table).parent().find('.result').text('');
472             },
473             onDrop: function(table, row) {
474                 $('#AjaxResult').load("server/ajaxTest.php?"+$.tableDnD.serialize())
475                         .parent().find('.result').html($('<p>').append('Result of $.tableDnD.serialize() is url encoded: ')
476                         .append($('<pre class="prettyprint">').text($.tableDnD.serialize()))
477                         .append(' Which looks like this when decoded (decodeURI): ')
478                         .append($('<pre class="prettyprint">').text(decodeURI($.tableDnD.serialize()))));
479                 prettyPrint();
480             }
481         });
482
483         $('#table-4').tableDnD(); // no options currently
484
485         $('#table-5').tableDnD({
486             onDragStart: function(table, row) {
487                 $(table).parent().find('.result').text('');
488             },
489             onDrop: function(table, row) {
490                 var data = $(table).tableDnDSerialize();
491                 $(table).parent().find('.result').append(
492                         $('<strong>').text('The urlencoded serialized string:'))
493                         .append($('<pre class="prettyprint">').text(data))
494                         .append($('<strong>').text('Which looks like this through decodeURIComponent:'))
495                         .append($('<pre class="prettyprint">').text(decodeURIComponent(data)));
496                 prettyPrint();
497             },
498             dragHandle: ".dragHandle"
499         });
500
501         $("#table-5 ").find("tr").hover(function() {
502             $(this.cells[0]).addClass('showDragHandle');
503         }, function() {
504             $(this.cells[0]).removeClass('showDragHandle');
505         });
506
507         $('#table-7').tableDnD({
508             hierarchyLevel: 4,
509             onDragStart: function(table, row) {
510                 $(table).parent().find('.result').text('');
511             },
512             onDrop: function(table, row) {
513                 $(table).parent().find('.result').append(
514                         $('<strong>').text('JSON.stringify result of $.tableDnD.tableData()'))
515                         .append($('<pre class="prettyprint">').text($.tableDnD.jsonize(true)));
516                 prettyPrint();
517                 $.post("server/ajaxJSONTest.php", $.tableDnD.jsonize(), function (data) {
518                     $('#table-7-response').html('<br>'+ data);
519                 });
520             }
521         });
522
523         $('.toggle-json6').toggle(function() {
524           $(this).text('Show JSON');
525           $('json6').hide();
526           return false;
527         },
528         function() {
529           $(this).text('Hide JSON');
530           $('json6').show();
531           return false;
532         });
533         $('.toggle-json7').toggle(function() {
534                 $(this).text('Show JSON');
535                 $('json7').hide();
536                 return false;
537               },
538               function() {
539                 $(this).text('Hide JSON');
540                 $('json7').show();
541                 return false;
542               });
543
544         $('#radio-button-test').tableDnD();
545
546     });
547 </script>
548
549 </body>
550 </html>