Ionic scroll top sepcific element on viewdidenter - ionic4

Is there any way to scroll top in ionic specific element when a viewdidenter?
<ion-content nopadding>
<div class="notes-main" *ngFor="let item of notesGroupDate">
<h3 class="heading"*ngIf="today" #scrolltop>{{item[0]| date}}</h3>
<div no-border *ngFor="let data of item[1]">
<div class="notes-subject">{{data.field_subject}} {{data.field_assigned_to_class}}</div>
<div class="notes">
<div class="notes-data private" *ngIf="data.field_private_notes_title || data.field_private_notes">
<div class="notes-icon" *ngIf="data.field_private_notes_title || data.field_private_notes">
<ion-img src="../../assets/Diary_PersonalNote.svg"></ion-img>
</div>
<div class="notes-details">
<div class="notes-title">{{data.field_private_notes_title}}</div>
<div class="notes-description">{{data.field_private_notes}}</div>
</div>
</div>
</div>
</div>
</div>
</ion-content>
I want to scroll top <h3 class="heading"*ngIf="today" #scrolltop>{{item[0]| date}}</h3> this element if condtion satisfy on ionviewdidenter.

You can do it like this to scroll to the top of the page each time you go back to the page:
import { Component, ViewChild } from '#angular/core';
import { IonContent } from '#ionic/angular';
#Component({...})
export class MyPage{
#ViewChild(IonContent) content: IonContent;
scrollToTop() {
this.content.scrollToTop(400);
}
ionViewDidEnter(){
this.scrollToTop();
}
}
It sounds like that's what you are looking for, unless this is a simplified version of your real app, in which case we will need to use scrollToPoint and then write some code to get the y offset for that spot.

Related

I'm looping through my array with v-for and I would like that each item goes to a specific grid position. How do I do that?

Well, I have this component and I want to display my data in a grid that looks like this:
I'm looping through my last 3 items of my array
async created(){
const res = await axios.get("https://base-url/posts")
const data = res.data;
this.destaques= data.slice(-3);
}
But when I use v-for I do not see a way to put them in the positions above.
<div v-for="(destaque, i) in destaques" :key='i'>
<nuxt-link :to="`/${destaque.id}`">
<p>{{destaque.title}}</p>
</nuxt-link>
</div>
I've tried this way
<div class="destaques__principal">
<nuxt-link tag="a" :to='`/${destaques[0].id}`' class="wrap-link">
<img :src="`${destaques[0].image[0].name}`" alt="">
<div class="white-box">
<h1 class="white-box__title">{{destaques[0].title}}</h1>
</div>
</nuxt-link>
</div>
<div class="destaques__cima">
<nuxt-link tag="a" :to='`/${destaques[1].id}`' class="wrap-link">
<img :src="`${destaques[1].image[0].name}`" alt="">
<div class="white-box">
<h1 class="white-box__title">{{destaques[1].title}}</h1>
</div>
</nuxt-link>
</div>
<div class="destaques__baixo">
<nuxt-link tag="a" :to='`/${destaques[2].id}`' class="wrap-link">
<img :src="`${destaques[2].image[0].name}`" alt="">
<div class="white-box">
<h1 class="white-box__title">{{destaques[2].title}}</h1>
</div>
</nuxt-link>
</div>
and first it works but when I click on the logo to get back to home page, it gives me an error. I don't get that error when I display the data like this destaque.title. So I was wondering if there is a way to dynamically arrange the items to specific positions on the grid. Is there anyone that could help me out, please?
You could use CSS grid to achieve this. DEMO: https://jsfiddle.net/kpset24g/1/
HTML
<div class="grid">
<div v-for="(item, i) in items" class="box" :class="{'full-height-box': i == 0}">
{{item}}
</div>
</div>
CSS
.grid {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: 2;
grid-gap: 10px; /* OPTIONAL */
}
.full-height-box {
grid-row: 1 / span 2;
}
.box { /* Custom styles of your box */ }
JS (Just as demo)
new Vue({
//...
data: {
items: ['Block 1', 'Block 2', 'Block 3']
}
})

