Responsive sticky sidebar, need to update width - responsive-design

I've got a responsive sticky sidebar started here: http://codepen.io/cmegown/pen/fjqzH. I've got the sticky part down, and it's responsive in relation to the width of the original viewport width. However, if you scroll down and then change the viewport size you'll see that the width of the sidebar does not change.
I know I need to update the sidebarWidth variable, but I'm sure exact how/where to do that.
Any help is appreciated, thanks!
EDIT:
This one kind of got left behind amid some other projects, but I'm back to finish this. I got a little further, but still can't seem to figure out how to update the sidebar width if the user scrolls down the page then expands their browser (or rotates their device). I have some commented code in the JS panel where I left off.

Just put the width calculation in your scroll function.
$(function () {
// cache selectors
var wrapper = $('.wrapper');
var sidebar = $('.sidebar');
// get some maths
var sidebarTop = sidebar.offset().top;
var sidebarOffset = 25; // is .wrapper padding
// sticky logic
$(window).on('scroll', function () {
var windowTop = $(window).scrollTop();
var sidebarWidth = Math.round(wrapper.width() * 0.3); // is .sidebar width
if (sidebarTop < (windowTop + sidebarOffset)) {
sidebar.css({
position: 'fixed',
top: sidebarOffset,
width: sidebarWidth
})
} else {
sidebar.css({
position: 'static',
width: '30%' // original CSS value
})
}
})
})
There's a little bit of overhead there, since it has to calculate the width every time you scroll. The alternative would be to put it into a $(window).resize() function so it figures out the width when you resize the window.

Related

Angular1 perfect scrollbar : After refreshing the data, how to get it back to the top

I set the scroll bar for the table. When I scroll to the bottom of the current page and click on the next page, the scroll position does not get back to the top. How can I get it back to the top after the data is refreshed? Thanks.
It could be done a lot of ways, how are you handling pagination? You could place a ng-click on the pagination button that scrolls you to the top. A code sample or plunkr would be helpful.
You could do something like below using regular JS.
var btn = document.getElementById('x');
btn.addEventListener("click", function() {
var i = 10;
var int = setInterval(function() {
window.scrollTo(0, i);
i += 10;
if (i == 200) clearInterval(int);
}, 20);
})
body {
background: lightblue;
height: 600px;
}
\HTML in view layer
<button id='x'>click</button>

Animating a height value for text input

So i am using react-native-autogrow-textinput in order to have an editable document viewable in my application. I am currently trying to work around the keyboard in order to adjust the height of textinput box, so that all text is visible. I have found the following code to do so
componentWillMount () {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this));
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide.bind(this));
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
keyboardDidShow(e){
let newSize = Dimensions.get('window').height- e.endCoordinates.height - 150;
console.log(e.endCoordinates);
this.setState({docViewHeight: newSize});
}
keyboardDidHide(e){
let newSize = Dimensions.get('window').height - 170;
this.setState({docViewHeight: newSize})
}
However, the result i am getting is: When the keyboard is animating off screen, the height of the textinput remains the same, let newSize = Dimensions.get('window').height- e.endCoordinates.height - 150, untill the keyboard has finished sliding off screen.
The height then adjusts to fill the whole screen again, except it sort of 'pops' into the new height. How do i get the value of this height to gradually grow, so it looks like it is simply extending to fit the whole screen? Ill post my Autogrow TextInput code below also. Any help would be much appreciated.
<AutoGrowingTextInput
ref="editText"
editable = {this.state.editting}
style = {{fontSize: fontProperties.fontSize+3, marginLeft: 18, marginRight: 18, marginTop: 15}}
/*animate this*/ minHeight = {this.state.docViewHeight}
animation = {{animated: true, duration: 300}}
//has some other confidential props here for onChange etc
</AutoGrowingTextInput>
Found the answer myself, after digging through some library files.
The solution is to use a keyboardWillHide event listener instead of keyboardDidHide.
This will fire before the keyboard begins its outro animation. Ive put the code below.
componentWillMount () {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this));
this.keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide.bind(this));
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
this.keyboardWillHideListener.remove();
}
keyboardWillHide(e){
let newSize = Dimensions.get('window').height - 170;
this.setState({docViewHeight: newSize})
}

mousewheel scroll down doesn't work when mouse is on the grid - ui-grid angular js

