script.aculo.us Sortable with delimiters - javascript

I'd like to use Script.aculo.us Sortable to sort elements of a horizontal list (let's say some little boxes). The problem is that these boxes have to be separated from each other by another boxes of a different kind, which shouldn't be movable, but they have to be always there in between these sortable boxes, one between each pair of movable boxes.
Let's mark movable boxes by [M] and unmovable delimiters by [D]. Then the situation is as follows:
[M1][D][M2][D][M3][D][M4]
Now, when a user drags, for example, the [M2] movable box to the position of [M4], the situation should become as follows:
[M1][D][M3][D][M4][D][M2]
and when he moves the [M4] movable box into the [M2] position, the situation should be like below:
[M1][D][M3][D][M4][D][M2]
But the following settings are forbidden:
[M1][D][M3][M4][D][D][M2]
[M1][D][M4][D][M2][M3][D]
that is, no two delimiters should be near each other, and no delimiter should be left in front or at the end of the sequence.
How can I make something like that using Script.aculo.us Sortables? Is it possible at all?

I think I've figured a way to make it: It could be done by CSS rules.
I simply set the following rule for my list element:
li:before {
content: "[D]"; /* my delimiter */
}
li:first-child:before {
content: "";
}
This makes that all list elements but first will have [D] text attached before them in their container.
Now when I move around my list items (Draggables of a Sortable), the CSS keeps these delimiters updated: when I drag an element to the beginning of the list, it gains :fisrt-child pseudo-class, so it appears without the delimiter. At any other place in the list it lacks this pseudo-class, so the delimiter appears in front of it.
So looks like the problem is solved.

Related

How to stop horizontal movement in jQuery Nestable?

I am using this plugin https://github.com/dbushell/Nestable
I have tried commenting various core code in it which it has helper comments like horizontal and vertical but still I am clueless on how to stop the horizontal dragging.
Let me elaborarte I only want vertical movements of elements and no horizontal movements of elements of which will lead to parent-child scenario
see the pic below
this is a tree view if you want to just align them equally you can simply use ul , li but if you have an object and it has parent/child nodes and you want to show them as a tree view except not having the indent then simply remove the indent with css or maybe there is a method or property in nestable to set amount of indent to whatever you want
Well found the answer , in case any one finds a flaw then please comment
$(element).nestable({
maxDepth: 1,
});

jQuery multiple sortable tables