How to transfer data between components (siblings) Vue?

In the HeaderComponent method 'clickPrices' is called on click
<template>
<header>
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
<h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5>
<nav class="my-2 my-md-0 mr-md-3">
<a class="p-2 text-dark" href="#">Features</a>
<a class="p-2 text-dark">Enterprise</a>
<a class="p-2 text-dark" #click="clickPrices()">Get pricing</a>
</nav>
<a class="btn btn-outline-primary " href="#">Sign up</a>
</div>
</header>
</template>
<script>
export default {
name: "HeaderComponent",
methods: {
clickPrices() {
...
},
},
}
</script>
<style scoped>
</style>
and there is a Pricing Component in which I make a request to the server in the method 'getPricing'
<template>
<div class="wrap-pricing">
<div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center">
<h1 class="display-4">Pricing</h1>
<p class="lead">Quickly build an effective pricing table for your potential customers with this Bootstrap example. It’s built with default Bootstrap components and utilities with little customization.</p>
</div>
<div class="container">
<div class="card-deck mb-3 text-center">
<div class="card mb-4 shadow-sm">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Lorem</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title">$10 <small class="text-muted">/ mo</small></h1>
<ul class="list-unstyled mt-3 mb-4">
<li>Lorem</li>
<li>Lorem</li>
<li>Lorem</li>
<li>Lorem</li>
</ul>
<button type="button" class="btn btn-lg btn-block"></button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import router from '../routes.js';
import { axios } from 'axios';
export default {
name: "PriceComponent",
methods: {
getPricing() {
axios.get('api/pricing').then((response) => {
//some actions
router.push('prices');
});
},
},
}
</script>
<style scoped>
</style>
How should I process the result of the 'сlickPrices' HeaderComponent method?
Or am I waiting for your ways, how can I get data in another by clicking in one component
You can emit an event and let the parent component handle the fetching and pass the data as props to the child component.
Or another way is to directly listen to the event as follows
Component 1:
this.$root.$emit('clickPrices', data);
Component 2:
mounted() {
this.$root.$on('clickPrices', data => {
this.getPricing();
});
}
Check out the answer by #alex
Since you are using 2 independent components (one is not included in the other), you cannot pass props
Things you can do -
Instead of fetching all the prices on click, just create a created hook like so, which will fetch all the pricing details whenever your component is created -
created () {
this.getPricing()
},
methods: {
getPricing() {
axios.get('api/pricing').then((response) => {
//some actions
router.push('prices');
});
},
},
Use State and when a user clicks on the button, pricing details are fetched and added in the state. And you can just use the state anywhere in your application like so -
this.$store.state.prices
Let me know if it works, if not we will find some other solution for you!

VueJS with bootsrap carousel how to pass images to the carousel

My requirement is something like this.
I got the list of images from the back-end.
I want to pass those image names to the carousel to display images.
This is my code.
<template>
<div class="">
<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" v-for="banner in banners">
<img :src="`./assets/${banner}`" alt="" class="img-fluid" >
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
banners:["logo.png","index.png","Capture.png"]
}
},
methods:{
}
}
</script>
But this method doesn't work. How do I pass images to my carousel element?
The problem is that you're setting all carousel slides to active, so they will all display at once. Use :class to conditionally set the active slide...
<div class="carousel-item" v-for="(banner,idx) in banners" :class="{ active: idx==0 }">
<img :src="banner" alt="" class="img-fluid">
</div>
Also, make sure the :src="'./assets/${banner}'" reference is actually working to find the images.
Working demo on Codeply
Note: You don't want to use jQuery $('.carousel').carousel(); to load the Carousel since you're already using the data-ride="carousel" attribute. As stated in the Bootstrap 4 docs...
The data-ride="carousel" attribute is used to mark a carousel as
animating starting at page load. It cannot be used in combination with
(redundant and unnecessary) explicit JavaScript initialization of the
same carousel.
From https://www.w3schools.com/bootstrap/bootstrap_carousel.asp
The data-ride="carousel" attribute tells Bootstrap to begin animating the carousel immediately when the page loads.
Vue hasn't mounted this component yet on page load. So you gotta initialize the slider only after it has mounted.
So you gotta remove data-ride="carousel", and add $('.carousel').carousel() in the mounted hook (assuming that the jquery $ is available as a global variable). Make sense ?
<template>
<div class="">
<div id="carouselExampleSlidesOnly" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active" v-for="banner in banners">
<img :src="`./assets/${banner}`" alt="" class="img-fluid" >
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
banners:["logo.png","index.png","Capture.png"]
}
},
methods:{
},
mounted(){
$('.carousel').carousel();
}
}
</script>