For my Angular js grid work, I am using ui-grid(v3.1.1) to implement the grid table. When I change the pagination size, I am having trouble to scroll down using mousewheel. When I hover over the mouse on scrollbar, then scroll up and down both are working fine. Strangely, the scroll up using mousewheel is working fine too. Its just the scroll down that doesn't seem to work. I fail to understand the reason for it.
I have disabled the scrolling when not required using:
.ui-grid-render-container-body .ui-grid-viewport {
overflow: auto !important;
}
Other than this I have not changed any of the default settings. Why is it that the mousewheel scroll down won't work when hovered over ui-grid? Please help
I commented out event.preventDefault() on line 2859 of v4.0.2 (in gridUtil.on.mousewheel function).
Can't say what other impact this may have, but worked for my usage.
Experienced this mousewheel/trackpad drag issue in v4.0.2 & v4.0.3 in a grid with pagination & filtering enabled and with CSS modifications to enable cell word-wrap.
.ui-grid-viewport .ui-grid-cell-contents {
word-wrap: break-word;
white-space: normal !important;
overflow:visible;
}
.ui-grid-cell {
display : table-cell;
height: auto !important;
overflow:visible;
position: static;
}
.ui-grid-row {
height: auto !important;
display : table-row;
position: static;
}
.ui-grid-row div[role=row] {
display: flex ;
align-content: stretch;
}
Tried Paul's fix and it worked but requires change to core code. Also, our requirements called for showing the entire table on the page based on the data rather than a fixed height table with scroll. So we couldn't use.
Instead, I worked around the issue by implementing a dynamic grid height solution.
Added ng-style to the grid as follows:
<div ui-grid="gridOptions" style="float:left" ui-grid-selection ui-grid-pagination ng-style="gridHeight()" class="myGrid"></div>
Disabled grid scrolling:
$scope.gridOptions.enableHorizontalScrollbar = 0;
$scope.gridOptions.enableVerticalScrollbar = 0;
Wrote function gridHeight as follows (uses jQuery):
$scope.gridHeight = function() {
var outerHeight = 50; //buffer for things like pagination
$('.ui-grid-row').each(function() {
outerHeight += $(this).outerHeight();
});
$('.ui-grid-header').each(function() {
outerHeight += $(this).outerHeight();
});
return { height: outerHeight+"px"};
};
This satisfied our requirements.
Another way to solve this - if the grid has no scroll at least - is to redefine the prototype function atTop & atBottom on uigrid's ScrollEvent. This will not need changes to uigrid's code, one just has to inject ScrollEvent in the controller or app.run().
The grid swallows any scroll event if its possible to scroll, but does not handle it if there are no scrollbars present.
The original code also fails an isNaN check on this.y.percentage - i think it should be as it is in the comment below.
ScrollEvent.prototype.atTop = function(scrollTop) {
return true;
//return (this.y && (this.y.percentage === 0 || isNaN(this.y.percentage) || this.verticalScrollLength < 0) && scrollTop === 0);
};
ScrollEvent.prototype.atBottom = function(scrollTop) {
return true;
//return (this.y && (this.y.percentage === 1 || isNaN(this.y.percentage) || this.verticalScrollLength === 0) && scrollTop > 0);
};

Scrollmagic duration

Is there a way to set the scrollmagic duration on a scene as long as the height of the scene? I want to use the class toggles functionality and certain scenes are heigher than the viewport height.
<section id="sec1">I'm 400px in height</section>
<section id="sec1">I'm 100% in height (1 viewport)</section>
<section id="sec1">I'm 2500px in height (2,2 viewports)</section>
Duration in px: {duration: 400}
Duration in vh: {duration: '100%'}
Duration in element height: ???
Thanks for helping!
Try using $("#sec1").height() in the duration option.
To make the duration the height of a scene, you would need to find the height of the item, and then apply that to the duration.
Seeing as all your scenes are sections, you could loop through all sections.
(function() {
let controller = new ScrollMagic.Controller();
// Run through all sections
let items = document.querySelectorAll("section");
items.forEach(function(element, index) {
let height = element.clientHeight; //height of current element
let scene = new ScrollMagic.Scene({
duration: height
//Other scene options go here
})
.on("leave enter", function() {
//Element instructions
})
.addTo(controller);
});
Note: Unless the goal is to give each section their own ID, I would change the ID to class on your sections as pages should only have an ID appear once on the page, while classes can be used multiple times.
An example of this in use.

AngularJS animate dynamic margin

I have an element that appears when the user clicks a button elsewhere on the screen. The element appears to come out of the top of the screen. The element by default needs to be tucked out of view above the screen, so I will have a margin-top style that is based on the height of the element (and will be a negative value). This cannot be hardcoded in css because the element height may vary. When I click the button, I want the element margin-top to change to 0 and I want a transition animation.
The sample shown on angularJS documentation is for adding a removing a class. This would work fine if I knew the values to be set and could code them in CSS, however I cannot. What is the correct way to solve this?
The code below works for displaying and hiding my element using a margin but there is no animation. How do I trigger an animation here when the margin changes?
https://docs.angularjs.org/guide/animations
Quote Total: {{salesPriceTotal + taxesTotal - tradeInsTotal | currency}}
<div class="totals" ng-style="setTopMargin()">
// totals stuff here.
</div>
$scope.setTopMargin = function() {
return {
marginTop: $scope.marginTop
}
};
$scope.$watch('showTotals', function() {
var margin = $scope.showTotals ? 10 : -160 + $scope.modelTotals.length * -200;
$scope.marginTop = margin.toString() + 'px';
});
I added the following code per a suggested solution, but this code is never hit.
myApp.animation('.totals', function () {
return {
move: function (element, done) {
element.css('opacity', 0);
jQuery(element).animate({
opacity: 1
}, done);
// optional onDone or onCancel callback
// function to handle any post-animation
// cleanup operations
return function (isCancelled) {
if (isCancelled) {
jQuery(element).stop();
}
}
},
}
});
As the documentation explains: "The same approach to animation can be used using JavaScript code (jQuery is used within to perform animations)".
So you basically needs to use animate() from jQuery to do what you want.

Resources