This question is best read with the fiddle open ;). I've got a tables inside a table. The inside grey tables need to be sorted in there own container. So the grey rows can only be moved in the grey table. But the white rows need to move there grey table with them. So you cannot move a white row or a grey table on there own, they are connected.
Here is my fiddle for what I got right now:
fiddle
options = {
helper: (event, ui) ->
children = ui.children()
view = ui.clone()
view.children().each (index) ->
$(#).width(children.eq(index).width())
return view
}
$('#ccc').find('tbody').sortable(options)
I've been cracking my head on this all day but I cannot figure out how to like a grey table to a white row.
With your current html structure this is quite difficult to achieve.
First of all you need two sortables (one to sort big chunks with white headers and second to sort inside grey tables).
You want to be able to move big tables with small ones inside but as these were all inside sibling elements (tr) it was not really possible (so I've added multiple <tbody>s in there).
Anyway here's the working fiddle: https://jsfiddle.net/9vmvjqm4/5/
You still need to exclude thead from being sortable. I don't like CoffeeScript so I left that (add items : ':not(thead)') to options (or sth like that, there are topics how to do that on stackOverflow).
Also, have a look at this: http://johnny.github.io/jquery-sortable/

Dynamically shorten/hide/overlap tekst in table cells when too long

My table has static width values but sometimes table cells of a certain column can contain text which is too long and which messes up the table's width. I'm looking for a way to dynamically shorten text (kind of like a table grid functionality but then without grids) because it can be of a variable length, and when one hovers over the table cell the entire text is shown without stretching the table.
Currently, I have this hard coded in my script in the following way:
string.substring(0, 65) + '...'; and passing the full text to the 'title' attribute of the table cell.
Note that I don't want to keep using the 'title' attribute. I tried surrounding the text with <span style='position: absolute; background: #EEE'></span> when triggered by the hovering event, but unfortunately that wasn't an appealing solution as the text moved a bit to the bottom while the padding nor the margin style were changed.
The solution can also be a jQuery plugin or JavaScript script.
1. Shortening the original data
I suggest that you consider something more elegant than chopping the string at the 65th character. -- Instead, look for whitespace to break the string at. Only chop mid-word if no whitespace is found.
To save more room in the table cell, use the ellipses character… instead of three periods... Just copy/paste it from this answer. The ellipses character could also be styled with a different or smaller font.
2. Showing the original data on hover
I prefer YUI. Their tooltip widget works well for this. An example.
You should try this CSS instruction:
td { break-word: word-wrap; }
that works in many browsers (yes, including IE 6, even IE 5.5 but not Fx 3.0. It's only recognized by Fx3.5+. Also good for Saf, Chr and Op but I don't know the exact version for these ones) and don't do any harm in the other ones.
If table's width is still messed up, there is also:
table { table-layout: fixed; }
th, td { width: some_value; }
that will force the browser to use the other table algorithm, the one where it doesn't try to adapt many situations including awkward ones but stick to what the stylesheet says.

How to distinguish between blank areas and non-blank areas in a webpage with JavaScript?

How to distinguish between blank areas and non-blank areas in a webpage with JavaScript? Blank areas including:
areas that are not occupied by DOM elements.
margins, borders and paddings of DOM elements.
EDIT:
As response to the first comment: I am working on a web-based ebook reader. Cursor is set to {cursor:move} for blank areas so that the user can drag and scroll the webpage.
You could recursively go through each element and attach onmouseover and onmouseout events (where the former enables the text cursor and the latter enables the move cursor) on each which has text in it, e.g:
function attachEvents(e) {
if (n.nodeType == 3) { // Node.TEXT_NODE
// A text node - add the parent as an element to select text in
e.parentNode.onmouseover = elmMouseOver /* define your own event fns */
e.parentNode.onmouseout = elmMouseOut
}
else if (n.nodeType == 1) { // Node.ELEMENT_NODE
for (var m=e.firstChild; m != null; m = m.nextSibling) {
attachEvents(m)
}
}
}
The best way I can think of to make sure it's actually "text" which is moused over and not a blank area is to use e.g. <div><span>content</span></div> and put the mouseover/mouseout events in the <span> so that blank areas don't trigger events. This is what I'd recommend doing if you can, as things can get very complicated if you use block elements with padding from my experience. For example:
| The quick brown fox jumps |
| over the lazy dog | <- onmouseover/out of SPANs will ignore the space
after "dog" while DIVs won't and you won't need
to calculate padding/margins/positions which
makes it faster and more simple to implement
If you have to use block DIVs: You could use something like jQuery's jSizes plugin to get margins/padding in pixels or this (for a way to get the inherited CSS values and parse yourself by removing the px part from the end etc)
After that, you could figure out the position using position() in jQuery. I personally don't use jQuery for my stuff, but I use those specific "find positions" functions and found them to be one of the best I think in large part because of number of users testing them.
Good luck!
My advice would be to go for a simple scrollbar. That's far more foolproof. By trying to implement the cool drag-and-scroll feature you risk with a lot of buggy behavior in dozens of edge-cases none of us can even imagine.
If you really want to detect clicks in whitespace, you could try attaching to the onmousedown/onmouseup/onmousemove events for the page itself. JavaScript events bubble nicely, so you'll handle the whole page at once (unless it has some JavaScript in itself, in which case you're screwed anyway). These events supply both the mouse X/Y coordinates and the element that was clicked. Then you can check for padding of that element (careful with inline elements) and figure out if it's in the padding or not. You do not need to check the margin because clicking there will instead originate the click in the parent element.
Although the effect you get this way is a lot of scattered "drag-zones" that the user will have to hunt for in order to scroll the page. I doubt this will sit well with your users. Better then make the whole page "draggable", but then you will loose the ability to select text. Or do like Acrobat, which only allows grabbing in the considerable padding area of the page itself (then you should make sure that there is a considerable padding area). Which in my eyes is not much better than a scrollbar. :P

Javascript drop down menu widget

I have a menu consisting of an <ul> in a Web CMS.
I want several menu items to have sub-items that are displayed in a dropdown list. These sub-items are <ul>s as well.
This is basically easy to do with a few lines of CSS and Javascript, but I am looking for a ready-made Javascript solution that helps me handle the following:
Deal with screen edge situations: If any part the dropdown menu would be outside the current viewport, place it so that it is completely within the viewport.
This is a bitch to code from scratch.
"Nice to have"s would be:
Centered positioning below the drop-down button
Adding a onclick event to the body so that clicking outside the drop down menu will close it; clean removal of the onclick event afterwards
But those I can do myself if necessary.
A nice, small, unobtrusive widget that magically converts my <ul> would be lovely.
If the solution is based on a framework, it has to be Prototype as that's what I'm using in the CMS.
You can get the offsets of the UL, and check whether those are in a certain distance of the viewport.
// Pseudo code
var ul = document.getElementById("menu");
if(ul.offset.x + ul.width > viewport.width) {
ul.offset.x = viewport.width - ul.width;
}
It's also possible to get the exact position of the dropdown button clicked, and then you should apply basic math in order to position the menu beneath it.

Categories

Resources