<ionic-content> / <ion-nav-view> not scrolling - ionic-framework

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.

Related

Fancybox is repeating pictures

i have created a gallery using fancy-box but i have a problem that when i open all items (all projects) it works properly as each item will show its own pictures (only three picture) as shown in this picture
(have only three thumbnails) but when i open a specific category (villas category) pictures for all villas will shown as this picture
(6 thumbnails included for two projects)
and if i press all project again i will have the same problem and the picture for all items will be shown (9 thumbnails for 3 items)
so i think the problem is with the java script and here below is the html code and java script code
sorry i am new to programming and i need your help, i appreciate your efforts
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.js"></script>
<script type="text/javascript">
jQuery(function ($) {
// fancybox
$(".fancybox").fancybox({
modal: false, // enable regular nav and close buttons
// add buttons helper (requires buttons helper js and css files)
padding:0,
helpers: {
thumbs : {
width : 50,
height : 50,
},
}
});
// filter selector
$(".filter").on("click", function () {
var $this = $(this);
// if we click the active tab, do nothing
if ( !$this.hasClass("active") ) {
$(".filter").removeClass("active");
$this.addClass("active"); // set the active tab
// get the data-rel value from selected tab and set as filter
var $filter = $this.data("rel");
// if we select view all, return to initial settings and show all
$filter == 'all' ?
$(".fancybox")
.attr("data-fancybox-group", "gallery")
.not(":visible")
.fadeIn()
: // otherwise
$(".fancybox")
.fadeOut(0)
.filter(function () {
// set data-filter value as the data-rel value of selected tab
return $(this).data("filter") == $filter;
})
// set data-fancybox-group and show filtered elements
.attr("data-fancybox-group", $filter)
.fadeIn(1000);
} // if
}); // on
}); // ready
</script>
<div id="galleryTab">
<a data-rel="all" href="javascript:;" class="filter active">All Projects</a>
<a data-rel="vil" href="javascript:;" class="filter">Villas</a>
<a data-rel="res" href="javascript:;" class="filter">Residential and Commercial</a>
<a data-rel="mix" href="javascript:;" class="filter">Mixed Used</a>
</div>
<div class="row"> </div>
<div class="col">
<div class="galleryWrap">
<ul id="projects">
<li id="liproject" data-tags="Villas"><a title="Mr.Omran Villa (G+1+R)" class="fancybox villa" data-filter="vil" rel="villa1" href="images/Projects/1.jpg"><img src="images/Projects/1s.jpg" alt="omran" width="240" height="160" class="img-responsive" id="img1"></a></li>
<div class="hidden"> <a class="fancybox" data-tags="Villas" data-filter="vil" rel="villa1" href="images/Projects/1h.jpg"><img src="images/Projects/1h.jpg" alt="omran"></a> <a class="fancybox" data-tags="Villas" data-filter="vil" rel="villa1" href="images/Projects/12h.jpg"><img src="images/Projects/12h.jpg" alt="omran"></a> </div>
<div> <li data-tags="Villas"><a title="Mr.saif Villa (G+1+R)" data-tags="Villas" class="fancybox" data-filter="vil" rel="villa2" href="images/Projects/2.jpg"><img src="images/Projects/2s.jpg" alt="saif" class="img-responsive" id="img2"></a></li>
<div class="hidden"> <a class="fancybox" data-tags="Villas" data-filter="vil" rel="villa2" href="images/Projects/21h.jpg"><img src="images/Projects/21h.jpg" alt="saif"></a> <a class="fancybox" data-tags="Villas" data-filter="vil" rel="villa2" href="images/Projects/22h.jpg"><img src="images/Projects/22h.jpg" alt="saif"></a> </div>
<div id="res"> <li data-tags="bldg"><a title="Ajman Tower (G+8Podium+26 Typical+R)" class="fancybox" data-tags="Residential and Commercial" data-filter="res" rel="bldg1" href="images/Projects/4.jpg"><img src="images/Projects/4s.jpg" alt="ajman" width="240" height="160" class="img-responsive" id="img3" border="0"></a></li>
<div class="hidden"> <a class="fancybox" data-filter="res" rel="bldg1" href="images/Projects/41h.jpg"><img src="images/Projects/41h.jpg" alt="ajman"></a> <a class="fancybox" data-filter="res" rel="bldg1" href="images/Projects/42h.jpg"><img src="images/Projects/42h.jpg" alt="ajman"></a> </div>
</div>
</div>
</ul>
</div>
</div>
<footer>©Copyright Qyas Engineering Consultancy All Rights Reserved. </footer>
</div>
I would suggest you to use Isotope + fancybox combination, see this example:
http://codepen.io/fancyapps/pen/EZKYPN
Because then your code could be simplified to something like this:
// Custom click event - open fancyBox manually
$('.fancybox').on('click', function() {
var visibleLinks = $('.fancybox:visible');
$.fancybox.open( visibleLinks, {}, visibleLinks.index( this ) );
return false;
});

