How to go to different section of a page in ionic? - javascript

Does anyone know the right syntax on how to go to a particular section on a page in ionic? I'm still trying to work my way with angular and ionic 4. This is my code and whenever I press the button that should direct me to section 2 of the current page, I end up going to a different page instead.
<div id="section1">
//some content here
<ion-button href="#section2>Next</ion-button>
</div>
<div id="section2">
//some content here
<ion-button href="#section3>Next</ion-button>
</div>

For this you will can use scrollToPoint() method.
Declare a method in your component.ts file to get position of element:
export class SampleComponent {
#ViewChild(Content) content: Content;
scrollTo(_id: string) {
let y = document.getElementById(_id).offsetTop;
this.content.scrollToPoint(0, y);
}
}
Now bind this method to your scrollTo method and send section id where you want to scroll as argument.
<div id="section1">
//some content here
<ion-button (click)="scrollTo('section2')">Next</ion-button>
</div>
<div id="section2">
//some content here
<ion-button (click)="scrollTo('section3')">Next</ion-button>
</div>

Related

change page layout on link click vue.js

I'm learning how to use vue.js
I've a shared hosting plan where I can only use html. I'm fetching the data I need using axios and a remote wordpress installation that will act as a backend only. What I need to know, is how I can change the DOM content of the index.html using vue if the user click on a link and I need to change the layout of the page because a different presentation for the contents is needed?
See the example:
<div id="vue-app">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app">
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Please read up on Conditional Rendering in Vue.js.
You can have a boolean variable in the data compartment of your script tag and change it on click.
And in the tags put v-if="your_bool_variable".
<div id="vue-app" v-if="layout_switch">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app" v-else>
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Negate the boolean variable at the #click event.
Data could look like the following:
<script>
export default {
name: "YourComponent",
data: () => {
return {
layout_switch: true
}
},
methods: {
changeLayout() {
this.layout_switch = !this.layout_switch;
}
}
}
</script>

Why do background images load when navigating by anchor link but not by routerLink?

