Ionic 2 - virtual scrolling not working as expected - ionic2

I don't know why the virtual scrolling I implemented is looking weird.
I have a list of words and I wanna show them in a page. earlier I iterated these words using a for loop but the scrolling performance was horrible in android devices. So I decided to implement basic virtual scrolling as mentioned in ionic's official documentation.
http://rhymebrain.com/talk?function=getRhymes&word=baby
This is the data That I'm trying to iterate. I only need the words, no other info.
Code for my virtual scroll looks like this:
<ion-card *ngIf="words?.length > 0">
<ion-card-header>rhymes with...</ion-card-header>
<ion-card-content>
<ion-list [virtualScroll]="words" [approxItemHeight]=" '500px' ">
<button *virtualItem="let word" ion-button round small>
{{word.word}}
</button>
</ion-list>
</ion-card-content>
</ion-card>
In my web browser, the results I got are terrible. I will share some screens:
Pic 1: User searches for a word to fetch all rhymes but no data is shown even when response is not null.
Pic 2: If I navigate to another page and come back, I see a few of the rhymes.
Pic 3: If I repeat step 2 or scroll a little down, I see few more words. It looks so weird.
I have no idea why virtual scroll is acting like this. Can anyone tell me what mistake I made or a better solution for this?
thanks in advance

