ngInfiniteScroll initially fill container-element with results - angularjs

I have a scope with 150 elements in it and I'm using ngInfiniteScroll to alowe users to scroll through those results. But in my project I can't get the directive to initially fill the container element. It shows the number of results that I want to add whenever the bottom of the element has been reached, and because of that there's no scrollbar so users can't scroll to get to the extra content.
http://plnkr.co/edit/B7CRjvdQ9paytwl5csKi?p=preview
$scope.loadMore = function() {
for(var i=0;i<10;i++) {
if($scope.movies.length) {
var movie = $scope.movies.pop();
$scope.pagedData.push(movie);
}
}
}
If I change the 10 to 20 it starts with 20 examples. The desired result is that the container element is filled with results untill a vertical scrollbar shows up, from then it should only add results when the bottom of the element has been reached.

You can use infinite scrolling feature of ag-grid
AG-Grid

Related

Change text when image is displayed on scroll react

I'm building a portfolio website with React with large full width vertically scrolling images. There is a single text box on the side of the webpage that I would like to display the title of each image as each image comes into view.
Any recommendations on how to change the text in a DIV when an image comes into view? I'm not even sure what to search to find an answer to this. Any help is much appreciated. Thanks!
You can attach an onscroll listener to detect when the user scrolls. Inside the listener, you need to do some math to calculate which element is currently viewed. The variables you can use for the calculation are scrollTop (on the container, used to determine the current scroll position) and the clientHeight of each element.
let nameDisplayDiv = document.getElementById('display')
let containerDiv = document.getElementById('container')
function refresh() {
let scrollTop = containerDiv.scrollTop + containerDiv.clientHeight / 2
let height = 0
for (let child of containerDiv.children) {
let top = height
let bottom = height += child.clientHeight
if (top < scrollTop && bottom > scrollTop) {
// Found the element that's currently viewed!
nameDisplayDiv.innerHTML = child.style.backgroundColor
break
}
}
}
containerDiv.onscroll = refresh
Here's a working fiddle:
https://jsfiddle.net/uxh91Leq/2/

Delete one slide from a Google Slide Presentation using Google Apps Script

I need to use Google Apps Script, not the API.
I create an empty presentation
It seems newly created presentations always contains an empty slide by default
I insert a slide (taken from an other prez) into the presentation.
-> I'd like to delete this empty slide, so that the presentation contains only the slide I paste into it.
The code I have:
var presentation = SlidesApp.create("my new presentation"); // creates an empty slide in the prez
presentation.insertSlide(0,slides.pop()); // a slide from a deck of slides collected elsewhere
presentation.getSlides().pop(); // here trying to delete the empty slide, doesn't work: the slide remains in the presentation.
presentation.saveAndClose();
You need to remove the Slide. pop() just removes it from the array and returns the last slide in the Slide [].
var lastSlide=presentation.getSlides().pop();
lastSlide.remove();
To remove the first slide, use the shift() method. The shift() method pulls the first element off of the given array and returns it.
// Remove first blank slide
const removeFirstSlide = newPresentationSlide.getSlides().shift()
removeFirstSlide.remove()
But remember, to remove the first blank slide, you need more slides in your Presentation.

React-slick Slider stays on same page if slides items are changed

I am stuck with an issue with react-slick. The subject line may not make sense, but I will try to explain the scenario in detail. See this example fiddle to see the issue in action.
var DemoSlider = React.createClass({
getSlides(count) {
var slides = [];
for(var i = 0; i < count; i++) {
slides.push((<img key={i} src='http://placekitten.com/g/400/200' />));
}
return slides;
},
render: function() {
var settings = {
dots: false,
infinite: false,
slidesToShow: 3,
slidesToScroll: 3
}
var slides = this.getSlides(this.props.count);
return (
<div className='container'>
<Slider {...settings}>
{ slides }
</Slider>
</div>
);
}
});
In this demo, initially the slider shows 20 slides (3 per page). The idea is that if you click the button, it will generate a random number, which would be the new number of slides. The code is fairly simple and self-explanatory.
To reproduce the problem,
1. keep on clicking Next arrow until you reach the last slide.
2. click on the button that says 'Click' to generate a new random number of slides.
My expectation was that the slide will go back to the first slide but not to stay on the page where it previously was. Even worse, if the new number of slides is lower than the previous number, the user will see a blank page with no slides. On clicking Previous error, he/she can go to the previous slides, and everything works normally but the initial display ruins the user experience.
Is there something I am missing to add in the code, or is this a bug?
Thanks,
Abhi.
I would say it is rather a buggy behavior, but still you can achieve what you want by forcing a redraw after new collection has been passed as props, by resetting react's key:
<DemoSlider key={Date.now()} count={this.state.count}/>
UPDATED FIDDLE
Quick workaround: When you change to a new set of slides, remove the component, and reconstruct it again. It would then start with the first slide. You can do this by incrementing the key attribute of DemoSlider.
For a proper fix, you'd need to tell the component to change the 'current slide', so that it's not looking at a slide index beyond the end, but a casual look at the source at https://cdnjs.cloudflare.com/ajax/libs/react-slick/0.11.0/react-slick.js suggests it currently does not allow this. A change would need to be made to InnerSlider.componentWillReceiveProps() to check state.currentSlide against props.slidesToShow and state.slideCount.
It would also benefit from allowing currentSlide to be passed as props.