I have a feeling the answer to this question is quite simple, but I cannot find an answer to it anywhere. I am build a very simple app with Vue.js (v2.6.11) that consists of just two pages, a home page and another page with a form. Now, on both of these pages, there are several parallax containers made with MaterializeCSS. If you're unfamiliar, a parallax container is basically just a div with an image as its background, and when the user scrolls, the background image moves at a different rate than the foreground of the site.
My problem is that when I navigate from the home page to the page with the form using a Vue.js link, <router-link :to="{name: "FormPage"}>Form Page</router-link>, the images in the parallax containers DO NOT load. However, if I refresh the page, the images load fine and everything is well. Similarly, If I replace the <router-link> with a simple Form Page the images load fine, everything works as it should.
So my question is this: why don't my parallax container images load on the page navigated to with <router-link></router-link>, but then when I navigate to that same page with a the images do load? In other words, what is <router-link></router-link> doing that prevents my parallax container images from loading??
Any and all feedback would be appreciated. Otherwise, I hope you have a marvelous day, and thank you for you time in reading and or answering my question :)
--Update--
CODE:
This is the component on the homepage that contains the link in question:
<template>
<div id="index-banner" class="parallax-container" style="height: 400px;">
<div class="section no-pad-bot">
<div class="container">
<br><br>
<h1 class="header center white-text">{{ translations.title }}</h1>
<div class="row center">
<h5 class="header col s12 white-text light">{{ translations.subtitle }}</h5>
</div>
<div class="row center">
<!-- <router-link :to="{name: 'Generator', force: true }" class="btn-large waves-effect waves-light teal lighten-1 center-align">{{ buttonText }}</router-link> -->
{{ translations.buttonText }}
</div>
</div>
</div>
<div class="parallax"><img :src="img" alt="Unsplashed background img 1"></div>
</div>
</template>
<script>
export default {
name: 'Banner1',
props: {
translations: String,
img: String
},
}
</script>
<style>
</style>
This is the 'view' that is navigated to, containing the parallax containers in question:
<template>
<div>
<PageTitle
:translations="$t('generatorPage.components.pageTitle')"
img="/imgs/parallax5.jpeg"
/>
<SigForm
:translations="$t('generatorPage.components.sigForm')"
/>
<Separator
img="/imgs/parallax5.jpeg"
/>
</div>
</template>
<script>
import PageTitle from '#/components/banner/parallax/PageTitle'
import Separator from '#/components/banner/parallax/Separator'
import SigForm from '#/components/generator/SigForm'
export default {
name: 'Generator',
components: {
PageTitle,
SigForm,
Separator,
}
}
</script>
<style>
</style>
Here is the 'PageTitle' component with a parallax container:
<template>
<div class="parallax-container form-parallax-container">
<h1 class="white-text center">{{ translations.title }}</h1>
<div class="parallax"><img :src="img"></div>
</div>
</template>
<script>
export default {
name: 'PageTitle',
props: {
translations: String,
img: String
}
}
</script>
<style>
</style>
And here is the 'Separator' with a parallax container:
<template>
<div class="parallax-container form-parallax-container">
<div class="parallax"><img :src="img"></div>
</div>
</template>
<script>
export default {
name: 'Separator',
props: {
img: String
}
}
</script>
<style>
</style>
---UPDATE: Complete repo & sandboxed app---
Someone mentioned it would be eaiser if I provided a sandboxed app or whatever to debug it, so I just made the github repo public and also uploaded it to codesandbox.io. You'll notice that on codesandbox.io, the parallax images aren't even loading at all...on the homepage, on the form page, or upon refresh!
Ok so this is not the answer, but I needed to post some code to illustrate.
I have to confess that I'm not fully au-fait with JS frameworks, but I do know materializecss very well. I've been trying to help another user with a React based problem where the sidenav stops working when the react router is used - until he refreshes the page, when it works fine again.
So here's my hunch:
Parallax is a component that needs initialising like so:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.parallax');
var instances = M.Parallax.init(elems);
});
// Or with jQuery
$(document).ready(function(){
$('.parallax').parallax();
});
If you leave that initialisation code out, it won't work. And, taken from the docs for select fields dynamically added components need reinitialising.
You must initialize the select element as shown below. In addition,
you will need a separate call for any dynamically generated select
elements your page generates.
So my hunch is that when the page is re-rendered via a navigator, we get a new component added to the dom - but this is after the initialisation has already run. So that component is not initialised.
Could be wrong, hope I'm not for your sake more than mine. As I said, I don't know Vue or React very well at all, and my suggestions to run the init at each render didn't work for the React issue - but there are so many moving parts it's hard to rule out.

click twice on button process the ngIf statement in other component

I've added breadcrumb in my site such that when clicks on it, it makes that specific variable undefined(which session stored value and can retrieved easily in other component) and based on that, in other component I've ngIf for that variable such that if that variable is undefined then that specific div should not be shown and other div should be shown. You can get more idea by looking into following gifs.
Problem I'm facing is on first click it don't go back to that other div which it does on second click.
Clicking twice on breadcrumb for Model(or its value) do the trick but i want to do this happens on first click.
Breadcrumb component TS file:
#SessionStorage() model: any;
onClickModel(m){
this.model = m.value; // gets the value from button and set as model value
}
other component HTML file:
<div class="model" *ngIf="model && !provider">
<div class="row">
<div class="col-md-12 text-center pb-20">
<h2>Choose your Carrier</h2>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<!-- That next component buttons for providers -->
</div>
</div>

Button inside a popup with vue

