Angular JS ng-view change store scroll position - angularjs

I used button click to change the route to the next page. Angular JS retain the scroll position and doesn't scroll to the top of the ng-view.
1. Disabling $anchorScroll doesn't work
2. Using window scroll to doesn't work
$rootScope.on("$routeChangeSuccess", function(){
window.scrollTo(0,90);
})
However, to keep the fix header on iPad, the following window scroll works.
$(document).on('blur', 'input, textarea', function() {
setTimeout(function() {
window.scrollTo(document.body.scrollLeft,document.body.scrollTop);
}, 0);
});
Any suggestions? How to clear the stored scroll positions by angualar js view?

What you want is not disable anchorscroll, but enable it. You can achieve what you want using the following code:
<div data-ng-view data-autoscroll="true"></div>
or:
<div data-ng-view data-autoscroll></div>
as pointed in the AngularJS docs.

Minor update to #Rafael's answer.
Since Angular 1.3.14 you can use simpler syntax to enable autoscroll to the top when switching views with ngView:
<div ngView autoscroll></div>
Angular Docs

Have you tried setting autoscroll to false on your ng-view element?
<div data-ng-view data-autoscroll="false"></div>

Related

ionic Popover content position issue

I've implemented a popover with number keys on it using this library https://github.com/alvarowolfx/ng-keypad.
When I click on an input field, the popover appears. But, sometimes the position of content of popover is not correct.
Can you please help me.
Here is my html:
<script id="keypad-popover.html" type="text/ng-template">
<ion-popover-view class="aiv-keypad">
<ion-content overflow-scroll=false>
<div class="ios">
<ng-keypad on-key-pressed='onKeyPressed'>
<ng-key ng-repeat='key in aivkeys' ng-key-data='key' ng-key-type='keypad.type'>{{key}}</ng-key>
<!--<ng-key ng-key-type='keypad.type' ng-key-data="keypad.data">{{keypad.data}}</ng-key>-->
</ng-keypad>
</div>
</ion-content>
</ion-popover-view>
</script>
In controller,
$ionicPopover.fromTemplateUrl('keypad-popover.html', {
scope: $scope,
backdropClickToClose:false
}).then(function(popover) {
$scope.keypad_popover = popover;
});
Expected,
Sometimes, this problem occurs,
While the problem could be described as overflow scrolling, the overflow-scroll=false attribute you're using on <ion-content> means you are explicitly using Ionic scroll, which is to use transform3d() in CSS to implement scrolling. Usually overflow-scroll=false is the default.
If you'd turn overflow-scroll=true the element would use "traditional" overflow-y: auto CSS rule instead of transform3d(). With popovers, this is usually enough to fix the problem you describe.
If not—you can disable element's scrolling altogether with scroll=false attribute.

AngularJS - looking to add and remove an iframe based on dom events

I would like to add an iframe to a page when certain links are clicked and remove it when other mouse events happen on the page. From what I can see, it seems that using an AngularJS directive would be the best way to do this. What I'm not sure about is what is the best way to format the directive. I'm thinking of making the directive at the attribute level...something like this:
<div myIframeDirective></div>
What I'm not sure of is the best way of removing/adding the directive contents (an iframe and a header above it) when various click events happen on the main page. Not looking for anyone to write the code for me...just looking for examples of how this can be best accomplished.
You should be using ng-if.
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
Here's a working example:
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
</div>
In Angular, ng-if will remove the iframe from the DOM if it is false.
This means the URL will NOT be requested until ng-if is true.
<iframe ng-if="frameDisplayed" ng-src="{{src}}"></iframe>
And use the link
Toggle
Then in your controller, you can control what your iframe display:
$scope.src = 'https://angularjs.org';

AngularJS hide progress bar after ng-animate complete

My requirement is to display a spinner image on every $route change request and hide the spinner image on success or error. I am using angular-animate.js to slide the view after the $route success
<div ng-cloak ng-controller="sliderController">
<div ng-view ng-class="{slide: true, left: isDownwards, right: !isDownwards}">
</div>
</div>
I need to hide to progress image (Spinner) after the new page is loaded (ie : on complete page animation)
Any help would be appreciated.
In your code, I don't see anything that is showing what you're doing for the spinner. So this will be just a stab in the dark at what you're looking to accomplish.
One option is to use an app-wide progress bar. Think of how YouTube does page transitions. The Angular Loading Bar is a good solution to accomplish this. I think it uses $http interceptors to do it (good explanation of interceptors).
Another option would be to use $routeChangeStart and $routeChangeSuccess that are part of the $route provider. You can simply have a $scope variable that triggers whether or not the image should be visible.
$scope.$on("$routeChangeStart", function(event, next,current) {
$scope.spinnerDisplayed = true;
});
$scope.$on("$routeChangeSuccess", function(event, next,current) {
$scope.spinnerDisplayed = false;
});
And then your HTML would just have a basic ng-show/hide
<div ng-show="spinnerDisplayed">
<!-- some spinner image here -->
</div>

Master Page Concept in AngularJS?