Getting correct height of an app part after removing item from repeat

I'm building an app part in sharepoint (o365) using angularjs, which displays a list of items i'm following (docs, sites). I display the items as tiles (in rows of 4 below each other), and to fit the app part nicely on any page, I calculate the height of the most outer div (topContainer) which contains all items). I calculate the height when the ng-repeat finishes rendering (with a custom directive). The resizing is done with a postmessage:
var resizeAppPart = function (width, height) {
if (senderId && hostweburl) {
var message = "<Message senderId=" + senderId + " >"
+ "resize(" + width + "," + height + ")</Message>";
window.parent.postMessage(message, hostweburl);
}
}
The height and width are provided by
var heightDoc = $("#topContainer").height();
var widthDoc = $("#topContainer").width();
myUtils.resizeAppPart(widthDoc, heightDoc);
If I use
$(document).height/width();
it delivers the same result.
This works perfectly when loading the page.
However I also provide a button which allows a user to 'unfollow' any of the displayed items. Then the item disappears (splice from the array, the repeat gets updated nicely), and I try to recalculate the height of the app part (so no gap remains when unfollowing an item). I can successfully call the recalculate size function for the app part (that's not the problem) however I just can't get the right height of the app part.. The height remains the same as before unfollowing an item, even though there's now a gap where the unfollowed item was..
So I'm trying to find a method to get the right height of the app part after removing the item from the array. Any Ideas?

How to implement a AngularJS Google Images style rows with center content bar

I have an angular app with rows of four boxes followed by a sliding div that opens and displays information from the above boxes. I first tried
for (var i = 0; i < data.length; i++) {
if(i % 4 == 0) components.push([]);
components[components.length-1].push(data[i]);
}
return $scope.components = components;
});
Using nested ng-repeats I would push 4 in then the bar would be put in then rinse and repeat. I could use $parent to push info into the sliding div and just the bar below the row would open and populate. When I tried using the filtering with this method it would filter out per row but would leave the number of rows intact. So I tried using a single ng-repeat with a switch case to add the bar every 4. The filtering works now but the scoping figures out to the sliding bar being the child of the box in the row and using $parent. now opens and populates all the sliding divs.
If I'm not doing a good job describing what I'm trying to do think of google images and the bar that pops up in-between rows of images. Except instead of having varying number per line I always have four.
I can make my own filters from scratch and apply them inside the controller before I use the first method I tried but I feel like there must be an easier way
I'll leave the ng-animate for the slide out to you, but here's a basic directive that should point you in the right direction. (I didn't test this code, so there might be typos.) Remember, if you're doing UI components, you want to be using a directive.
module.directive('slidePanel', function() {
return {
restrict:'E',
scope: {
cards:'='
},
template:'<div>
<div class="cardrow">
<div ng-repeat="c in cards" class="card-panel">
{{c.cardTitle}}
<button ng-click="openCard(c)">Open</button>
<!-- html for each card here ->
</div>
</div>
<div class="carddetail" ng-show="activeCard">
{{activeCard.title}}
<!-- html for card detail here-->
</div>
</div>',
link: function(scope,el,attrs) {
scope.activeCard = null;
scope.openCard = function(c) {
scope.activeCard = c;
}
}
}
});
<slide-panel cards='cardVariableFromMyController'></slide-panel>

Resources