Angular js do not scroll when list element height change - javascript

I have a list of elements. Each element has an expanded and collapsed state.
When user expands one of the element, all other elements need to collapse. The list is inside a div which could be scrolled to allow seeing the entire list.
element 1
element 2
element 3
element 4
element 5
Lets say, element 1 is in expanded state. When I expand element 3, I collapse element 1. The problem is that when I do that, element 3 scrolls up. I want to avoid this and position element 3 to same position.
This is a pseudo code. There could be some minor syntax errors, but do ignore them, since my actual code has lot more going on and I don't want to paste the entire thing here.
The controller will include expand function like:
public expandElement(currentElement: any, previousElement: any) {
// get the height of previous element
var scrollOffset: number = angular.element("#" + this.getAnchorId(previousElement).offsetHeight;
// this function will collapse the element decreasing the height of it
previousElement.collapse();
// scroll to the newly expanded element
this.$timeout(() => {
var anchorId: string = this.getAnchorId(element);
var element = angular.element("#" + anchorId)[0];
var offset = element.getBoundingClientRect().top + scrollOffset;
this.$anchorScroll.yOffset = offset;
this.$location.hash(anchorId);
this.$anchorScroll();
});
previousElement = currentElement;
}
The html will look something like:
<div ng-repeat="element in listElements"
id="{{getAnchorId(element)}}">
<my-directive ng-click="expandElement(element, previousElement)"></my-directive>
</div>
This currently is not working at all, but even if I get it to work, there would be a small UI jump that could happen. I want to avoid scroll completely.
Is there another easy way to just block the scroll when angular expands an element?
Appreciate the help.
Thanks!

I got your problem, but i have one question. Consider you have more elements in the list and you will expand say 50th element then it has to scroll the main container to show the content of that expanded panel, i think it is the desired functionality in the scroll. I know i am not answering your question but, just thought of reconsidering it.

Probably you have to save scroll position and after click function got triggered change the scroll position back to saved state. There could be flick effect. If you want to hide the flick effect, hide the div show with a slow animation. Hope it helps.

Related

Scroll element in to view horizontally

I have a list of divs which are floated left. They are inside another div, which can be hovered over to move that inner block of divs left and right. These inner divs or 'events' have class names which include a year.
I also have a range slider at the bottom. The values of this slider are years. When the range slider is changed I would like the first div which includes that year number to slide into view.
See example here... http://thetally.efinancialnews.com/tallyassets/20years/index.html
Currently when you change the slider value the number changes accordingly, but I don't know how to slide everything so the related numbered div comes into view. They are in a row of floated left divs so can't be absolutely positioned.
In the example above the last event div has a class of 'year1998' so would be a good one to test the code on
var slider = $('#range-slider'),
textbox = $('#range-no');
slider.change(function() {
var newValue = parseInt($(this).val());
textbox.empty();
textbox.append(newValue);
( I need something here which would say...
$('.year'+newValue).comeintoviewplease();
... or something to that effect)
});
Thanks in advance for any help
check this out, the same effect can be achieved using css transitions
http://css3.bradshawenterprises.com/transitions/

jQuery scrolling out of view issue

I am working on building a schedule. So far it's pretty straight-forward. There is one bit of functionality I am having issues with.
I have an ul that has a fixed height to allow scrolling. There are "Labels" (li.dayLabel) withing the ul that separate the hours. What I am trying to do is to have it so that when a label is scrolled out of view it will change the text in the placeholder to it's text. Then once that works, I need it to work in reverse. So when they label scrolls back into view it updates the placeholder. Basically, I am trying to make the placeholder be a title for the available items until another label is then scrolled out of view. This is for scrolling from the top. So as you scroll down the list the placeholder is meant to be a title for the section you are viewing until you reach another section and it takes its place. Then when you scroll back down I need it to replace the text with the previous li.dayLabel so the sections stay organized. I hope this makes sense.
You can see what I am trying to do by looking at the original that I am basing this off of. Notice how the placeholder changes as you scroll down the list and changes back when you scroll back up.
Demo: jsFiddle // Note: line 54 is the part that is in question
I originally used:
$(".snlf-schedule-list li.dayLabel:visible:first").text();
as the :first selector is suppose to only match a single element.
I later tried:
$(".snlf-schedule-list li.dayLabel:visible").filter(":eq(0)")
as this is suppose to be the same thing.
It seems that when an element is out of view it still is considered :visible I believe this is my issue.
Am I doing this completely wrong? I was under the impression that when you scroll an element like this it should no longer be :visible. After reading the documentation I have learned that this is not the correct selector to use.
It would appear that scrollTop is how I should be doing this. Now I have used scrollTop for scrolling down pages to disable animations when not in view but I am not clear on how to untilize this for a ul with scrollbars.
I tried:
var _first = $('li.dayLabel:first'); // next element to scroll out of view?
if( $(this).scrollTop() > (_first.offset().top+_first.height())) {
// Out of view
console.log("out");
} else {
// in view
console.log("in");
}
Updated Demo: jsFiddle
But it seems to be redundant as it's already calculating the first element so I am not sure how to get the correct element (the next one that's about to scroll out of view.) Then I need this to work when they scroll back up...
Any insight on this is much appreciated. Hopefully it's something simple I am just over complicating or missing completely.
Thanks,
Jeremy
The solution for my case was:
// Set placeholder text on scroll
var _scrollCagePositionTop = $(".snlf-schedule-list").offset().top;
var _first = $('li.dayLabel:first'); // first dayLabel element
$(".snlf-schedule-list").scroll(function(){
var _lastOffText = $(_first).text();
$("li.dayLabel").each(function() {
if ($(this).offset().top < _scrollCagePositionTop) {
_lastOffText = $(this).text();
}
});
$("#schedule-placeholder").text(_lastOffText);
});
What I did was set the known position of the top of the scroll cage (_scrollCagePositionTop)
When the user scrolls I set a variable _lastOffText that keeps track of the last item text content when scrolled out of view (less offset top than the palceholder). I then set this value to the placeholder.
This method allows me to have the proper text in my placeholder when the user scrolls up or down.
To fix the issue of an empty placeholder when the user scrolls back to the top I just set the default of _lastOffText to be the text of the first label ($(_first).text())
Hope others find this useful.
Here is the working demo: jsFiddle Final

