How to change dynamicaly slide in ion-slides on Ionic 2? - ionic2

I have slider in my application:
<ion-slides #showSlider *ngIf="product.show_images" class="slideShowWrapper productImages" [options]="mySlideOptions">
<ion-slide *ngFor="let image of product.show_images;">
<img [src]="image.big_url" alt="{{image.title}}"/>
</ion-slide>
</ion-slides>
And in code I need to change slides and count of slides. But after change the list of slides. Slider changes, but first slide not shows, or it can be showed but points of slides is not anought.
How right to change slides list?
My code to change is:
this.slider.getSlider()['removeAllSlides'](); // Delete slides
this.product.changeOffer();
this.product.show_images = this.product.getImages();

Template:
<ion-slides #showSlider *ngIf="product.show_images" class="slideShowWrapper productImages" [options]="mySlideOptions">
<ion-slide *ngFor="let image of product.show_images;">
<img [src]="image.big_url" alt="{{image.title}}"/>
</ion-slide>
</ion-slides>
Code:
export class ProductBlocksProductPage extends AbstractBlock{
mySlideOptions: any
#ViewChild('showSlider') slider: Slides; //Access to slider
#Input() slideOptions = {}; // Slider options
constructor(){
}
/**
* Change the images action
*/
changeOffer()
{
this.product.changeOffer(); //Here is your function to change of our images array
// Update slider
this.slider.getSlider().update(); //Reinit slider
this.slider.getSlider().slideTo(0, 0, true); //Move to first slider
}
}

Related

React Native Render HTML bullet list is not centered with text

I'm using react-native-render-html library to display data from Django Rest Framework stored in RichTextUploadingField from django-ckeditor. As basic styling is working properly I have a problem with the <ul> tag - text is not centered with circle/square/number as shown in the image. I tried using renderersProps like:
<RenderHTML renderersProps={{ ul: { markerBoxStyle:{ paddingRight: 3, top: 5 }, markerTextStyle: { color: "red" } } }} />
But it works for specific text size. If I change the text size in style in Django admin, the element and text aren't centered again. Is there any option on how to fix it or what causes the problem?
You could add a custom CSS class to unordered list items only. Then apply your styles to that CSS class.
// this function goes through every list item in <ul> only and adds your custom class ('ul-li' in my case)
const onElement = (el) => {
const { children, name } = el;
if (name === 'ul' && children && children.length) {
children.forEach(listItem => listItem.attribs = {class: 'ul-li'})
}
}
// define your styles for your custom class
const classesStyles = {
"ul-li": {
lineHeight: '21px', // for me adjusting lineHeight did the job
}
}
// in your JSX
<RenderHtml
source={source}
contentWidth={width}
tagsStyles={tagsStyles}
... // other props you may have
domVisitors={{onElement}} // first alter your html
classesStyles={classesStyles} // then apply styles
/>
Sources:
classesstyles
onElement

How to update Scroll values while using Bunit automation scripts

We have a requirement to update the scrollLeft value of the a element in blazor platform. We have tried to update the scroll Left property through databinding using the below code snippet. But its not working. So it is a mandatory to use the JS code to update the scrollLeft property of the parent element.
#page "/Scroll"
#using Microsoft.JSInterop;
#inject IJSRuntime JSRuntime;
<input type="button" #onclick="#OnScroll" value="scroll" />
<input type="button" #onclick="#OnScrollJs" value="scroll-Js" />
<div id="parentDiv" style="width:500px;height:300px;overflow:auto" scrollLeft="#ScrollLeft" scrollRight="#ScrollRight">
<div id="childDiv" style="width:1500px;height:1500px"></div>
</div>
#code {
double ScrollLeft = 0;
double ScrollRight = 0;
private void OnScroll()
{
ScrollLeft = 200;
ScrollRight = 200;
}
private async void OnScrollJs()
{
await JSRuntime.InvokeVoidAsync("onChangeScrollValues", "parentDiv", 200, 200);
}
}
JS code was shown in below
window.onChangeScrollValues = function (id, left, top) {
var element = document.getElementById(id);
element.scrollLeft = left; element.scrollTop = top;
}
From the above code when we use the JS code snippet to update the DOM elements means, it does not suitable for Bunit testing. So in this scenario how I able to set the Scroll values in Bunit scripts ?
bUnit doesn't run JavaScript, instead you can write a test that verifies that the onChangeScrollValues is correctly called when scroll-Js button is clicked.
Something like this should suffice:
// arrange
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var cut = ctx.RenderComponent<MyComponent>(); // replace MyComponent with the name of the component.
// act
cut.Find("input[value=scroll-Js]").Click();
// assert
cut.JSInterop.VerifyInvoke("onChangeScrollValues");

