Change item height in famous-flex list - javascript

I have a list in a FlexScrollView.
I'm selecting an item in the list according to some logic, and I need the selected item to expand. Since a change in height won't be noticed by famo.us I'm looking for a way to make it work. Any ideas?
So far I have tried a css transition that occurs when the selected surface gets selected, but of course this doesn't change the position of the other items because of how famo.us works.
I also tried to add a StateModifier as a datasource (wrapped with RenderNode) instead of directly adding the surface. I then tried to make the transition happen via the StateModifier I created but it doesn't seem to move the surface at all, even the completion function of setTransform isn't being called.
Update:
I managed to get the item to animate via the RenderNode, but the other items stay put and get drawn over by my expanding item. Added the question to famous-flex github page https://github.com/IjzerenHein/famous-flex/issues/53.

Solved it by using setSize animation instead of setTransform. For some reason my eyes insisted that the docs don't say anything about animating size.

Related

How to animate transformed component between rerender?

I am trying to animate my components after they are dropped into a new position. I use react-beautiful-dnd for drag and drop.
sandbox example for this situation
Here you can see, that when I drag one element from one list and drop to another list, that dropped item first drops to the last position of the list, and after that, it goes directly to the first position of the droppable list.
When dropping, it is dropped by using transition, but after pushing it to first position (here react does rerender), it only updates the view without animating (i know that it is normal behavior). I tried to add a transition to those elements, but that didn't help me.
Is there any way to achieve that?

How does jQuery Slidedown get final height of hidden item before showing it?

I'm trying to replicate jQuery slideDown() in GSAP and I'm having trouble working out how jQuery calculates the height of an item which is currently hidden as if it was set to height:auto.
I've tried trawling the code on GitHub but can't find any code which seems to be doing this in jQuery.fn.slideDown or jQuery.fn.animate which it calls.
There are several similar questions on SO and several solutions proposed, all of which seem to have their own problems:
Clone the element, position it off screen and calculate its height. This won't work if the element or any of its child elements have a height set by CSS styles which require the element to be in its original place in the DOM (e.g. an .accordianItem might only be styled if it's inside its .accordian).
Display the item, remove height:0 and quickly calculate the height before hiding the element again and then stating the animation. This might flash the content quickly while calculating the height.
Use visibility:true to show it in place while calculating the height. This would stop the flash and still keep the element in the same position in the DOM for correct height calculation, but it would still push other items below it down because visibility:false items still have a height.
Calculate the height of an item before it's hidden and store it in a data attribute so we know it when we want to open the item later. This won't work if any dynamic content changes the height of the item whilst it's hidden.
jQuery slideDown() "just works" every time so I'd be really interested to know how it works, but I just can't work out where it's doing this. I'm also surprised that GSAP can't do this out of the box, or that nobody has shared a proper solution to this before.
Any help would really be appreciated.
It turns out that if you use $.height() to get the height of an element with display:none it doesn't return 0 as you would expect, it actually sets visibility:hidden, position:absolute etc. and sets display to block to give you the correct height back. I assume this is what's being used internally when doing a slidedown.
This answer helped me a lot.
jQuery: height()/width() and "display:none"
Just to be clear about how this seems to avoid all the problems in my original question. It's basically doing number (3) but avoiding the problem of pushing lower content down the page because it's also set to position:absolute while the height is being calculated. A very simple elegant solution

Is there a way to make a div display "upwards" when it is going to be cut off by overflow:hidden?

I'm using Harvest Chosen for some dynamic select elements, but I'm running into a problem where if the select element is near the bottom of the page the select list gets cut off. The containing div is set to overflow:hidden, and for some reason changing that to overflow:visible results in a scrollbar showing up inside the container div.
It would be really nice if I could just get the options list to behave like a normal dropdown, and render "upwards" when the bottom would get clipped.
So is there some magic css (or maybe javascript/jquery) that could force the div to show on top of the select element instead of below it, but only when it would be cut off by the containing element?
Or better yet an option in the Harvest Chosen plugin that I missed?
Looks like even in chosen 1.2.0, it still has the same behavior. I'm surprised nobody has added this feature yet. The alternative: use Select2.

