I'm great with CSS but I largely suck at jQuery. We all have our limitations...
OK with that admission out of the way I'll begin. We have a "favourite products" table, which you can sectionalize into categories (eg, Booze, Sheep, Spoons). Each category is a . Each row (excluding the ) is a product.
I want to enable a user to drag and drop (reorder) the table rows, even between tbodies. I've looked at Table Drag and Drop (DnD) plugin for jQuery but was disappointed to find that it doesn't really support dragging between tbodies - and hasn't been updated for quite some time.
Here is the basic table structure:
<table>
<thead>
<tr>
<th>Favourite</th>
</tr>
</thead>
<tbody>
<tr>
<th>Spoons</th> <!-- secion title, not draggable -->
</tr>
<tr>
<td>Wooden Spoon</td>
</tr>
<tr>
<td>Metal Spoon</td>
</tr>
<tr>
<td>Plastic Spoon</td>
</tr>
</tbody>
<tbody>
<tr>
<th>Nuclear Bombs</th> <!-- seciont title, not draggable -->
</tr>
<tr>
<td>US Nukes</td>
</tr>
<tr>
<td>Soviet Nukes</td>
</tr>
</tbody>
</table>
I'm going to need to turn of the "dragability" of certain rows such as the first row in the - this being the section title.
Is there a better version of a jquery plugin out there that can do what I need? If you can find a better plugin please share and win my "favourite person of the week" award.
Thank you.
Your going to want to use jQueryUi's sortable plugin and then use the option
connectWith: '.connectedSortable'
to connect the different table bodies.
the plugin is designed for lists, but it does work on tables, mostly. I've used it with success on a table before.
here's the link to the documentation on jquery ui's sortable:
http://jqueryui.com/demos/sortable/#connect-lists
EDIT:
you'll also want to use the items option to specify that certain rows are sortable
items: 'tr:not(.dontIncludeMe)'
Have you looked into jQuery UI's droppable widget? I'm wondering (since I haven't played around with your specific problem yet) if you could set your tbody as droppable and your tr as draggable. Or possibly add some classes to each to be able to specify that certain rows (non-title rows) are draggable...
UPDATE: more research turned up this SO question, which links to this other article about dragging table rows.
you can turn off the dragability in case od table dnd plugin by specifying
<tr class ="nodrag nodrop">
<th>Favourite</th>
</tr>
class nodrag nodrop will not allow drag and drop
and
class nodrag will not allow it to be dragged i hope it helped.
Related
I am a beginner in react and web apps in general let me know if anything is unclear.
I have the following table :
<div>
<table id="mytableid" className="some classes">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone Number</th>
<th>Age</th>
<th>Sex</th>
<th>Blood Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>Some place somewhere</td>
<td>093-1252-4879</td>
<td>51</td>
<td>Male</td>
<td>AB</td>
</tr>
</tbody>
</table>
</div>
Let's say I want to hide Address and blood type if table is too big to fit in a div.
The way I am thinking of doing this is to check the size of the div and the table in componentDidMount
if the size of the table is bigger than the div then I will set the style of those two columns to display:none.
I did something similar for submenu transitions where I would change my component set on the componentDidMount to get the height then put the visibility to hidden by changing the state. I didn't notice any slowness neither can I see that the submenu was actually visible(on chrome)
I saw some people are doing things like for the nth column to not be displayed if the screen is too small using purely css which is nice. But in my case I am not sure if I could do something similar as I would like the user of my component to specify which columns to hide.
My question is if it is the usual way for webapp developers to display the component check the result on componentDidMount and then change how things look or is there a different pattern?
The one pattern I have seen is, removing items on demand in such cases, i.e. user has choice of which columns to see and which one to hide. Refer this dynamic-columns example from an open source.
http://uikernel.io/examples/dynamic-columns/
In jQuery mobile v 1.4.5 i used table rows append dynamically with column toggle but it does not work for the rows which are dynamically generated.
<table id="tab" data-role="table" data-mode="columntoggle" class="ui-responsive">
<tbody id="tb" >
<thead id="th">
<tr id="tr1">
<th>First</th>
<th data-priority="1">Second</th>
<th data-priority="2">third</th>
</tr>
</thead>
</tbody>
</table>
Here is the Fiddle what I tried.
I referred this jQuery mobile document.
Note: I want to insert the table rows at the top of the previous rows (dynamically added rows that why I used "after" property).
Edited:
New link is the below to locate created new row on the top of the table
http://jsfiddle.net/txej8qhj/6/
The below link works fine;
http://jsfiddle.net/txej8qhj/3/
Probably you too know. Sometimes we may overlook somethings. You should separate the thead and tbody element. Actually thead element first comes in a table like the below;
<table>
<thead>
</thead>
<tbody>
</tbody>
</table>
Check the below link out to use as guide;
http://demos.jquerymobile.com/1.4.5/table-column-toggle/#&ui-state=dialog
You need to call refresh and trigger create functions on the table element.
Please, try the below:
$("#tr1").after(newrow);
$('#tab').table("refresh").trigger("create");
I have a standard table with option to hide columns and I want to use a plugin for re-sizing the width of the columns.
I tried with colResizable and resizableColumns but the things get messy when I hide a column and then try re-sizing.
Edit: My table:
<table id="mytable">
<thead>
<tr><th class="column1"></th>text 1 <th class="column2">text 2</th></tr>
</thead>
<tbody>
<tr><td class="column1"> cell00 </td> <td class="column2"> cell01 </td></tr>
<tr><td class="column1"> cell10 </td> <td class="column2"> cell11 </td></tr>
<tr><td class="column1"> cell20 </td> <td class="column2"> cell21 </td></tr>
</tbody>
</table>
Activating colResizable:
$("#mytable").colResizable({
liveDrag:false,
gripInnerHtml:"<div class='grip'></div>",
draggingClass:"dragging",
minWidth:50
});
Function for hidding / displaying columns:
function toggleColumn(index){
if(something){
$('.column'+index).hide();
}else{
$('.column'+index).show();
}
$("#"+tableID).colResizable({
disable:true
});
$("#"+tableID).colResizable({
disable:false,
liveDrag:false,
gripInnerHtml:"<div class='grip'></div>",
draggingClass:"dragging",
minWidth:50
});
}
After each toggle i restart colResizable, so it can get the new values.
The problem comes when I re-size any columns beyond the hidden ones.
I also need the option to set default widths to each column. All suggestions are welcomed.
colResizable 1.5 is compatible with hidden columns. You can download it on http://www.bacubacu.com/colresizable
if you want to change column visibility after colResizable is already activated, those are the steps you have to follow:
call colResizable (as usual)
before you perform any DOM modifications (such as hiding a column), destroy colresizable using disable:true
change columns visibility
call colResizable again
It looks like Datatables has everything you may want.
Check out this fiddle. You get everything: Show, hide columns, resized columns, and many more cool options. And using it is very easy
$(document).ready( function () {
$('#example').dataTable( {
"option": value;
} );
} );
option 1:
Use a class name on the TD. Give the class name in a style element that is added dynamically to the document. To resize, delete the style element from the document then add again with new specifics.
option 2:
Cycle through the rows collection of the table setting style.width on .cells[0], .cells[1], ....
To hide, set style.display to none, then to unhide, inline.
I just try a table with <ol> as list elements with which it is possible to insert new table row.
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody>
<ol id="list">
<li><tr><td>row</td><td>row</td><td>row</td></tr></li>
</ol>
</tbody>
However, I have the problem that the element appear outside of my tables. When I add dynamically content via .append(), the formatting is not taken some elements gets removed.
Jsfiddle example
I want to use this solution for counting currently positions in an "container list".
I got a similar function like the example below for counting my lists, that's working great but the insert into the table does not work properly.
countinglists example: Nested ordered lists
Maybe its possible to achieve that counting syntax in a table without the <ol>? or is there any <ol> equivalent?
You need to do some reading on basic HTML: http://www.w3schools.com/html/html_tables.asp
Here is how it should look...
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody id="list">
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
</tbody>
In theory, you should be able to use CSS counters.
table {
counter-reset: myTableCounter;
}
thead th:first-child:before {
display: table-cell;
content: "";
}
tbody td:first-child:before {
display: table-cell;
counter-increment: myTableCounter;
content: counter(myTableCounter);
}
However, when I attempted to do that I found there were issues with display: table-cell generated content.
You may have to look at adding additional elements to the table to generate the content inside the first cell of each row.
My question is: what are you trying to achieve? Is this an exercise just to see how much can you stretch the HTML?
For your jsfiddle, the action associated to the click removes some of the HTML tags (at least on my browser) resulting in a <li>rowrowrow</li>, so you end up having a rather odd formatted-table. My renderer takes all <li> tags added by clicking as the content of a row; if you have only <li> tags, the dom parser will likely wrap them into a <ul> (it does on mine).
IMHO you don't need to use the ol to be able to count stuff. You can do it in jquery afaik. If you insist to use lists, then you probably need to style them and use e.g. divs inside (styled too). Emulating a table via a list and divs is madness imho :)
Update - for the hierarchical table
My idea would be to have something similar to this jsfiddle. I basically styled in the .sub and the .main classes. However, things get a bit more complex is you need to add some extra columns. In this case, you'd need something like a treetable.
I am trying to hide subsequent tr's with role="metadata" and the same data-group-id as the first occurring tr.
I cannot use JavaScript here and I am trying to achieve this using pure CSS.
<table>
<tbody>
<!-- BEGIN this tr should be visible -->
<tr data-group-id="1" role="metadata">
<td>
First rows group title
</td>
</tr>
<!-- END this tr should be visible -->
<tr data-group-id="1" role="data">
<td>
Row belonging to group 1
</td>
</tr>
<!-- BEGIN this tr should be hidden -->
<tr data-group-id="1" role="metadata">
<td>
Rows group title
</td>
</tr>
<!-- END this tr should be hidden -->
<tr data-group-id="1" role="data">
<td>
Another row belonging to group 1
</td>
</tr>
<!-- BEGIN this tr should be visible -->
<tr data-group-id="2" role="metadata">
<td>
Second rows group title
</td>
</tr>
<!-- END this tr should be visible -->
<tr data-group-id="2" role="data">
<td>
Row belonging to group 2
</td>
</tr>
</tbody>
</table>
Selectors like this...
[data-group-id="1"][role~="metadata"] ~ [data-group-id="1"][role~="metadata"]
display: none
... work very well, except that data-group-id may change dynamically.
Something like this would be perfect (I know that this is invalid CSS code, its just my fantasy with regular expressions to help illustrating the problem):
[data-group-id="(.*?)"][role~="metadata"] ~ [data-group-id="\\1"][role~="metadata"]
Is there any way I can achieve this using only CSS?
Thanks in advance.
Seems to me that using the data-group-id in CSS is impractical, especially since it's dynamically mutable and conditions of wether an element is hidden or not change. You end up with a huge chunk of CSS thats impossible to maintain.
In the initial rendering, it might be better to add a className so you determine serverside wether the initial state should be shown or not.
<tr data-group-id="1" role="data" class="hidden">
<td>Another row belonging to group 1</td>
</tr>
I am assuming JavaScript is used to dynamically change data-group-id, so why not use JavaScript to add/remove the className "hidden" when/where it makes sense. At least in JavaScript you CAN use regular expressions ;)
When you get to the point where you have to write impossible, long winded, error prone and unmaintainable CSS expressions, you're doing something wrong.
You're going to have to write some code to achieve this anyways, might as well do it the clean way instead of trying to shoehorn it into a styling language that isn't fit for the job.