JScrollPane Dynamic Height

The demo page referenced can be found here.
I'm trying to determine a way that on the click of a parent category (ex: Stone Tiles, Stone Sinks), that the JScrollPane would re-determine the current height and adjust as needed. Unfortunately, my attempts to do so have not worked yet.
I referenced the example here which provided the following function (to do a refresh)...
api.reinitialise();
I've tried to setup this function to be triggered by the category parents like so...
var pane = $('.menuwrap')
pane.jScrollPane();
var api = pane.data('jsp');
var i = 1;
$("li.expandable.parent").click(function() {
api.reinitialise();
});
Unfortunately, while I was able to verify the click is being rendered, the function (api.reinitialize) doesn't appear to be working. I'm hoping that a fresh pair of eyes could point me in the right direction. :-)
Thanks!
The problem is that api.reinitialise executes immediately after the click, and the li element will not have expanded yet so when jscroll pane goes to to recalculate the height it gets it wrong. You can try adding a delay but the best solution would be to bind api.reinitialise() to an event that's triggered once the your list has finished expanding. I'm not sure how you're expanding the div within the li but if for instance it's using .animate, you could bind the api.reinitialise to the animation complete event.
Also noted that not all the parent li's have the class parent associated it to them. I would expect you would want the pane to reinitialize on the expansion and collapsing of all the main li elements.
Hope that helps !
Cheers :)
What you can do is have your inner divs expanded by default, and then close them with jquery, rather than in the CSS directly.
So instead of doing this:
.mydiv.closed {display:none}
do this in your jquery after the elements are drawn to the page:
$('.mydiv.closed').hide();
This will load the jscrollpane at the necessary height, and then collapse what you want to be initially hidden.

jQuery add close buttons dynamically on elements

I'm trying adding fancy close buttons dynamically to html elements
code is:
function add_close_box(element,img_close_box,base_url_close_box){
var i;
$.each($('.'+element),function(i){
$(this).addClass('close_box'+i);
var x = $('.close_box'+i).offset().left;
var y = $('.close_box'+i).offset().top;
$('body').append('<img src="'+base_url_close_box+img_close_box+'">');
$('.img_close_box_'+i).css({'position':'absolute','top':y-10,'left':x+$('.close_box'+i).width()-20});
$('.img_close_box_'+i).live('click',function(){
var hei = $('.'+element).height();
$('.img_close_box_'+i+','+'.close_box'+i).hide();
$.each('.'+element,function(e){
$('.img_close_box_'+(e)).animate({
'top':'-='+hei
},0);
});
});
});
}
it works good but when click on button and element is fadeOut() other close buttons doesn't follows their own related element cause of absolute position they remain in same positions while elements scroll up (first element fadeOut next element scroll up and close button remain in same position)
i would like that close buttons could follow their related element.
Also cause my lazy mind i would like to know if anyone knows some good jquery plugin to do what I'm trying to code, something with also ajax callback after closebox button click (do not reply to watch jQuery UI please :) )
thanks ;)
I have to make a few assumptions because you haven't posted your markup. I think Diodeus is on the right track. You're using absolute positioning for your new close button. Absolute positioning will look up in the DOM until it finds a relatively positioned element to anchor the coordinates. if the element you pass in doesn't have the property position:relative then the button could be positioned anywhere.
Two possible fixes:
Add relative positioning to everything you add the close button to:
element.css({'position':'relative'});
Obviously this will replace any other previously set positioning. There's a chance this blows up your layout if you're adding close buttons all over the place.
The second option is to make sure the only relatively positioned element is something high in the DOM, so all of your close buttons are positioned based on the same thing. It's a little hacky, but then you can position them based on the x and y of the element:
var x = element.position().x;
var y = element.position().y;
// you can add the necessary offsets like element width or height

error offset().left in null or not an object [duplicate]

I have a menu system made up of divs and i want to animate the left property to slide each time the user mouses over a menu item but i need the outer div(which is black) element to expand as the menu items move left to right also I want the div element(.container) to slide back and contract the outer div element(this black div which is 0 width) I have a basic example done in jsFiddle it olny moves the elements to the left
Having a little trouble fully understanding, but is this sort of what you mean?
http://jsfiddle.net/V3RHr/2/
If I could rewrite your html a bit, I would put make each .menu-item into an unordered list.
When you mouseenter the unordered list, you expand the second container. Inside that mouseenter function, I would have a second event when you mouseenter a list item, you populate the second container and stopPropogation.
You could probably still do it with a mouseenter on the first container, and another mouseenter on the div.menu-item, but your first container has extra height and width.
You should be able to fix the left is null issue by having the code not execute on the last .content, like this:
$('.container').not(':last').find('.menu-item').mouseenter(function () {
This will not apply to the menu-items within the green box.
For the re-show issue, I would change the way you are showing. Instead of sliding the box out from behind the other, you can position it where you want it to end up and hide it, then you can use:
.animate({width: 'show'})
Which will give a similar sliding effect.
That, or do it similar to my response to your other question, only without the collapsing I had previously:
http://jsfiddle.net/V3RHr/3/

Categories