jquery "empty" changes the scrollbar

i am updating content with ajax call from server.
after the update, i empty the wrapper div, that contains the data, and fill it again with the new data.
so far so good.
the problem is - that on a
$('#MessagesContainer').empty();
method - the scrollbar changes back up.
so if someione want to add data and he is in the bottom of the page, the scroll goes back up.
this action makes sense, but for this particular action i want to avoid it since it's not so "user-friendly".
you can use $('#MessagesContainer').html('');
This may work.
If the container you are emptying is almost all the content in the site that behaviour makes sense since for a millisecond the browser doesnt need a scrollbar.
Try just append a new container with the new messages and then remove the old one, in that way the user wont have any changes to the scroll state. Howere if the user was looking at something below the message container and there are more messages now than before the user might have to scroll down some.
Give you #messagecontainer a height with css. or depending on the layout add a second div with a min-height inside the scrolling div and then update the content of the inner div.
Add a height or min-height css property to the #MessagesContainer div this will mean that even when the contents are empty it still maintains a reasonable height on the page - this will keep the srollbar present
well, thanks for your answers.
use .html() would probably be better than .empty() and re-append the data.
but, the thing is that for my implementation that is not possible.
so what i did is implemented
.RemoveAfter(x) function
that remove all the elements after index 'x' in the collection and then append data from this 'x' index. that did the trick. the scrollbar stays where it is. it's not 100% percent user-friendly since it make some of the data disappear for a milisecond and then it comes back, but at this currently point, it's the best i could think of.

How to display the latest called object on top?

I'm creating a custom select plugin. Everything is going great, but the dropdowns (<ul>-objects) are overlapping on each other :(
I understand, that the overlapping order is set after the elements order on page or when they are created. So my question is: What is the method to make the latest opened/shown object (<ul>) on top of the hierarchy?
I just need the correct method. I'm not going to copy the full code, but a little example:
$('#trigger').click(function () {
new_dropdown.slideDown();
});
(A picture is worth of 1000 words)
So lets say, that I open the green select the last.. How can I make it on top of the yellow one?
EDIT
For easier testing I created jsfiddle. For future references I'll post the link: http://jsfiddle.net/hobobne/uZV5p/1/ This is the live demo of the problem at hand.
What you're looking for is the CSS z-index property (higher values put elements at the front).
You could probably just set them in ascending order (e.g. set green one to 1000, yellow to 1001), but if you really need to bring it to the front when clicked, you can change the z-index with javascript
var zindex=100;
$("#trigger").click( function() {
newdropdown.css('z-index', ++zindex);
});
Here's a demo: http://jsfiddle.net/waitinforatrain/Vf7Hu/ (click the red and blue divs to bring to front).
Edit: gilly3's approach is better, and as was mentioned there may be some issues with older versions of IE.
Two ways:
Set a z-index
Setting a z-index will change the default stacking order. You can have a counter that increments and use that to set the z-index of newly stacked items. You may have issues with IE 7 or earlier, though, and those can be fixed by setting the z-index of other items. https://developer.mozilla.org/en/Understanding_CSS_z-index/Adding_z-index
Use absolute positioning, and append the div to the body
If you use absolute positioning, you can append the div to the body and still have it appear below the element. If you append the div to the body, the one last added should be on top, because of the default stacking order.
Give it a class when it is opened, and remove that class from the previously opened ones:
$(".slidedown_active").removeClass("slidedown_active");
$(this).addClass(".slidedown_active");
Then your users can use z-index in their style definition for that class to ensure the active list is always visible.
The reason I don't recommend setting the z-index directly is because you can mess up your users' layout unnecessarily. These kind of overlap issues can be a real headache for a web developer. For a plugin to try to guess at how to resolve overlap issues, without any knowledge of the code or design, would be virtually impossible. Instead, give your users the tools they need to fix the overlap issues themselves. It may be that your users would never encounter overlap issues, so setting the z-index for them would be pointless at best, and potentially harmful.

Categories