UI/DOM Sorting with jQuery - javascript

So, I have scoured the internet to find help on this...
I have a bar graph where the bars/values are sorted left to right with the largest value on the left. Based on user interaction, the bar graphs/values may change and, for instance, the middle bar may need to move 1 or more spots to the left. This has to be done on the fly, without removing the DOM element because I need to animate the left to right movements... this is for user appeal, something that is very important to the project.
So, I guess my question is, since you can't resort DOM elements and animate them at the same time, how can you track the movement. I've toyed with the idea of creating an initial index of the graph as the page loads and updating the index as changes are made. Logically, I have a hard time with this. Also, if one were to do that, whats the best way to index, using the data attribute? Isn't this only HTML5 and possibly unsupported in older browsers, or does jQuery keep a cache that has nothing to do with HTML5?
I'm fairly new to javascript/jQuery. I would say I've been using it for 2 years but I've ever really only done small jQuery animations and validation. Would really love some input form the community!
Thank you!

You're right, you can't animate elements by sorting.
The knack is to position the bars within the graph space with CSS properties, eg. left or margin-left.
Then you have something that, when changed in the right way, will give an animated effect.
All you need to do is to loop through each bar in turn, calculate its new CSS left/margin-left property and use jQuery's .animate() to cause it to slide into its new position.
Assuming that the bars to be positioned with margin-left and that the height of the bars also needs to be changed, then the general form of the jQuery will be :
$(".bars").each(function(i, bar) {
var $bar = $(bar);
var marginLeft = ........;//expression that calculates or fetches the new margin-left property for bar i
var height = ........;//expression that calculates or fetches the new height property for bar i
$bar.animate({
'margin-left': marginLeft,
'height': height
);
})
There's no need to sort anything or to use the data attribute.

Related

Inside of a scrolling div, offset and position do not properly give dimensions in term of the top of the doc

I have a scrolling div, which has enough controls to scroll. Which all flow in a block display. when scrolling down, when i was to take a snapshot of all the elements, i was wanting to get the list of all the positions and print them out. The issue at hand is that when scrolling, things that are out of view (towards the top) have a neg. position.
I was looking at offset and Position, but they both arent giving me the numbers i was wanting.
How would i get the X:Y positions of all the children, from the top of the div? IE: [0,0], [0,20], [0,40] etc etc.
Is there another variable i am not making use of? some sort of scrollY or something which should be appended to adjust everything?
Edit: When dealing with scrollable divs, making use of: $.scrollTop gives the offset, which would need to be applied to all the children. when getting the position of all the items
If I'm understanding the question correctly, it sounds like you want scrollTop, i.e.
document.getElementById('div1').scrollTop;
...which you can get and set. If I've misudnderstood, perhaps you could create a jsfiddle?

How to make HTML elements react on mouse movements?

my question is how can I add specific movement to x-y axis for an HTML element according to mouse movements.
Look at the site here and scroll to second slide:
http://community.saucony.com/kinvara3/
How can i achieve such effect!?
If you're going to write the library-free version, you will need to start with the following:
Learn DOM-manipulation.
var myEl = document.querySelector("#my-el");
Learn the <element>.style interface.
myEl.style.position = "absolute";
Learn the CSS properties, their values and how to read/use them from the style interface.
myEl.style.left = 10 + "px";
You'll need to understand the following CSS properties at a minimum:
"display"
"position"
"top"
"left"
"z-index"
Learn how to parse numbers from strings, properly, in JS.
...this will be unimportant, working with the mouse,
but very important, working with the DOM.
Learn how to write event-handlers.
window.addEventListener("mousemove", function (evt) {/*mousemove event object*/});
Learn the properties of event-objects (specifically the event-types that are important, like mouse, keyboard, touch).
Learn how to manage events, and control the number/frequency of operations, based on an ideal framerate, when the browser won't do it for you.
Learn how to make all of these things happen in a cross-browser, IE8+ way.
Learn a little linear-algebra (honestly, learning enough of it to understand an inverted-axis scaled-parallax is just a tiny bit harder than Grade 6 geometry.
You can get a similar effect CSS only, no JS needed!
You can see an example here: Pure CSS 3D Meninas, by Román Cortés. In his blog, there is also the explanation.
Basically, you have to split the target element in small elements, and on hover, set the position of different background layers according to your trigonometric calculations.
From his explanation,
There are 80 vertical hover elements of 5*455 pixels each, covering
the full effect. Each hover element contains inside elements to define
every layer position, the background image and the lateral background
image. When the hover element is not active (without the mouse over
it), all is inside elements showing images are hidden, with display:
none.
When the hover element is active, the images are set to display:
block, and the position of these are set. These positions have been
calculated and are written in the CSS code for each layer and each of
the 80 vertical hover elements. This is what does the magic.

table.scrollleft is always zero

I have a table with a fixed layout. The columns take up more space than is available so a horizontal scroll bar appears. Currently you can move around in the table using the keyboard arrows. But when a cell is selected that is not in view I need to programmatically tell the scrollbar to move. I thought this would be scrollleft but is not settable and is always zero. Instead I have achieve my desired effect by using scrollIntoView(false). This works but I still want to know why scrollleft was not working.
Please see my fiddle. The function you may want to use is called scrollLeft()
http://jsfiddle.net/ydj5E/
jQuery Docs: http://api.jquery.com/scrollLeft/
MDN: https://developer.mozilla.org/en/DOM/element.scrollLeft

Animating a table with jQuery

I asked a question yesterday on here and got some awsome help, but I need more help concerning more or less the same, only a bit different.
This is my old thread.
So ye, I made this and the idea is that you can customize the table to see it the way you want. for now its possible to drag the columns to change the order and its possible to order the columns on alphabet or high/low. Since I got help here, its now also possible to hide the columns.
Now I want to make the hiding process a bit more smooth, since its hard to see if something is hidden after a click if you use no animation. I use .fadeOut(200); now, but when the fading is done the column just 'jumps' to fill the gap, is it possible to animate this in some sort?
Edit: After thinking some more, I thought that I could just loop a -1px width untill the element's width is 1px and then just hide it, but for some reason that wont work, the table doesnt respond to .width(xxx); or .css('width', 'xxx');. It does change the value, but the td keeps the same width.
This is somewhat of a workaround, and there might be a better solution, but here it is anyway:
Animate the opacity to 0.0. Fadeout does the same, but it also sets display:none after completely fading out. It is the display:none that causes the adjacent column to jump and fill in the gap.
Animating will cause your hidden div to remain there. Now that it is no longer visible, animate its width to 0. This will cause the adjacent div to smoothly take over its place.
Once width is 0, set display:none
Here's a working sample I whipped up. Adjust accordingly to animate width: http://jsfiddle.net/x7BEv/8/
Here's how the magic happens:
$(document).ready(function(){
$('#button').click(function(){
$('#upper').animate({opacity:0.0},'slow').animate({height:'0px'},'slow',allDone);
});
});
function allDone()
{
$('#upper').hide();
}
I'm not sure how important the allDone() method is. You could probably do away with it.
you must use jqgrid
or just for sorting you can use tablesorter which is very easy to implement

Javascript clientHeight and alternatives

I am currently trying to modify a Javascript function that "slides in" a <div>. The script as it is requires you to define the height of the div, so it is mostly useless in dynamically filled <div>s. I found some text on the clientHeight property in javascript, but it would appear that it doesn't support <div>s with display set to none (which is the method used to slide the div in). That makes sense, as the height of that div in the client window is nothing.
Basically I was wondering what other methods you all know of, or if there's a way to get around the clientHeight = 0 when display: none.
Thanks!
Oh, and here's the function I'm using:
function getDivHeight(objName) {
return boxHeight = document.getElementById(objName).clientHeight;
}
A simple solution is to set it's visibility to "hidden" and it's display to "block" and measure it. However, some modern browsers will manage to update the page layout during this short time and you will get a nasty flicker. The easiest way to overcome this is to place the element in an absolutely positioned container with overflow set to "hidden".
I've had luck cloning the element, moving it offscreen, then displaying it to get the client height:
var original = document.getElementById(some_id);
var new_item = original.cloneNode(true);
document.body.appendChild(new_item); // item already hidden, so it won't show yet.
// you may wish to validate it is hidden first
new_item.style.position = "absolute";
new_item.style.left = "-1000px";
new_item.style.display = "block";
var height = new_item.clientHeight;
EDIT: Looking through the jQuery code, they do exactly what Tsvetomir Tsonev suggests. jQuery temporarily sets the style to "display: block; position: absolute; visibility: none", and then measures the height, swapping the properties back after the measurement.
So, it looks like you're stuck with having to do something hackish, whether it's cloning the node or risking having it flicker in some browsers... I like Tsvetomir's suggestion better than my initial hack as it, at least, doesn't involve cloning a node into the DOM that you don't need. Either way, the element must not be set to "display: none" in order to measure it's height. Isn't the DOM wonderful? :-)
EDIT 2: Also worth noting that, after jQuery gathers the height, it adds allowances for padding, margin and border sizes, so you may need to as well.
Yes, an element that is not displayed on the page has no dimensions.
It kind of makes sense. Consider an element that has been created and filled with a bunch of text, but not yet added to the document tree. How high is it? Depends on font-size. How big is font-size? Depends where in the document that div is inserted; its parent font-size would inherit through.
Similarly for an element with “display: none”. It's not rendered, so it has no dimensions. Couldn't we ask “how high would this be if it were ‘display: block’”? Turns out no, because if it were displayed, that in itself could change the dimensions of its parent block, and then the dimension of displayed elements would be inconsistent with the dimensions of non-displayed elements!
The typical solution is to unset “display: none”, measure the height of the element, and then immediately re-set “display: none”. The browser won't redraw in the middle of a bit of JavaScript, so you won't see a flicker on the page.
I nkow you guys solved this a long time ago but I thought I should share this since it quite tricky to get the height of a hidden div tag.
heres what I did after reading your post,
I placed the div i want to slide inside a 1px height div with overflow set to hidden.
you dont even need to set the display of the inner div to none since it is already there and if you use offsetHeight it should return the proper height for all browsers and you can use that height to slide your div up an down.
PEACE!!!
In IE you could try scrollHeight, but I'm not sure if it will work or if it is cross browser.

Categories

Resources