How asynchronous render dom in Vue file?

I use $refs.height[index].offsetTop in the 1st part to computed same values, but $refs.height is in the 2rd part ,that render after the 1st part,so reload page has error TypeError: Cannot read property '0' of undefined.
I try comment <div>{{showNumber(index)}}</div>,then run npm dev,then recomment , it's work.
How render the 2rd part at first?
<template>
<div id="app">
//1st part
<div id="catalog">
<div v-for="(baike,index) in baikes">
<div class="catalog">
<h2>{{index+1}}.{{baike.name}}</h2>
<hr style="border:1px dashed #000; flex-grow: 1">
<div>{{showNumber(index)}}</div>
</div>
</div>
</div>
//2rd part
<div id="content">
<div v-for="(baike,index) in baikes" ref="height">
<h3 >{{index+1}}.{{baike.name}}</h3>
<p>{{baike.abstract}}</p>
<ul v-for="(info,key,index) in baike.info">{{key}}-{{info}}</ul></ul>
</div>
</div>
</div>
</template>
<script>
import baikeJSON from '../../items.json'
export default {
name: 'app',
data () {
return {
baikes: baikeJSON,
}
},
methods:{
showNumber(i){
return Math.ceil(this.$refs.height[i].offsetTop/1000)
}
},
}
</script>
Switch 2rd part and 1st part of position then add css
#app{
display:flex;
flex-direction:column-reverse;
}

Vue JS Component reattach or Cache

VueJS component doesn't get cached or atleast reattached after navigation. On refresh or launch everything gets attached and rendered well but after navigating to another page then back. The First Component - Carousel - component in my case doesn't get rendered but the API call is made.
<template>
<div class="rel">
<div id="homeCarousel" class="owl-carousel owl-slider">
<div class="item" v-for="product in featured">
<div class="bg-holder top-area-half" >
<div class="bg-mask-lighten"></div>
<img class="bg-img" v-bind:src="product.feature_image_url">
<div class="hero-caption">
<div class="container">
<h3 class="hero-title">{{product.feature_title}}</h3>
<p class="hero-subtitle">{{product.feature_subtitle}}</p>
<a class="btn btn-white btn-ghost btn-lg hero-btn" href="#">Shop now</a>
</div>
</div>
</div>
</div>
</div>
<div id="hero-slider-nav" class="hero-slider-nav">
<div class="container">
<div class="pull-right"></div>
</div>
</div>
</div>
</template>
<style>
</style>
<script>
export default{
data(){
return{
featured:[]
}
},
ready(){
},
mounted(){
this.getFeaturedProducts();
},
components:{
},
methods: {
getFeaturedProducts: function () {
Vue.http.get('/api/product/filter/featured=1').then(
(response) => {
this.featured = response.body;
}
)
}
}
}
</script>
`
<template>
<div class="global-wrapper clearfix ">
<keep-alive>
<Carousel></Carousel>
</keep-alive>
//The rest of the code which is just importing the Component
I found out what i was doing wrong. I had a separate JS/JQuery file and on the document ready i was initializing an owl carousel by id #('homeCarousel').owlCarousel({}) . What worked was, since i had already bootstrapped owl carousel -> on the mounted lifecycle callback i was now targeting the element and making it an owl carousel.