pull to refresh in ionic does not refresh my list

Using ionic pull to refresh function does not update my list. Function is called and in console data is retrieved from serve but does not refresh my list.
here is my view:
<ion-list>
<ion-item class="list card" ng-repeat="pickup in pickups">
<div class="item">
<h2>{{pickup.title}}</h2>
<p>Request Date : {{pickup.added_date}}</p>
<p>Status :
<span class="positive" ng-if="pickup.status==0">On Queue</span>
<span class="energized" ng-if="pickup.status==1">On Process</span>
<span class="balanced" ng-if="pickup.status==2">On Collected</span>
<span class="assertive" ng-if="pickup.status==2">Cancelled</span>
</p>
</div>
<div class="item item-body">
<p>Contact : {{pickup.b_contact}}</p>
<p>Location : {{pickup.b_location}}</p>
<p>
<a class="button circular-btn icon ion-android-done button-energized" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,1)"
ng-if="pickup.status==0"></a>
<a class="button circular-btn ion-android-done-all button-balanced" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,2)"
ng-if="pickup.status==0|| pickup.status==1"></a>
<a class="button circular-btn icon ion-close-circled button-assertive" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,3)"
ng-if="pickup.status==0|| pickup.status==1|| pickup.status==2"></a>
</p>
</div>
</ion-item>
</ion-list>
</ion-content>
my controller code:
.controller('AppCtrl', function ($scope, Service, $ionicLoading, $ionicModal, $ionicPopup, $timeout, $state, $http, $stateParams) {
$scope.doRefresh = function () {
Service.getpickup($state, $http).success(function (data) {
$scope.pickups = data.pickup_request;
console.log(data.pickup_request);
})
.finally(function () {
$scope.$broadcast('scroll.refreshComplete');
});
}
});
Please guide me. Thanks in advance.
Have you used the ion-refresher tag in your html? I cant see it in your code. If not, use this
<ion-refresher pulling-text="Pull to refresh..." on-refresh="doRefresh()">
Also, try manually adding the items to your list like this and see if that works. (check that data.pickup_request is an array as well)
$scope.pickups.push.apply($scope.pickups, data.pickup_request);
I have found the issues. I have the view in pickupCtrl but i was calling the scope function in another control. Thank you every one for your guide.Thanks a lot.

Ionic Android inappbrowser plugin - set all links in iframe to open in system browser

How could I set all links inside iframe to open in system web browser, instead of WebView? I'm using inappbrowser plugin.
<ion-view style="" title="iframe">
<ion-content class="has-header" overflow-scroll="true" padding="true">
<div style="" class="list card">
<div class="item item-divider-android">iframe content</div>
<div class="item item-body-android">
<div style="">
<center>
<iframe src='{{trustSrc(iframe.src)}}' frameborder="0" width="100%" height="500" scrolling="yes"></iframe></center>
</div>
</div>
</div>
</ion-content>
I found this solution in that gist (I didn't write it).
Basically it declares an angular filter that converts href links into window.open that opens the links using inappbrowser plugin
var myApp = angular.module('myApp', ['ngSanitize']);
myApp.filter('hrefToJS', function ($sce, $sanitize) {
return function (text) {
var regex = /href="([\S]+)"/g;
var newString = $sanitize(text).replace(regex, "onClick=\"window.open('$1', '_blank', 'location=yes')\"");
return $sce.trustAsHtml(newString);
}
});
myApp.controller('MyCtrl', function ($scope) {
$scope.html = "This a link: <a href='https://www.google.com'>Google</a> :)";
$scope.plaintext = "This is a link: https://www.google.com :) "
});
Usage in your HTML template:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<h1>Before</h1>
<p ng-bind-html="html"></p>
<p ng-bind-html="plaintext"></p>
<h1>After</h1>
<p ng-bind-html="html | hrefToJS"></p>
<p ng-bind-html="plaintext | linky | hrefToJS"></p>
</div>
</div>

Ionic scroll won't fire on load with $getByHandle()

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

Intel xdk, "Shutdown (name of app)" to pop up on back button

I would like to have the pop up "Shutdown (name of app)" on the back button and not on the default button that is right now..(Intel xdk app framework)
How could i do that? Please help me!
For that Add a custom header like.........
<div class="panel" title="Custom title" data-footer="footer_1" data-header='custom-header' id="page_5" data-appbuilder-object="page">
<div class="container" id="page_5_container" style="width:100%" data-appbuilder-object="container" data-position="static">
your content here...............
</div>
</div>
<header id="custom-header" data-appbuilder-object="header">
<a id="backButton" onclick="popup()" class="button back" style="visibility: visible; ">Back</a>
<h1 id="pageTitle" class="">
Custom title
</h1>
</header>