Make a individual items WITHIN a column of a JQuery Sortable table draggable without moving items in other columns - jquery-ui

I want to create a table that has drag-and-drop sortable items within a single column but where the movement of an item in an individual column will not impact the position of items in other columns.
The code below sorts entire rows (both left and right columns), not just the right column. It doesn't seem to be addressed in the JQuery UI docs. Has anyone tried to do this before?
<script>
$(function() {
$("table tbody").sortable({
handle: '.handle'
}).disableSelection();
});
</script>
<table>
<tbody id="sortable">
<tr>
<td>1 - Column Item I Want to Stay In Place</td>
<td class="handle">Item 1 - The Part That Should Be Draggable/Sortable</td>
</tr>
<tr>
<td>2 - Column Item I Want to Stay In Place</td>
<td>Item 2 - The Part That Should Be Draggable/Sortable</td>
</tr>
<tr>
<td>3 - Column Item I Want to Stay In Place</td>
<td class= "handle">Item 3 - The Part That Should Be Draggable/Sortable</td>
</tr>
</table>

I don't believe you can do that with table cells (at least I couldn't get it to work with normal sortables).
There is another option though. Instead of using a table, you could use lists that look like tables.
You can set up a style for columns to define their widths:
.column {
width: 100px;
list-style: none;
float: left;
}
Then, define each column as a list:
<ul class="column">
<li>Fixed 1</li>
<li>Fixed 2</li>
</ul>
<ul class="sortable column">
<li>Sortable 1</li>
<li>Sortable 2</li>
</ul>
<ul class="sortable column">
<li>Sortable 3</li>
<li>Sortable 4</li>
</ul>
Then all you have to do is apply your sortable to the sortable lists:
$(".sortable").sortable();
Here is a fiddle to illustrate: demo
Another option would be to disregard sortables completely and use draggable and droppable controls instead. You would have to manually alter the DOM though using the "drag" and "drop" events of these controls.

Related

knockout - how to make entire table row clickable

the first column is clickable and works fine. But now, I'd like to make the entire row clickable based on that same URL. And as each row prints, I'd like each row clickable with that respective URL that is dynamically created.
Sort of like wrapping all the td's for each row within "< a > < /a >"
But not sure how to do ... I saw an example using a databind click in the < tr >. But I'm not sure how to wrap all the tds within that URL, etc.
TIA.
<tbody data-bind="foreach: items">
<tr>
<td style="width: 300px"><h4><a data-bind="text: Name, attr: {href: $root.rootBaseUrl() + 'Items/' + ID}"></a></h4></td>
<td style="width: 400px"><h4><span>Link this as well</span></h4></td>
<td style="width: 400px"><h4><span>Link this as well</span></h4></td>
</tr>
</tbody>

Align contents to right in MvcRazorToPdf library

I have below view which generates PDF invoice using MvcRazorToPdf library
<table border="0">
<tr>
<td>
<h1>Company Name </h1>
</td>
<td>
<div style="text-align:right;margin-right:0px;">
Invoice
</div>
</td>
</tr>
</table>
<hr/>
<div>
#Model.InvoiceNum
</div>
Above code generates below view in pdf
But how much ever I style the above div within td for invoice, I am not able to move the Invoice text to the right side of the pdf. I've tried adding link to bootstrap.css which doesn't work either. Anyone have any solution for this? Has anyone worked on styling the pdf with MvcRazorToPdf librabry?
Your text alignment is being respected, its just that by default, you table and its cells will be collapsed to fit the content (easy to check by using your browser tools to inspect the elements).
Give your table (or its cells a width), for example
<table style="width:100%;">
However, using <table> elements is not good practice (refer Why not use tables for layout in HTML? and Why Tables Are Bad (For Layout*) Compared to Semantic HTML + CSS.). Instead you can use floats or relative/absolute positioning, for example
<div style="position:relative;">
<h1>Company Name</h1>
<span style="position:absolute;right:0;bottom:0">Invoice</span>
</div>
or
<div>
<h1 style="display:inline-block">Company Name</h1>
<div style="float:right;margin-top:40px;">Invoice</div>
</div>

How do I drag to an empty connected list using angular-ui?

As a follow-up to How do I move from one ui-sortable to another in Angular?
If I have 2 connected lists, and one of the lists is empty, how do I actually drop onto it? Again looking at http://minitrello.meteor.com he has a placeholder created even in an empty list. How do I replicate that so that when
list1 = [];
list2 = ['A','B','C']
I can actually drop onto list1? Fiddle at http://jsfiddle.net/hKYWr/894/
EDIT: Cleaner fiddle at http://jsfiddle.net/hKYWr/897/
If your List is empty then also you need to create an empty Li
I have added one List in each List
<li ng-show="list1.length==0"> </li>
<li ng-show="list2.length==0"> </li>
Below is the working Demo
Demo
Template code:
<div ng:controller="controller">
<div style="float:left; margin:5px;">
<h3>list1</h3>
<ul ui:sortable="sortableOptions" class="connectedList" ng:model="list1">
<li ng:repeat="item in list1" class="item">{{item}}</li>
<li ng-show="list1.length==0"> </li>
</ul>
</div>
<div style="float:left;margin:5px;">
<h3>list2<h3>
<ul ui:sortable="sortableOptions" class="connectedList" ng:model="list2">
<li ng:repeat="item in list2" class="item">{{item}}</li>
<li ng-show="list2.length==0"> </li>
</ul>
</div>
<div style="clear:both;"></div>
<hr />
<div>list1: {{list1 | json}}</div>
<div>list2: {{list2 | json}}</div>
</div>
It's a similarly 'hacky' solution to the accepted answer but you can also add some padding(top/bottom) on to your lists to handle this problem.
e.g.
<ul style="padding-top:20px; padding-bottom: 20px;">
See fiddle here for evidence!
This suggests the problem is that an empty list provides no 'target' to drop on.
Setting a min-height works just as well too.
A solution i used was just to set min-height to the connected list
.connectedList {
min-height: 10px
}
http://jsfiddle.net/hKYWr/2367/

