I am working on an ionic project.I want to share data between pages. Below is what I have done. But it is not working.Can some one tell me what I am doing wrong.I let the user to add the data to my reminder.html page and I want to show that added data in my meds.html.
This is my services.js
.factory('Authorization', [function() {
authorization = {};
authorization.drug = "";
return authorization;
}]);
This is my controller.js
.controller('reminderCtrl', ['$scope', '$stateParams','Authorization'
function ($scope, $stateParams,Authorization) {
//$scope.user = Authorization;
}])
.controller('medsCtrl', ['$scope', '$stateParams','Authorization',
function ($scope, $stateParams,Authorization) {
//$scope.user = Authorization;
}])
This is my app.js
controller('medsCtrl', function($scope, Authorization) {
$scope.user = Authorization;
})
.controller('reminderCtrl', function($scope, Authorization) {
$scope.user = Authorization;
})
This is my reminder.html. The page that I used to add data.
<button class="button button-royal icon ion-android-done" ng-click = "add(user)" ></button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
<form id="reminder2-form7" class="list">
<label class="item item-input" id="reminder2-input9" >
<input type="text" placeholder="Drug" ng-model = "user.drug" >
</label>
This is my meds.html page .This is the page that I want to show the data that I was added to the reminder.html.
<ion-view title="Meds" id="page14">
<ion-nav-buttons side="right" class="has-header">
<button class="button button-royal icon ion-android-add-circle"></button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
<ion-list id="meds-list6">
<label class="item item-input" id="meds-search3">
<i class="icon ion-search placeholder-icon"></i>
<input type="search" placeholder="med name">
</label>
<ion-item class="item-thumbnail-left dark" id="meds-list-item21">
<img src="img/CynoZgjCQlSOdh14y24s_drug-disposal.jpg">
<h2dark>Metformin
<p>for diabetes</p>
</h2dark>
</ion-item>
<ion-item class="item-thumbnail-left" id="meds-list-item22">
<img src="img/ZVN6KzlgTP2WdrghQtCH_images.jpg">
<h2>Drug:{{user.drug}}</h2>
</ion-item>
</ion-list>
<a ui-sref="medDiary2" id="meds-button7" class="button button-royal button-clear icon ion-android-add-circle"></a>
<a ui-sref="searchMeds" id="meds-button10" class="button button-royal button-clear icon ion-android-search"></a>
<a ui-sref="reminder" id="meds-button25" class="button button-royal button-clear icon ion-android-alarm-clock"></a>
</ion-content>
</ion-view>
You can use $broadcast in reminderCtrl controller
$scope.addData = function () {
var addObj = {};
// your logic here
$rootScope.$broadcast('add-event', { addedObject: addObj });
}
and listen back to previous event using $on in medsCtrl controller
$scope.$on('add-event', function(event, args) {
var addedObject = args.addedObject;
// Do what you want to do with passed object
console.log(addedObject)
});
Does anyone know how to open a bootstrap modal with vue 2.0? Before vue.js I would simply open the modal by using jQuery: $('#myModal').modal('show');
However, is there a proper way I should do this in Vue?
Thank you.
My code is based on the Michael Tranchida's answer.
Bootstrap 3 html:
<div id="app">
<div v-if="showModal">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" #click="showModal=false">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
modal body
</div>
</div>
</div>
</div>
</div>
</transition>
</div>
<button id="show-modal" #click="showModal = true">Show Modal</button>
</div>
Bootstrap 4 html:
<div id="app">
<div v-if="showModal">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" #click="showModal = false">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" #click="showModal = false">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</transition>
</div>
<button #click="showModal = true">Click</button>
</div>
js:
new Vue({
el: '#app',
data: {
showModal: false
}
})
css:
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
display: table;
transition: opacity .3s ease;
}
.modal-wrapper {
display: table-cell;
vertical-align: middle;
}
And in jsfiddle
Tried to write a code that using VueJS transitions to operate native Bootsrap animations.
HTML:
<div id="exampleModal">
<!-- Button trigger modal-->
<button class="btn btn-primary m-5" type="button" #click="showModal = !showModal">Launch demo modal</button>
<!-- Modal-->
<transition #enter="startTransitionModal" #after-enter="endTransitionModal" #before-leave="endTransitionModal" #after-leave="startTransitionModal">
<div class="modal fade" v-if="showModal" ref="modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button class="close" type="button" #click="showModal = !showModal"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">...</div>
<div class="modal-footer">
<button class="btn btn-secondary" #click="showModal = !showModal">Close</button>
<button class="btn btn-primary" type="button">Save changes</button>
</div>
</div>
</div>
</div>
</transition>
<div class="modal-backdrop fade d-none" ref="backdrop"></div>
</div>
Vue.JS:
var vm = new Vue({
el: "#exampleModal",
data: {
showModal: false,
},
methods: {
startTransitionModal() {
vm.$refs.backdrop.classList.toggle("d-block");
vm.$refs.modal.classList.toggle("d-block");
},
endTransitionModal() {
vm.$refs.backdrop.classList.toggle("show");
vm.$refs.modal.classList.toggle("show");
}
}
});
Example on Codepen if you are not familiar with Pug click View compiled HTML on a dropdown window in HTML section.
This is the basic example of how Modals works in Bootstrap. I'll appreciate if anyone will adopt it for general purposes.
Have a great code 🦀!
I did an amalgam of the Vue.js Modal example and the Bootstrap 3.* live demo.
Basically, I used the Vue.js modal example but replaced (sorta) the Vue.js "html" part with the bootstrap modal html markup, save one thing (I think). I had to strip the outer div from the bootstrap 3, then it just worked, voila!
So the relevant code is regarding bootstrap. Just strip the outer div from the bootstrap markup and it should work. So...
ugh, a site for developers and i can't easily paste in code? This has been a serious continuing problem for me. Am i the only one? Based on history, I'm prolly an idiot and there's an easy way to paste in code, please advise. Every time i try, it's a horrible hack of formatting, at best.
i'll provide a sample jsfiddle of how i did it if requested.
Using the $nextTick() function worked for me. It just waits until Vue has updated the DOM and then shows the modal:
HTML
<div v-if="is_modal_visible" id="modal" class="modal fade">...</div>
JS
{
data: {
isModalVisible: false,
},
methods: {
showModal() {
this.isModalVisible = true;
this.$nextTick(() => {
$('#modal').modal('show');
});
}
},
}
Here's the Vue way to open a Bootstrap modal..
Bootstrap 5 (2022)
Now that Bootstrap 5 no longer requires jQuery, it's easy to use the Bootstrap modal component modularly. You can simply use the data-bs attributes, or create a Vue wrapper component like this...
<bs-modal id="theModal">
<button class="btn btn-info" slot="trigger"> Bootstrap modal </button>
<div slot="target" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</bs-modal>
const { Modal } = bootstrap
const modal = Vue.component('bsModal', {
template: `
<div>
<slot name="trigger"></slot>
<slot name="target"></slot>
</div>
`,
mounted() {
var trigger = this.$slots['trigger'][0].elm
var target = this.$slots['target'][0].elm
trigger.addEventListener('click',()=>{
var theModal = new Modal(target, {})
theModal.show()
})
},
})
Bootstrap 5 Modal in Vue Demo
Bootstrap 4
Bootstrap 4 JS components require jQuery, but it's not necessary (or desirable) to use jQuery in Vue components. Instead manipulate the DOM using Vue...
Launch modal
<div :class="modalClasses" class="fade" id="reject" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modal</h4>
<button type="button" class="close" #click="toggle()">×</button>
</div>
<div class="modal-body"> ... </div>
</div>
</div>
</div>
var vm = new Vue({
el: '#app',
data () {
return {
modalClasses: ['modal','fade'],
}
},
methods: {
toggle() {
document.body.className += ' modal-open'
let modalClasses = this.modalClasses
if (modalClasses.indexOf('d-block') > -1) {
modalClasses.pop()
modalClasses.pop()
//hide backdrop
let backdrop = document.querySelector('.modal-backdrop')
document.body.removeChild(backdrop)
}
else {
modalClasses.push('d-block')
modalClasses.push('show')
//show backdrop
let backdrop = document.createElement('div')
backdrop.classList = "modal-backdrop fade show"
document.body.appendChild(backdrop)
}
}
}
})
Bootstrap 4 Vue Modal Demo
My priority was to keep using Bootstrap code, since they made the effort to make the modal work, fixin' the scrollbars and all. I found existing proposals try to mimic that, but they go only part of the way. I didn't even want to leave it to chance: I just wanted to use actual bootstrap code.
Additionally, I wanted to have a procedural interface, e.g. calling dialog.show(gimme plenty of parameters here), not just toggling a variable somewhere (even if that variable could be a complex object).
I also wanted to have Vue's reactivity and component rendering for the actual dialog contents.
The problem to solve was that Vue refuses to cooperate if it finds component's DOM to have been manipulated externally. So, basically, I moved the outer div declaring the modal itself, out of the component and registered the component such that I also gain procedural access to the dialogs.
Code like this is possible:
window.mydialog.yesNo('Question', 'Do you like this dialog?')
On to the solution.
main.html (basically just the outer div wrapping our component):
<div class="modal fade" id="df-modal-handler" tabindex="-1" role="dialog" aria-hidden="true">
<df-modal-handler/>
</div>
component-template.html (the rest of the modal):
<script type="text/x-template" id="df-modal-handler-template">
<div :class="'modal-dialog ' + sizeClass" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ title }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" v-html="body"/>
<div class="modal-footer">
<button type="button" v-for="button in buttons" :class="button.classes" v-bind="button.arias"
#click.stop="buttonClick(button, callback)">{{ button.text }}
</button>
</div>
</div>
</div>
</script>
component-def.js - contains logic for showing & manipulating the dialog, also supports dialog stacks in case you make a mistake and invoke two dialogs in sequence:
Vue.component('df-modal-handler', {
template: `#df-modal-handler-template`,
props: {},
data() {
return {
dialogs: [],
initialEventAssignDone: false,
};
},
computed: {
bootstrapDialog() { return document.querySelector('#df-modal-handler'); },
currentDialog() { return this.dialogs.length ? this.dialogs[this.dialogs.length - 1] : null; },
sizeClass() {
let dlg = this.currentDialog;
if (!dlg) return 'modal-sm';
if (dlg.large || ['large', 'lg', 'modal-lg'].includes(dlg.size)) return 'modal-lg';
else if (dlg.small || ['small', 'sm', 'modal-sm'].includes(dlg.size)) return 'modal-sm';
return '';
},
title() { return this.currentDialog ? this.currentDialog.title : 'No dialogs to show!'; },
body() { return this.currentDialog ? this.currentDialog.body : 'No dialogs have been invoked'; },
callback() { return this.currentDialog ? this.currentDialog.callback : null; },
buttons() {
const self = this;
let res = this.currentDialog && this.currentDialog.buttons ? this.currentDialog.buttons : [{close: 'default'}];
return res.map(value => {
if (value.close == 'default') value = {
text: 'Close',
classes: 'btn btn-secondary',
data_return: 'close'
};
else if (value.yes == 'default') value = {
text: 'Yes',
classes: 'btn btn-primary',
data_return: 'yes'
};
else if (value.no == 'default') value = {
text: 'No',
classes: 'btn btn-secondary',
data_return: 'no'
};
value.arias = value.arias || {};
let clss = (value.classes || '').split(' ');
if (clss.indexOf('btn') == -1) clss.push('btn');
value.classes = clss.join(' ');
return value;
});
},
},
created() {
// make our API available
window.mydialog = this;
},
methods: {
show: function show() {
const self = this;
if (!self.initialEventAssignDone) {
// created is too soon. if we try to do this there, the dialog won't even show.
self.initialEventAssignDone = true;
$(self.bootstrapDialog).on('hide.bs.modal', function (event) {
let callback = null;
if (self.dialogs.length) callback = self.dialogs.pop().callback;
if (self.dialogs.length) event.preventDefault();
if (callback && callback.df_called !== true) callback(null);
});
}
$(self.bootstrapDialog).modal('show');
},
hide: function hide() {
$(this.bootstrapDialog).modal('hide');
},
buttonClick(button, callback) {
if (callback) { callback(button.data_return); callback.df_called = true; }
else console.log(button);
this.hide();
},
yesNo(title, question, callback) {
this.dialogs.push({
title: title, body: question, buttons: [{yes: 'default'}, {no: 'default'}], callback: callback
});
this.show();
},
},
});
Do note that this solution creates one single dialog instance in the DOM and re-uses that for all your dialog needs. There are no transitions (yet), so the UX isn't too great when there are multiple active dialogs. It's bad practice anyway, but I wanted it covered because you never know...
Dialog body is actually a v-html, so just instantiate your component with some parameters to have it draw the body itself.
I create button with params for modal and simply trigger click()
document.getElementById('modalOpenBtn').click()
<a id="modalOpenBtn" data-toggle="modal" data-target="#Modal">open modal</a>
<div class="modal" id="Modal" tabindex="-1" role="dialog" aria-labelledby="orderSubmitModalLabel" aria-hidden="true">...</div>
From https://getbootstrap.com/docs/4.0/getting-started/javascript/#programmatic-api
$('#myModal').modal('show')
You can do this from a Vue method and it works just fine.
modal doc
Vue.component('modal', {
template: '#modal-template'
})
// start app
new Vue({
el: '#app',
data: {
showModal: false
}
})
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
default body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
<!--
you can use custom content here to overwrite
default content
-->
<h3 slot="header">custom header</h3>
</modal>
</div>
I'm making a simple app that keeps track of my hours at work. I'm developing the app for android and I'm having a problem with the scrolling.
Structure of the App:
I have a header bar and a footer which are both outside of the < ion-content > tab, so I don't expect that to be scrollable. Within the < ion-content > I have used an < ion-side-menus > tab and finally within the < ion-side-menu-content > tab I have put in a < ion-nav-view > tab which is controlled by my state provider.
Everything works fine, the menu is operational and the views change according to their design. Within one of my views I have a list that exceeds the size HERE IS WHERE THE PROBLEM BEGINS!. When using a computer, I can pull the page down (as if I were trying to refresh it) but when I try to scroll down the page goes straight to the top of the list unless I keep dragging and have my finger on the left click. Furthermore the rest of the content in the list is not loaded. The listed is literally cropped to where it stopped before I dragged down. When I export it to an android app I cant even drag to scroll. The scrolling is literally non-functional.
I've attached some code
var app = angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: "views/home.html",
controller: "MainController"
})
.state('rotas', {
url: '/rotas',
templateUrl: "views/rotas.html",
controller: "MainController"
})
.state('update', {
url: '/update',
templateUrl: "views/update.html",
controller: "UpdateController"
});
$urlRouterProvider.otherwise('/');
});
.scroll {
height: 100%;
}
/* Before i put in this CSS element, the content in the view was cropped SIGNIFICANTLY. not sure exactly what it does but it solved my problem. All other CSS elements are colour changes*/
index.html
<html>
<head>...</head>
<body ng-app="starter" ng-controller="MainController">
<ion-pane>
<ion-header-bar class="bar-stable">
<!--header bar -->
<h1 class="title">Shiftwiz.{{controllerCheck}}</h1>
</ion-header-bar>
<div class="bar bar-footer bar-stable">
<!--footer-->
<table id="footer-table">
<tr>
<td>
<a ui-sref="rotas" ng-click="activity.doRotas()">
<div>Rotas</div>
</a>
</td>
<td>
<a ui-sref="update" ng-click="activity.doUpdate()">
<div>Update</div>
</a>
</td>
</tr>
</table>
</div>
<ion-content>
<ion-side-menus>
<ion-side-menu-content overflow-scroll="true">
<!--menu-->
<button class="button button-full button-positive" ng-click="toggleLeft()">
Rotas: {{activity.rotas}} Update: {{activity.update}}
</button>
<ion-nav-view overflow-scroll="true"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-item>Next Week</ion-item>
<ion-item ng-click="toggleLeft(); activity.chooseThisWeek(); calcDates()">This Week</ion-item>
<div id="further-weeks" ng-show="activity.rotas">
<ion-item>Last Week</ion-item>
<ion-item>Last Two</ion-item>
<ion-item>Last Three</ion-item>
</div>
</ion-side-menu>
</ion-side-menus>
</ion-content>
</ion-pane>
</body>
</html>
update.html
<!-- this view contains the list which isn't rendering-->
<div class="card" ng-repeat="day in unPublishedRota">
<a ng-click="day.toggleState()">
<div class="item item-divider">
<p class="day">{{ day.date | date:"EEEE" }}
<br />{{day.date | date:"d, MMM y"}}</p>
<p class="times">{{day.start}} | {{day.finish}}
<br />{{day.hours}} hrs</p>
</div>
</a>
Your update.html contents should be wrapped in <ion-view> and <ion-content> elements.
<ion-view>
<ion-content>
<div class="card" ng-repeat="day in unPublishedRota">
<a ng-click="day.toggleState()">
<div class="item item-divider">
<p class="day">{{ day.date | date:"EEEE" }}
<br />{{day.date | date:"d, MMM y"}}</p>
<p class="times">{{day.start}} | {{day.finish}}
<br />{{day.hours}} hrs</p>
</div>
</a>
</div>
</ion-content>
</ion-view>
You can also have a look at a working sidemenu example by Ionic.
I have a main view that has a button "AddSkillBtn" which on clicked shows a modal popup witha partial view inside. Works fine so far. I have a link inside the partial view "addAnotherSkill" which on clicked has to show an alert. However, the click event doesn't get fired at all. Please find below the code snippet - Any help much appreciated!!
**jQuery:**
$('#AddSkillBtn').click(function (e) {
$.ajax({
url: '#Url.Action("MyAction", "MyController")',
type: "POST"
success: function (result) {
$("#AddContainer").html(result);
$('#AddModal').modal('show');
}
});
});
$("#addAnotherSkill").on('click', function () {
alert("Hi!!");
});
**Main View**
<p><a id="AddSkillBtn" href="javascript:void(0)" class="btn btn-rounded btn-primary">Add new Skill</a></p>
<div class="modal modal-wide fade" id="AddModal" tabindex="-1" role="dialog" aria-labelledby="AddLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="AddLabel">Add New Skills</h4>
</div>
<div class="modal-body">
<div id="AddContainer">
</div>
</div>
</div>
</div>
</div>
**Partial View rendered in the modal popup has**
<a id="addAnotherSkill" href="javascript:void(0)"><i class="fa fa-plus"></i> Add Another</a> //clicking on this link does nothing
Your element with id="addAnotherSkill" is being added to DOM dynamically. In order to use event delegation using the .on() function, it needs to be
$(document).on('click', '#addAnotherSkill', function (e) {
e.preventDefault();
...
}
Note you should change document to the closest ancestor of the element which exists when the page is first loaded.
Note also the use of e.preventDefault() which means that you can just use <a id="addAnotherSkill" href="#"> (my preference but I have seen arguments for and against - for example the answers here)
I'm trying to scroll down to delegate-handle="start" with ionic on load. When i try to run it, i get this message in console.
Delegate for handle "small" could not find a corresponding element with delegate-handle="small"! scrollTop() was not called!
Possible cause: If you are calling scrollTop() immediately, and your element with delegate-handle="small" is a child of your controller, then your element may not be compiled yet. Put a $timeout around your call to scrollTop() and try again.
My code looks like this, can somebody maybe see what is wrong?
$timeout(function() {
$ionicScrollDelegate.$getByHandle('start').scrollTop();
}, 10);
If i use $ionicScrollDelegate.scrollBottom(), it will scroll to the bottom, so it must be a problem with the specific function.
The html code
<ion-view title="Kalender">
<ion-content>
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
<div delegate-handle="start"></div>
</ion-content>
</ion-view>
Thanks.
Ionic 1.0.0-beta14 has some strange issue with getByHandle() so you can do it this way:
$timeout(function() {
var startHandle = _.find($ionicScrollDelegate._instances, function (s) {
return s.$$delegateHandle === "start";
});
startHandle.scrollTop();
});
Solution source at forum.ionicframework.com
I think there is a misunderstanding about what the delegate handle does here. Delegate handle is a way to name scroll/content containers. Think of it like a way to give your <ion-content> container a unique name that can be later used with the service. It is possible to have multiple <ion-content> containers on a single view, and this is why the naming is necessary. If you only have one scroll area or don't specify the handle, then it just uses the first view it finds.
You want to scroll to a particular place in the application, which is the job of $ionicScrollDelegate.anchorScroll('element-id');. Take a look at your code here with some modifications. I've put the delegate handle in the correct place, and then use the anchorScroll method to automatically scroll to that ID in the page.
Markup
<ion-view title="Kalender">
<ion-content delegate-handle="kalendar">
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
<div id="start"></div>
</ion-content>
</ion-view>
Controller
$timeout(function() {
$ionicScrollDelegate.$getByHandle('kalendar').anchorScroll('start');
}, 10);
Specify the dalegate-handler in ion-content
<ion-view title="Kalender">
<ion-content delegate-handle="start">
<ion-list ng-repeat="activity in calendar">
<div class="item item-divider" ng-show="activity.date_divider != null" data-year="{{activity.year}}">
<div class="header-divider-small">{{activity.year}}</div>
<div class="header-divider">{{activity.date_divider}}</div>
</div>
<div class="item item-icon-right calendar" ng-show="activity.date_divider == null">
<span class="header">{{activity.name}}</span>
<br />
<span class="text">{{activity.time}} - {{activity.place}}</span>
<a class="button button-icon icon {{activity.icon}} right not-selected"></a>
</div>
</ion-list>
</ion-content>
</ion-view>
Scroll top can be achieved by forgetting the scroll position which can be achieved by using
$scope.$on("$destroy", function() {
var delegate = $ionicScrollDelegate.$getByHandle('start');
delegate. forgetScrollPosition();
});
Use
$ionicScrollDelegate.$getByHandle('start').scrollTop(); //To scroll to Top.
As I noticed delegate-handle won't work if used with overflow-scroll.
I managed to do it this way:
$scope.scrollHandle = some-handle-value-that-you-want-to-use;
$scope.$on('$ionicView.loaded', function () {
$timeout(function () {
scrollView = $ionicScrollDelegate._instances.filter(function (s) {
if (!s.$$delegateHandle) return false;
return $parse(s.$$delegateHandle.slice(2, -2))
(angular.element(s.element).scope()) == $scope.scrollHandle;
})[0];
}).then(function () {
scrollView.scrollTo(0, 0, false);
});
});
In the template:
delegate-handle="{{scrollHandle}}"
EDIT:
This doesn't work anymore, check this answer for new solution: https://stackoverflow.com/a/32123613/1630623