I would like to create master page, that is main page which will be used in all views of the application.
For example, Left navigation and top men navigation. This navigation should be displayed in all the views, whenever url changes in application.
As per ng-view, it only renders given partial view and replace previous view. In the image above all my left and top navigation should be displayed by using angular Controller.
Controller code
angular.module('modelDemo').controller("authCtrl", ['$scope', function($scope) {
$scope.list;
}]);
Please let me know, how can i achieve this
You can use angular-route or Angular-ui-router, and setting your master, following this steps:
Step 1. Make your index.html your master page.
Step 2. Add the <header>, <footer>, <aside>, <div>, etc. referencing your templates by using ng-include
NOTE: your left and top navigation will be part of it
Step 3. The content of the view will be rendered using the directive attribute ng-view or ui-view
Step 4. Use your module app.config() to configure the children pages
Source:
using Angular Route: https://docs.angularjs.org/tutorial/step_07
template for a brand-new app: https://github.com/angular/angular-seed
using Angular UI Router: Angular Tutorial 30 mins
ng view should be able to do that just fine. Keep your top navigation / left navigation html intact and use ng view for the various display area. http://docs.angularjs.org/api/ng.directive:ngView
To use the controller from the top navigation inside ng-view you can use $parent to get access to that scope : https://stackoverflow.com/a/14700326/390330
Fiddle for parent scope : http://jsfiddle.net/ezhrw/2/
<button ng:click="$parent.letter = greek">Assignment expression {{ greek }}</button>
I was trying to create the same concept, but needed a way to define placeholders. I started experimenting in Plnkr.co and thus far, I resorted to using a LayoutManager that drives itself from settings within the routeProvider object.
Here is an example: http://embed.plnkr.co/4GPDfTSQCuqukJE7AniZ/
You'll see an example of how multiple routes use the same header and footer, I did not include an example with a sidebar.
Let me explain the LayoutManager.
I wanted to have placeholders that could be overridden. In this example, I have a toolbar that contains a title and provides a space to the right of the title for additional toolbar items. This gives views an opportunity to throw in additional functionality.
All of this is driven by the LayoutManager. The LayoutManager is a service that reads layout properties set on the $routeProvider. I wanted to implement this in a way keep things clean and self contained, per route. The LayoutManager is injected into the toolbar directive. The toolbar directive drives it's scope properties of the LayoutManager.
In turn, the LayoutManager has a dependency on the routeProvider as well as the rootScope $routeChange event.
I'm very new to Angular, open to suggestions.
I could not see any problem, if you are using bootstrap then use can easily divide your screen as you want
<div class="row">
<div class="col-lg-3">
Left panel
</div>
<div class="col-lg-9" style="border:1px solid #999; overflow-y:auto">
<div> Top Banner </div>
<!-- Main view to render all the page -->
<div ui-view> </div>
</div>
</div>
If you want complete demo and code on then see this link
Edited: 3 Nov. 2016:
If you are using ui-router then we can user abstract state to create different master pages.
You don't need to play show/hide, ng-if but just define the routing properly with you master pages and child pages
Better to see the detail
I know this is an old thread, but thought it should be noted that as of Angular 1.5+ we have been introduced to components. Instead of dealing with routes with named views and all that nonsense or using ngInclude you should be using a header component and footer component. Simply add these to your index.html (or whatever you call your master html template) and voila.
For example (this is using Angular Material and is missing the layout module but hopefully you get the point)
1. Added to index.html
<layout-header></layout-header>
2. header.component.js (you don't need all of this but I think it's helpful)
(function () {
'use strict';
angular
.module('layout')
.component('layoutHeader', {
templateUrl: 'layout/header.html',
bindings: {},
controller: Controller
});
Controller.$inject = [];
function Controller() {
var ctrl = this;
initialize();
////////////////////
function initialize(){
}
}
}());
3. header.html
<md-toolbar>
<div class="md-toolbar-tools">
<h2>
<span>Really Awesome Title!!!!</span>
</h2>
<span flex></span>
<md-button class="md-icon-button" aria-label="More">
<md-icon class="material-icons">more_vert</md-icon>
</md-button>
</div>
</md-toolbar>

How to get AngularStrap active tab?

I am somewhat new to using Angular and AngularStrap directives. I need to use the tab directive with static markup like the example:
<div data-fade="1" bs-tabs>
<div data-title="'Home'"><p>Static tab content A</p></div>
<div data-title="'Profile'"><p>Static tab content B</p></div>
</div>
On another part of the page I would like to display a div only when the first tab is selected. The div is not part of the tabs, but is in the same overall controller. How can I show/hide this div based on the selected tab?
Something like this?
<div ng-show="???? active tab stuff here ????">Home tab is selected</div>
Thanks for any help.
As shown in the example on the AngularStrap page the active tap is stored in
tabs.activeTab
So you can use this property to conditionally show display something else like so
<div ng-show="tabs.activeTab == 0">The first tab is active</div>
UPDATE
Even with non object tabs you can just bind a model against the bs-tabs to store the active ID like so:
<div data-fade="1" ng-model="tabs.activeTab" bs-tabs>
Here is an updated plnkr. (Click on the 3rd tab and see the 'Test' text appear)
I found somewhat of a hack to resolve this issue for now. This does not seem like the best approach, so if someone has a better idea, please share.
I realized that the bsTabs directive is creating data-toggle attributes for each tab. By watching the data-toggle shown event, I am able to recognize the tab change and display the div. The controller code looks like this:
$scope.HomeTabSelected = true;
function watchTab() {
$('a[data-toggle="tab"]').on('shown', function (e) {
$scope.$apply($scope.HomeTabSelected = (e.target.innerHTML == "Home"));
})
}
setTimeout(watchTab, 2000); // setTimeout necessary to allow directive to render
and the HTML div uses ng-show.
<div ng-show="HomeTabSelected">Home tab is selected</div>

Resources