Knockout Sortable list not working offset by new items added

When I add items to my list (by clicking the "add series" button) it causes my list to not sort properly. E.G. If I click the "add series" button and then try to move "seriesname232" inbetween items "trrde" and "1", then it will move it down one more than it should (below the "1"). I believe that this is because the sortable list isn't taking into account that something was added to it. Below is an example:
http://jsfiddle.net/thebassix/yTAXh/
<div id="results">
---Hidden---
<ul id="hidden" data-bind="sortable: { data: hiddenSeries, afterMove: hide}">
<li data-bind="visible: Hidden, text: Name"></li>
</ul>
---Unhidden---
<ul id="unhidden" data-bind="sortable: { data: unhiddenSeries, afterMove: unhide}">
<li data-bind="visible: !Hidden(), text: Name"></li>
</ul>
</div>
<hr/>
<div>All</div>
<ul data-bind="foreach: series">
<li>
<span data-bind="text: Name"></span> -
(<span data-bind="text: Hidden"></span>)
</li>
</ul>
<input id="btnAddSeries" data-bind="click: addSeries" title="Add Series" class="ews_button" type="button" value="Add Series" />
The issue is that the Series object that you are adding has _destroy as an observable. Generally, _destroy is just a normal property, as the destroy function of KO set's it as a normal property.
So, your issue will be fixed, if you do not make _destroy an observable in your Series constructor like:
self._destroy = data._destroy;
Updated sample: http://jsfiddle.net/rniemeyer/63rup/
Additionally, I just added a fix to the sortable plugin that will unwrap _destroy anyways, so this would not have been a problem.

Multiple HTML Elements on jQuery UI Tab

I'm using jQueryUI Tabs and have a requirement to add UI elements to each tab that allow a user to Edit information about the tab, or remove the tab.
The markup I use on the <li> for a given tab looks like this:
<li>
<div style="background-color:Red;"> <-- Red to see what's happening -->
<span>Tab One</span>
<div style="text-align:right; margin-right:3px;">
<div><span id="editTab-1">edit</span></div>
<div><span id="delTab-1">X</span></div>
</div>
</div>
</li>
This renders just as I would hope in IE
______________________________
| Edit|
| Tab One |
|___________________________X__|
but it does not render properly in Chrome or FireFox (the tab is only wide enough for the "Tab One" text, and "Edit" / "X" are mostly "under" the tab (lower Z-Index apparently).
What is a compatible way to achieve my goal?
I'm not sure if this is what you were intending or not, as I haven't tested in IE, but this works in Chrome and FF:
<div id="tabs">
<ul style="cursor:pointer">
<li>
<a href="#tabs-1">
<div style="float: left; margin-right: 20px;">Tab One</div>
<div style="float: right; text-align:right;">
<div id="editTab-1">edit</div>
<div id="delTab-1">X</div>
</div>
</a>
</li>
<li>
<a href="#tabs-2">
<div style="float: left; margin-right: 20px;">Tab Two</div>
<div style="float: right; text-align:right;">
<div id="editTab-2">edit</div>
<div id="delTab-2">X</div>
</div>
</a>
</li>
</ul>
<div id="tabs-1" class="tabPane">Tab One Content</div>
<div id="tabs-2" class="tabPane">Tab Two Content</div>
</div>
See the working jsFiddle
If you want to handle the clicks dynamically, you could use:
var $tabs = $("#tabs").tabs();
$tabs.find("a div[id]").on("click", function() {
var id = $(this).attr("id"),
idTab = parseInt(id.substring(id.length - 1)),
isEdit = id.indexOf("edit") > -1,
isDelete = id.indexOf("del") > -1,
index = $tabs.tabs('option', 'selected');
if (index + 1 === idTab) {
if (isEdit) {
console.log("Edit Tab " + (index+1));
//however you want to edit here
}
if (isDelete) {
console.log("Delete Tab " + (index+1));
$tabs.tabs("remove", index);
}
}
}).css("cursor", "pointer");​
See the working jsFiddle
The problem, I think, stems from the fact that the tab <li> and then the <a> inside are floating elements, as designed in the jQueryUI CSS.
The technical part can best be summed up with this quote (from http://css.maxdesign.com.au/floatutorial/introduction.htm)
If no width is set, the results can be unpredictable. Theoretically, a floated element with an undefined width should shrink to the widest element within it. This could be a word, a sentence or even a single character - and results can vary from browser to browser.
So the red <div> is shrinking to the widest element - the <a>. IE and Firefox/Chrome are simply behaving differently, just their interpretation of the specifications. To be honest, that fact that Firefox and Chrome are similar and IE has had a long history of float bugs I'd side with Mozilla/Google here although can appreciate that IE seems to be behaving nicer in this instance.
You can solve the problem by simply setting a width on the red <div>. However the markup could also be a bit cleaner, for example:
<li style="background-color:red;width:150px">
Tab One
<div id="editTab-1" style="text-align:right;margin-right:3px">edit
<p id="delTab-1">X</p>
</div>
</li>
gives the same result.

Resources