Reload carousel items - sencha-touch

I need to reload the items from my carousel (I clicked on an item and a panel gets destroyed, then when I try to go back, I need to rebuild the carousel)
For this I am removing the items of the carousel by doing:
var len = cards.length;
for(var c = 0; c < len;c++)
this.myCarousel[0].items.remove(cards[0]);
then I set the cards again and set the carousel items again:
this.myCarousel[0].items.append(cards);
this.doLayout();
but after doing this, the cards dont get set right, they just get written on top of each other, no carousel effect gets done. Also the cards start being drawn under the carousel's toolbar, instead of starting below the toolbar.
The first time when I load the cards it works perfectly (when I build the carousel from scratch), but if I delete the previous cards and add them again, they don't get displayed properly, I hope someone can help me.
Thank you in advance

Do the adding and removing on the carousel itself as it has methods to do this:
this.myCarousel.removeAll();
var items = [];
for (...) {
items.push(<item def>);
}
this.myCarousel.add(items);
this.carousel.doLayout(); // Force the carousel to re-render
this.myCarousel.scrollToCard(0); // This will send the user back to the first card
If the user was at a different card when you run the above (say, if you put this into an orientation check) then you should return them to the correct card like so:
var curIndex = this.myCarousel.items.items.indexOf(this.myCarousel.layout.activeItem);
// Now do removing and adding
this.myCarousel.scrollToCard(this.myCarousel.items.items[curIndex]);
You have to use the index as the item will be removed.

id should only be used for debugging. There are better ways to resolve a component than use id that can get you into trouble.

Related

zooming the page will reset the carousel

Is there a way to avoid reset the carousel after the user zoom in/out the browser page?
I found pages with similar carousel and this behaviour doesn't happens.
Go to spartacus demo website https://spartacus-demo.eastus.cloudapp.azure.com/electronics-spa/en/USD/, in the carousel navigate to the next block of slide, then zooming the page, you should see the carousel reset to the first block of slides.
This behaviour of the CarouselComponent is expected. Its service depends on window.resize event to adjust the number of items on carousel page whenever the window got resized.
If you consider it as a bug, please create an issue in the Spartacus GitHub repository. Team will take your proposal into consideration.
There is one way this can be handled.
In DOM, instead of using Spartacus's activeSlide variable for rendering the UI, use one tempVariable named say tempActiveSlide
Reassign the tempActiveSlide only if the items per slide are changing. This count will change whenever the window resizes and which is as per the functionality of CarouselService.
Ref - https://sap.github.io/spartacus/injectables/CarouselService.html#source
This way, the carousel on UI will only reset if the number of items per slide have changed. Otherwise it wont reset.
TS code:
tempActiveSlide;
itemsPerSlide = 0;
ngOnInit(): void {
super.ngOnInit();
this.tempActiveSlide = this.activeSlide;
this.size$.subscribe((items) => {
if (items !== this.itemsPerSlide) {
this.itemsPerSlide = items;
this.tempActiveSlide = this.activeSlide;
}
});
}

vuejs: mounted issues with coordinates of elements and svg

I have three columns, two with divs and the central one with an svg. I made a method that calculate the top() of each paragraph inside the divs to get the position and then draw an arrow in the svg. The problem is that when I use that method the first time I open my component, I get all zeroes, probably because the paragraph aren't really drawn (they have no coordinates) yet. I tried in mounted(), which should be the right place to do that. I use it also in updated() in case I reload my json with new data.
Am I missing something trivial?
The code I use to get the coordinates is like this:
drawLine(index1, index2) {
//var plist1 = this.$refs['p_list1'];
//var plist2 = this.$refs['p_list2'];
var plist1 = document.getElementsByClassName('p_list1');
var plist2 = document.getElementsByClassName('p_list2');
if (plist1.length == 0 && plist2.length == 0) return;
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'line');
//...
//const start = this.$refs['startpos'].getBoundingClientRect().top;
const start = document.getElementById('startpos').getBoundingClientRect().top;
const r1 = plist1[index1].getBoundingClientRect();
const r2 = plist2[index2].getBoundingClientRect();
index1 and index2 comes from a loop where I get which paragraph I have to connect with an arrow (also where the nextThick is)
Here is a simple example of the issue:
https://codesandbox.io/s/bootstrap-vue-test-bcozc
Note: it's badly shown, but if you press "DO" and then switch tab, you'll see that the arrow aren't correct. If you switch tab and then press DO, it will work.
Put your calculation methods in a $nextTick function to allow parents and children to fully render.
If that does not work, as a debug step, try using a setTimeout method to delay the calculation.
After understanding that the problem was linked to how tabs are built, I tried making that specific tab lazy and it worked.
<b-tab lazy ...
I don't know how tabs are normally built, but I suppose the dom is put together without having a real coordinate system and when it's made visible, I don't have any event to read to update the svg.

how to verify view is scrollable in mobile application (Automation)

