I'm looking for a way to implement both resizing and drag 'n' drop for columns (not rows) within a predefined table using jQuery. I've done a bit of Googling and haven't really found anything that fits the bill as many require you to essentially reconstruct your table using jQuery. I simply want to plug this functionality in, not have my entire table structure dictated by a third-party.
Does anyone know of any plugins that might help me to do this, and if not are there any jQuery Gurus out there that have solved this problem already?
So I take it you are not interested in one of the existing grid plugins such as jqGrid? I would suggest looking at their implementations to get an idea of how they drag/drop columns.
I'd don't have specific code to do this, but here are my initial thoughts on how to approach the problem.
I would use use css
table-layout: fixed with
<col> tags to define your column widths. This way your jquery code only needs to change the width value in one place and all cells in the column will adjust width.
<table width="100%" cellspacing="0"> <col width="25%"> <col width="25%"> <col width="25%"> <col width="25%"> <tr>...</tr> </table>
Use CSS to float an invisible narrow div to the right side of each header cell:
<th>Title<div class="resizer"></div></th>. This
<div> becomes your resizer handle, and you would want to have CSS on it to change the mouse cursor on hover. You could even use CSS to nudge it to the right a little so that it overlaps the border between columns.
Then apply jQuery UI draggable behavior to that div. As the div is dragged, update the
<col> widths appropriately. How you resize will be dependent on your needs and will probably take a little bit of math.
Alternatively, when the invisible div is dragged, you could convert it to an absolutely positioned narrow div that increases to the height of the table. You would need to move it when the mouse is dragged, and make it visible to indicate where you are resizing the columns to. Then once the resizing is done, you recalculate the
<col> sizes and apply them, change the height back to only fit in the
<th>, and make it not visible again.
This could be trickier. I would start by applying the draggable behavior to
<th> elements. The
<div> described above inside the
<th> elements could have a droppable behavior. This way you could drag any column onto one of these divs and drop it on them. When a column is dragged on top of a div, the div should become visible, and maybe the height of the column.
Once a user drops a column header onto one of these resizer bar divs, you would then need to loop through each row of the table and move the appropriate
<td> to the correct location. Don't forget to move the appropriate
<th> as well.
I hope this will get you going. I'm sure there are examples of this out there somewhere if you look hard enough. But most grid controls do have far more features than I would actual use, and it sounds like you would rather keep things simple.
I just did a quick google search and found this plugin. I haven't looked at the source yet, but from the demo, it looks like it takes a similar approach to what I'm suggesting. It seems to do the job, but in my opinion it doesn't look very pretty. The resizer bar doesn't line up where you'd expect and such. But it might help.