unable to display list of items with Nativescript-Vue GridLayout

Nativescript-vue newbie here...
I am using nativescript-vue to display a list of items. When the .vue page loads, the grid should just be an empty table. When a button is clicked, the grid is populated with sub-elements of a list I retrieved from a service. I am running into two issues:
There is only one row, where there should be a row per item in the list.
The date will be a date element such as 06-01-2019 11:30:01 but I would prefer to display it as 06-01-2019
In my *.vue:
<RadListView for="item in itemList" layout="grid" #itemTap="onItemTap">
<v-template>
<GridLayout rows="20, 20" class="list-item list-item-grid">
<GridLayout row="1" rows="25, 35" columns="auto, auto, auto, auto">
<Label col="0" :text="item.date" class="list-item-left" textWrap="true"verticalAlignment="middle" horizontalAlignment="left"></Label>
....
</GridLayout>
</GridLayout>
</v-template>
</RadListView>
....
<script>
expot default {
data() {
return {
itemList: []
};
},
methods: {
getItems() {
// really simplified but it will return something like:
// [{"date" :"09-01-2019 11:32:01", "name":" first last"}]
service.getItemArray()
}
},
beforeMount: function() {
this.itemList= this.getItems();
}
</script>
I have put a shortened Playground version here:
You could try a v-if to render the RadListView after the button is clicked, or manual load on demand.

How to use images inside a select component in Ionic 2

I am trying to put an image inside a Select component in Ionic 2 :
I have put the image source files inside the www/img folder in my Ionic 2 project.
However, using a simple img-tag does not display any image using this code:
<ion-list>
<ion-item>
<ion-label>Gaming</ion-label>
<ion-select [(ngModel)]="gaming">
<ion-option value="nes">
NES
<img src="img/myImage.png">
</ion-option>
</ion-select>
</ion-item>
</ion-list>
Does anyone have any idea?
The ion-select component doesn't allow direct customization to itself and anything that you add to ion-select and ion-option which is not as per the ionic documentation, will be ignore in the generated output.
You cannot add class or style to the component.
One way to do this is to put the ion-select in a parent element like div or ion-row etc. with class and apply the CSS rules using .parentclass childElement selector.
To show the images in option check the function below:
prepareImageSelector() {
setTimeout(() => {
let buttonElements = document.querySelectorAll('div.alert-radio-group button');
if (!buttonElements.length) {
this.prepareImageSelector();
} else {
for (let index = 0; index < buttonElements.length; index++) {
let buttonElement = buttonElements[index];
let optionLabelElement = buttonElement.querySelector('.alert-radio-label');
let image = optionLabelElement.innerHTML.trim();
buttonElement.classList.add('imageselect', 'image_' + image);
if (image == this.image) {
buttonElement.classList.add('imageselected');
}
}
}
}, 100);
}
I have implemented color and image selector using ion-select. Please refer https://github.com/ketanyekale/ionic-color-and-image-selector
You can also check the answer at Ionic select input of colours
I achieved it like this.
<ion-select (click)="loadFlags()" formControlName="pays" value="select-country">
<ion-select-option value="select-country" >select your country </ion-select-option>
<ion-select-option *ngFor="let country of countries" value="{{country.name}}">{{country.name}}</ion-select-option>
</ion-select>
And this is my .ts file
loadFlags() {
setTimeout(function(){
let radios=document.getElementsByClassName('alert-radio-label');
for (let index = 1; index < radios.length; index++) {
let element = radios[index];
element.innerHTML=element.innerHTML.concat('<img class="country-image"
style="width: 30px;height:16px;" src="'+countries[index-1].flag+'" />');
}
}, 1000);
}
Timeout is to let the system create alert componens. My Json is an array with elements like {name:"Cameroon",flag:"https://restcountries.eu/data/cmr.svg"}
On your basis, I have worked out a more concise solution!
The method 'prepareImageSelector' is used as the Click event of the control。
Thank you!
image: string = 'English';
prepareImageSelector() {
setTimeout(() => {
let buttonElements = document.querySelectorAll('div.alert-radio-group button');
if (!buttonElements.length) {
this.prepareImageSelector();
} else {
for (let index = 0; index < buttonElements.length; index++) {
let buttonElement = buttonElements[index];
let optionLabelElement = buttonElement.querySelector('.alert-radio-label');
let image = optionLabelElement.innerHTML.trim();
if (image == this.image) {
optionLabelElement.innerHTML += '<img src="assets/img/English.png" style="width:20px;height:20px;float:right;"/>';
}
}
}
}, 100);
}
There are already some great answers, and I honestly think Select with some images should have been part of the core Ionic library, but here we are.
I made the following adaptations for my answer:
Implemented with Ionic Vue (Ionic 6, so it's still an issue)
Flags for the countries are nested in a country JSON obtained from an API call.
Implemented for Action Sheet instead of Alert as the other answers
Flags appear on the left instead of the right
First, the HTML:
<IonSelect #click="loadFlags()" placeholder="Country" :interface-options="customAlertOptions" interface="action-sheet" cancelText="Cancel" style="width: 100%" v-model="selected_country">
<template v-for="(country, index) in countries" :key="index">
<div class="ion-text-center">
<IonSelectOption :value="country.code">
<IonLabel>{{ country.name }}</IonLabel>
</IonSelectOption>
</div>
</template>
</IonSelect>
And then the Javascript:
loadFlags() {
let that = this;
setTimeout(function() {
let radios = document.getElementsByClassName('action-sheet-button-inner');
for (let i = 0; i < that.countries.length; i++) {
let element = radios[i];
element.innerHTML = `<div style="display: flex; position: relative; width: 100%"><img style="width: 40px;height:40px;" src="${that.countries[i].flag}"/>`
+ `<span style="font-size:16px; position: absolute; top:10px; left: 70px;">${element.innerHTML}</span></div>`
}
}, 10)
}
Even though it's a little crude, the innerHTML in the loadFlags function, with some HTML and CSS, can be used to achieve almost anything.

Highslide: Pause HTML Slideshow when Gallery Expands

I created a HTML Gallery that expands an image every window.
http://mmvirtualtours.com/0002/photos.php
When I run the gallery as a slideshow I would like it to pause when the contained image expands.
I am trying the following code:
hs.Expander.prototype.onAfterExpand = function() {
if (this.contentType == 'html') {
this.slideshow.pause();
As it is it will pause after every transition in the slideshow. What do I need to change the contentType to and or is there a better way to do this?
Thanks!
Remove this:
hs.Expander.prototype.onAfterExpand = function() {
if (this.contentType == 'gallery') {
this.slideshow.pause();
}
};
Add this:
// Stop slideshow when viewing large image
function stopSlideshowAndExpand(element, config) {
var exp = hs.getExpander(element);
if (exp.slideshow) {
exp.slideshow.pause();
}
return hs.expand(element, config);
}
Change the onclick for the large image in the highslide-maincontent div:
<a class='highslide' href='media/01.jpg' onclick="return stopSlideshowAndExpand(this, largeGalleryOptions1 )">
<img src='media/s01.jpg' alt='' / border="0">
</a>