Anyone knows automation script to verify a view (homePage/Browse) is scrollable or not. i can use ScrollTo(id) which is at the bottom of the page. But it is not a correct method to do, as test case passes if that element present in 1st page
Basically You cannot. You could try to cast the view to ScrollView class however any custom view can implement scroll.
Get the coordinates of any particular element like button etc unique element.
Swipe using driver.swipe() to 100 or more pixels.
And get the coordinates of that element again and check whether x or y coordinates changed or not.
This will let you know whether it is a single page application or more to scroll.
Basically there is no API to check the view is scrollable or not but if you still require this then you can do work around
#Test
public void testVerticalScroll()
{
//Try to Scroll till the 15th row
driver.scrollTo("List item:15");
//Assert that the 1st row is not visible.
Assert.assertFalse( driver.findElement(By.name("List item:01")).isDiaplyes())
//Assert that the 15th row is not visible.
Assert.assertTrue( driver.findElement(By.name("List item:15")).isDiaplyes())
}
You can consider the last visible element as "YourText" But this is
just a workaround that needs to be customized for each page.
Here we are using swipe until we find the element. In this case, the last visible element indicates the margin of the page.
Dimension dimensions = driver.manage().window().getSize();
Double screenHeightStart = dimensions.getHeight() * 0.5;
int scrollStart = screenHeightStart.intValue();
System.out.println("s="+scrollStart);
Double screenHeightEnd = dimensions.getHeight() * 0.2;
int scrollEnd = screenHeightEnd.intValue();
for (int i = 0; i < dimensions.getHeight(); i++) {
driver.swipe(0,scrollStart,0,scrollEnd,2000);
if (driver.findElement(By.name("YourText")).size()>0)
exit;
}
driver.findElement(By.name("YourText")).click();
There is a way to check it. You have to find a layer that you will target for example:
MobileElement scrollableLayer= driver.findElementById("elementID");
Then you will extract attribute value "scrollable" of that element like this:
String scrollableState = scrollableLayer.getAttribute("scrollable");
And then you can check if the String value is true or false.
if (scrollableState.equals("true")){System.out.println("it's scrolable"); }else{System.out.println("it's not scrolable");}
Or you can do whatever you want with it :)

Is it possible to dynamically add a slide to an existing Materialize Carousel?

I am able to create a carousel as described here. The carousel appears and works properly.
Later on I would like to add an additional slide:
$(".carousel").append('<a class="carousel-item active" href="#six!"><img src="http://lorempixel.com/250/250/nature/6"></a>');
However, this does not appear to work as the slide does not get added to the carousel.
Is adding slides to an initialized carousel not supported or is this an issue on my end?
Sure it is. I haven't seen any solution in the internet. I believe that there might be a better and smoother solution but this one is mine.
All you need to do is after adding your new items remove the initialized class from already initialized main carousel div and reinitialize it.
//init carousel
var slider = $('.carousel');
slider.carousel();
//add a new item
slider.append('<a class="carousel-item active" href="#three!"><img src="http://lorempixel.com/250/250/nature/3"></a>');
//remove the 'initialized' class which prevents slider from initializing itself again when it's not needed
if (slider.hasClass('initialized')){
slider.removeClass('initialized')
}
//just reinit the carousel
slider.carousel();
full working fiddle: https://jsfiddle.net/8tq4ycm3/
I had the same problem, but I'm using the slider. (http://materializecss.com/media.html#slider)
To resolve this, it was necessary to clear all items, re-add items with the new one, and then re-bind the slider.
Follow example: https://codepen.io/troits/pen/QvdZov
let itens = [];
function addItem(){
$('.slides').empty();
$('.slider > .indicators').detach();
itens.push(createItem());
for(i in itens){
$('.slides').append(itens[i]);
}
$('.slider').slider();
showItem(i);
}
function showItem(i){
$('.slider > .indicators > .indicator-item')[i].click();
}

Dojo EnhancedGrid and programmatic selection

Here's my problem: in my application I have a Dojo EnhancedGrid, backed up by an ItemFileReadStore. The page flow looks like this:
The user selects a value from a selection list.
The item from the list is posted on a server and then the grid is updated with data from the server (don't ask why, this is how it's supposed to work)
The new item is highlighted in the grid.
Now, the first two steps work like a charm; however, the third step gave me some headaches. After the data is successfully POSTed to the server (via dojo.xhrPost() ) the following code runs:
myGrid.store.close();
myGrid._refresh();
myGrid.store.fetch({
onComplete : function(items) {
for ( var i = 0; i < items.length; i++) {
if (items[i].documentType[0].id == documentTypeId) {
var newItemIndex = myGrid.getItemIndex(items[i]);
exportMappingGrid.selection.deselectAll();
exportMappingGrid.selection.addToSelection(newItemIndex);
}
}
}
});
Now, the selection of the grid is updated (i.e. the selection object has a selectedIndex > 0), but visually there's no response, unless I hover the mouse over the "selected" row. If I remove the .deselectAll() line (which I suspected as the culprit) then I sometimes end up with two items selected at once, although the grid selectionMode attribute is set to single.
Any thoughts on this one?
Thanks a lot.
You need to use setSelected(), like so
exportMappingGrid.selection.setSelected(newItemIndex, true);
The second parameter is true to select the row, false to unselect it.
This is what works for me:
grid.selection.clear();
grid.selection.addToSelection(newItemIndex);
grid.selection.getFirstSelected();
Jon