There's a few issues with virtual scroll that are unfortunately not documented. Fixing all these should get you in the right direction.
Predefined Height
All ancestors of your [virtualScroll] must have a predefined height. The virtual list will grab the elements height and based on that, populate the cells. If the height is 0, it will populate only a few cells which make up for the buffer space of scrolling quickly. Don't use inline CSS but for simplicity here's an example.
<ion-content>
<div style="height:100%">
<ion-list [virtualScroll]="items" approxItemHeight="50px">
...
</ion-list>
</div>
</ion-content>
Define Approximate Item Height
In the example above you can see I'm setting approxItemHeight. This is an important step that helps the virtual list with it's calculations.
Don't Wrap In If Statement
Unfortunately you can't put your virtual scroll inside an ngIf, ticket. Your virtual scroll needs to be rendered at the beginning of your components life cycle. So if you wrapped your virtual scroll inside of a condition which from the time of the constructor was equal to true, the issue would not exist. However if some point later on the condition becomes true, you'll have to redesign your implementation.
What I did for this was switch from using *ngIf to using [ngClass]="virtualClass". When I want to hide the virtual scroll I will set virtualClass = 'virtual-hide'.
.virtual-hide {
overflow: hidden;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
You can't use display: none since this will not render the virtual scrolls height, same problem we want to resolve. The above CSS should allow for the element to be on screen and take up the correct amount of space while not appearing to actually be there. This code might need to be adjusted based on your implementation.
Ensure Items Exist
Switching to using ngClass from ngIf will mean your virtual scroll is always in the DOM. Because of this, you must make sure that items (the array for [virtualScroll]) is always set. So make sure it's never undefined or null, instead set it to [] if you want it to be empty.

Related

Popup LOV with multi select in Inline Dialogue has trouble with manual insert

I had an Inline Dialogue region with a page item being a Popup LOV. I needed to be able to select multiple values and be able to manually add more. But once I switched on multi-select the input field contracted to max-width 4px, the only way I found to fix that was to set the item to Stretch Form Item on and have it stretch out. But now came another problem. Now the manual entry was weird, you could only click on the first 4px(or the 4px after the last value if there were already values in there), and text you were writing was not visible until you stopped writing and clicked away.
So I was wondering how to fix this.
Running on APEX 19.2 btw, maybe this gets fixed in next versions
I found that if I hadnt set the Stretch Form Item parameter, max-width was set to 4px no matter what else I tried. If I did set it though, then flex-grow was set to 0.
So I just had the js that shows the Inline Dialogue fix this with a simple js command:
apex.item("P1_LOV").node.style.flexGrow = 60;
Its a simple fix, but it took me a bit to figure out so I wanted to show the answer here in case it helps anyone else

ionic3 slides swipe sensitivity

In my Ionic3 app, I have a slides component with a bunch of slides, and I want to be able to click on each of them. So code would look like:
<ion-slides>
<ion-slide *ngFor="let s of slides" (click)="onClick()">Slide</ion-slide>
</ion-slides>
The problem I have is that very often, when I try to click on the slide, it actually does a swipe of the current slide and shows the next one, therefore the click never happens. This happens mostly using a tablet, as I guess my finger is less stable and if the click is not perfect then it will slide.
Is there any way to make the click less sensitive (so that even a small variation of distance between down and up event is recognized as click not swipe)?
You can just first get your swiper using querySelector:
let mySwiper = document.querySelector('yourSwiperSelector');
Then just change the treshold:
mySwiper.threshold = 100;
It worked for me. In my case it was ionic2-calendar and my selector looked like this:
let mySwiper = document.querySelector('.swiper-container')['swiper'];
There's a lot of options available that ionic don't list but you can see them here in the library that ionic slides uses:
http://idangero.us/swiper/api/
Setting the Touches threshold to a reasonable value should help.
If you have a reference to your slider, you can simply say this.slider.threshold = 100;
<ion-slides pager>
<ion-slide *ngFor="let s of slides" (click)="onClick()">Slide</ion-slide>
</ion-slides>

possible to set position of dropdowns (zurb foundation)?

right now the content of dropdowns is by default to the bottom right.
Is there an option to set it so it goes to the bottom left?
(foundation 5)
The "right" style is being applied through JS. To override this just give #contentDrop a style of #contentDrop{left: -100px !important;} or whatever value you would like to pull left. You will need to adjust the .f-dropdown:after{left:XXpx !important;} and .f-dropdown:before{left:XXpx !important;} stylings to bring the little triangle to the right of the dropdown box.
This is a hack because Zurb-Foundation is still working on a solution to this problem. There is an github issue related to this. I found a Hack here that helped me solve it.
Using this information here is how to get the alignment correct. Add a class bottom-align-left to the content dropdown div:
Search
<div id="drop2" data-dropdown-content class="f-dropdown bottom-align-left">
Then add this to your CSS or SCSS file. You will have to play with the number to get it right.
.bottom-align-left {
margin-left: -375px;
}
Now the triangle shows up in the wrong place. To fix this remove the triangle.
Open _settings.scss.
Find $f-dropdown-triangle-size and set it to 0px i.e.
$f-dropdown-triangle-size: 0px;

How to set starting slide for Foundation Orbit slider

I'm using Foundation's Orbit slider to show levels of a house, the first slide is always the basement but this is not the slide that we would like to start with. We would like the page to first show the first floor, which is the second slide. We are using Foundation 4.
There is nothing in the documentation about setting a starting slide and adding the active class on the second slide in the HTML doesn't solve it either.
Check out my JSBin example: http://jsbin.com/IVisAWA/2/edit. Here the starting slide is '0' but I would like it to be '1'.
I can't find any built in option, you can use the orbit:ready event callback and force a click to the next element.
Code:
$("ul").on("orbit:ready", function(event) {
$(".orbit-next").click();
});
Demo: http://jsbin.com/ekarucuc/1/edit
You can include two lines of code to the foundation.orbit.js to use and customize it your way:
Add this line
self._goto(settings.start_slide, true);
at the end of the "self.init" function.
In the
Foundation.libs.orbit
inside the "settings" list, add this new setting
start_slide: 0
to start always on the first slide by default.
Now, reset the parameter of the starting slide you want to:
<ul data-orbit data-options="start_slide:1;">.
knowing that your list starts at 0, the second item should be 1: data-options="start_slide:1;" in your HTML slide list.
Now you can use even two or more slides in the same page, one starting in the first slide, and the other starting where you want.
I was looking for something similar, but couldn't use Fabricio's solution as I didn't have scope to change the Foundation.orbit.js file.
I ended up enabling the bullet point nav items when initialising Orbit, then just triggering a 'click' on the appropriate bullet point. But I didn't actually want to display the bullet points, so I hid them with some CSS.
Something like:
var button = $('div.orbit-container').find('li[data-orbit-slide="1"]');
button.trigger('click');
And:
div.orbit-bullets-container {
display: none;
}
You can do this after you initialize your orbit slider.
$('#orbit-slide').data('orbit-instance')._goto(indexSlide, true);

Upgrade to zurb foundation 4.3 and Section now hidden on large screen size

I just upgraded from version 4.1 from a month or so back and suddenly my section (horozintal-nav) is being hidden on screen sizes above 768px. Prior to the upgrade it would display as a horizontal nav above 768px and as an accordion on smaller screens.
I am using compass and sass.
I have also tried cutting and pasting their example code from their documentation into the top of my page and I get the same behaviour with that as well.
The CSS that hides the control...
/* line 49, ../../../../../lib/gems/1.9.1/gems/zurb-foundation-4.3.1/scss/foundation/components/_section.scss */
[data-section='horizontal-nav']:not([data-section-resized]):not([data-section-small-style]), .section-container.horizontal-nav:not([data-section-resized]):not([data-section-small-style]) {
visibility: hidden;
}
Is anyone else having this problem?
Seems I just needed to add data-section-resized attribute to my container.
<div data-section="horizontal-nav" data-section-resized>...</div>
So simple fix, but that isn't in the zurb documentation - does anyone one know what that attribute is for?
I ran into this problem as well. The above answer didn't quite work for me because all my tabs were squashed to the top right, overlapping each other.
This thread helped me sort it out:
https://github.com/zurb/foundation/issues/3555
This isn't broken. Sizing can't be calculated correctly when elements aren't visible. If you're going to hide them and then show, you'll need to call reflow or fire the resize event to get things to calculate the correct sizes.
At least for my case, my items were being loaded AFTER Foundation was able to calculate the widths, so it always went to 0.
Hope this helps!