I have used the vue2-google-maps package to make a custom popup. In my custom popup I have placed a button which should open a new popup in the place of the old one.
Html
<gmap-info-window
:options="infoOptions"
:position="infoWindowPos"
:opened="infoWinOpen"
#closeclick="infoWinOpen=false"
>
<div v-html="infoContent"></div>
</gmap-info-window>
Javascript for the first popup. The
toggleInfoWindow: function (marker, idx) {
this.infoWindowPos = marker.position;
this.activeMarker = marker;
this.infoContent = this.getInfoWindowContent(marker);
//check if its the same marker that was selected if yes toggle
if (this.currentMidx == idx) {
this.infoWinOpen = !this.infoWinOpen;
}
//if different marker set infowindow to open and reset current marker index
else {
this.infoWinOpen = true;
this.currentMidx = idx;
}
},
getInfoWindowContent: function (marker) {
return (`<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src="https://bulma.io/images/placeholders/96x96.png" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<p class="title is-4">${marker.name}</p>
</div>
</div>
<div class="content">
${marker.description}
<br>
<time datetime="2016-1-1">${marker.date_build}</time>
<button #click="getSecondPopUp">Get second popup</button>
</div>
</div>
</div>`);
},
getSecondPopUp: function () {
console.log("why don't you work?");
}
The problem is that when I click on the button the second method does not get executed. Does anyone know why that might be and how to fix it?
Thanks in advance.
v-html only renders raw HTML. The HTML that you are returning from the getInfoWindowContent method is a Vue template which must be rendered directly by a Vue component (and depending on your setup, if you're using webpack then it's likely that the templates will be compiled with vue-loader and not at runtime).
I'm not familiar with the vue2-google-maps package, but to achieve what you want, you should not use v-html and instead put the Vue template source directly inside <gmap-info-window>. Replace all of the ${marker.description} string interpolations with Vue template interpolations {{ activeMarker.description }} (assuming activeMarker is declared upfront in the component's data object in order for it to be reactive and renderable inside the template). You may need to use v-if to control the visibility of parts of the template that access activeMarker in case activeMarker is null (unless the gmap-info-window component does not render its slot if the opened prop is false).
Ideally v-html should never be used, for one it makes XSS possible.
Consider using a popup done with Vue, instead of the one given by maps. Try this one https://www.npmjs.com/package/#soldeplata/popper-vue

viewContentLoaded - Without duplicating code per each controller - AngularJS

Hey all I'm trying to get a feel for angular and have ran into a little snag.
I have a container structure like the following:
<div class="main-container" ng-view>
<!-- The below divs are constantly being
reloaded based on the current URL and it's associated view -->
<div class="left-col">
</div>
<div class="right-col">
</div>
</div>
Before I implemented Angular I just had a simple script that would check the height of the window and set the height of the left column and right column divs accordingly.
With angular there is probably a better way to do this then attaching an event function to the window object. Basically I want to fire a function everytime a new view is rendered but not duplicate the below code in all of my angular controllers like so:
$scope.$on('$viewContentLoaded', setColumnHeight);
Any help would be appreciated. Thanks!
I've solved this problem in my app by having a root "Application Controller" at the top of the DOM tree. For example:
<body ng-controller='applicationController'>
...
<div class="ng-view"></div>
...
</body>
applicationController is always there, and can set up bindings on its scope when it is created.
How about putting that event listener on the root scope:
$rootScope.$on('$viewContentLoaded', setColumnHeight);
You could use something like this:
<div class="main-container" ng-view>
{{ setColumnHeight() }}
<!-- The below divs are constantly being
reloaded based on the current URL and it's associated view -->
<div class="left-col">
</div>
<div class="right-col">
</div>
</div>
and it will check the height every time a render is made, however, this seems to be a bit over processing.
The best approach would be to only update the height from both columns when the height of one of them changes. For that you could use DOM Mutation Observers, however they are not yet available on all browsers. If that's not a problem for you, check the mutation-summary lib.
If you are using jQuery you can also try this: https://github.com/jqui-dot-net/jQuery-mutate (examples here).

Categories

Resources