angular - scroll to element on div element display visiable - angularjs

Trying to manage for angular to scroll automatically to a specific div element when this element becomes visible.
Already searching and trying for hours (no joke) with no success.
So far tried a couple of modules
'angular-scroll'
'angular-ui-scroll'
some others i already forgot
And coudn't get one of them to work (or only on ng-click).
How far did I get?
For this question to answer; I found an example witch basically scrolls but is not what I'am trying to get tho.
e.g.
<button ng-click="scrollToHash()">Scroll</button>
..
..
<div id="#div">
..
</div>
-
function scrollController ($scope, User, $location, $anchorScroll) {
$scope.scrollToHash = function () {
$scope.hash('div');
$anchorScroll();
};
};
This way I can't gat any 'animation duration' on it.
What I know what should work is to set a $watch on the element and call the function if the element is shown.
Not getting anywhere so I ask you guys for help.
Still new on Angular so please don't blame this newbie!
Thanks

I created a service to get my scroll going. You can try this.
Controller:
app.controller("scrollController", function ($scope, scrollToTopService) {
"use strict";
$scope.scrollToHash= function () {
scrollToTopService.scrollToTop();
};
});
Service:
app.service('scrollToTopService', function ($location, $anchorScroll) {
"use strict";
this.scrollToTop = function () {
$anchorScroll.yOffset = 80; //I want it top drop 80px from id. You can remove this.
$location.hash("IdWhereIWantToScroll");
$anchorScroll();
};
});
And here is your view:
<button ng-click="scrollToHash()">Scroll</button>
..
..
<div id="IdWhereIWantToScroll">
..
</div>
Hope this helps. Good luck.

Try to show/hide the elements using nh-show or ng-hide and then put a watch on the property used to show/hide the element. About scrolling, you already have a solution for that.

Related

How do I get my changes to persist in Angular using 2-way Data Binding with an onDrag callback?

I am trying to update a span's text after a call back function in Angular.
Here is my HTML:
<div ng-controller="onDragController">
<div id="draggableArea">
<div id="rectangle1" data-drag="true" jqyoui-draggable="{onDrag: 'dragCallback'}" data-jqyoui-options="{containment: '#draggableArea'}"></div>
</div>
<div>
<span ng-model="rectangleOne">{{rectangleOne.leftOffset}}</span>
</div>
</div>
And my controller is:
var App = angular.module('drag-and-drop', ['ngDragDrop', 'ui.bootstrap']);
App.controller('onDragController', function($scope) {
$scope.rectangleOne = {};
$scope.rectangleOne.leftOffset = 'ASDF';
$scope.dragCallback = function (event, ui) {
$scope.rectangleOne = {leftOffset: '12345'};
};
});
If I toss an alert in my callback function then I am seeing that the leftOffSet is updated, but on my HTML page the {{rectangleOne.leftOffset}} is staying the same.
What am I missing here...?
Use $apply in your dragCallback as follows:
$scope.dragCallback = function(event, ui) {
$scope.$apply(function() {
$scope.rectangleOne = {
leftOffset: '12345'
};
});
};
This will update your leftOffset in the scope. Here is a Plunker.
It might be helpful to better understand how Angular does two-way data binding. This blog post on how apply works, and why one would be motivated to use it, is pretty good.
In summary, for your changes to $scope.rectangleOne:
You can call $scope.$digest() every time you make a simple change like this. You need to do this so Angular knows to check if your bound data got updated.
Alternatively, you can use $scope.$apply, make the changes to $scope.rectangleOne inside a callback to $apply. It's doing the same thing, $apply ends up calling $digest() indirectly.
In code:
$scope.$apply(function() {
$scope.rectangleOne.leftOffset = '12345';
});
Hope that helps solve your problem, and add a bit of understanding to what's happening behind the scenes!

Inject $element in angularjs Controller

first, I have read millions of post saying you should not update DOM elements from a Controller in Angular. I know.
When trying to use angular-timer directive (a countdown). I faced some problems, so finally, with the plugin developer help, we did this plunker, which is working and meet my requirements.
http://plnkr.co/edit/CWXnKMbygVDMc8xzshZa?p=preview
However, when moving this code to my app, I got next error when I add the $element to my controller:
`Error: Unknown provider: $elementProvider <- $element`
I have read many posts and I know it can be injected, but I don´t know why it´s not working in my app.
In the other hand, I like to do things right, so I don´t like to implement something that is a bad practice. So, if you have a better approach that works, please let me know.
Looks ugly parsing DOM with jQuery, and I don't understand why you don't use the timer directive within the ng-repeat.
Here's an approach that just adds and extra array to scope for eleapsedTimers which are then displayed using ng-repeat
$scope.elapsedTimers=[];
$scope.$on('timer-stopped', function (data) {
/* loop through bookings to find one that just stopped*/
var now = new Date();
angular.forEach($scope.bookingsList, function (item) {
if (!item.elapsed) {
if (item.booking_date <= now) {
item.elapsed = true;
$scope.$apply(function () {
$scope.elapsedTimers.push(item)
});
}
}
});
});
HTML
<div id="result">
<div ng-repeat="item in elapsedTimers">ID {{item.id}} elapsed</div>
</div>
DEMO
Note...this will add a new property elapsed to the booking object. If this is a problem can create workaround

How can I hide an element when the page is scrolled?

Ok, I'm a little stumped.
I'm trying to think the angular way coming from a jQuery background.
The problem:
I'd just like to hide a fixed element if the window is not scrolled. If someone scrolls down the page I would like to hide the element.
I've tried creating a custom directive but I couldnt get it to work as the scroll events were not firing. I'm thinking a simple controller like below, but it doesnt even run.
Controller:
.controller('MyCtrl2', function($scope,appLoading, $location, $anchorScroll, $window ) {
angular.element($window).bind("scroll", function(e) {
console.log('scroll')
console.log(e.pageYOffset)
$scope.visible = false;
})
})
VIEW
<a ng-click="gotoTop()" class="scrollTop" ng-show="{{visible}}">TOP</a>
LIVE PREVIEW
http://www.thewinetradition.com.au/new/#/portfolio
Any ideas would be greatly appreciated.
A basic directive would look like this. One key point is you'll need to call scope.$apply() since scroll will run outside of the normal digest cycle.
app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
return function(scope, element, attrs) {
angular.element($window).bind("scroll", function() {
scope.visible = false;
scope.$apply();
});
};
});
I found this jsfiddle which demonstrates it nicely http://jsfiddle.net/88TzF/

How to click a button and focus on another input in angularjs?

I don't know how to focus on an input when clicking on a button in angularjs.
I create a simple demo which can't work here: http://plnkr.co/edit/NS0jJE9ttakNm8nc6QkZ?p=preview
This is the main code:
app.controller('MainCtrl', function($scope, $element) {
$scope.name = 'World';
$scope.myfocus = function(){
$element.find("#myinput").???? // what to do here?
}
});
You need to load jquery before loading angular.
See this updated plunker with load order changed and some changes to how you were trying to focus the element http://plnkr.co/edit/PLi1BiI83GKdAvSGufCP
and this previously asked question Error: "Selectors not implemented"
And fastreload is right about not dealing with the DOM in the controller.
http://docs.angularjs.org/guide/directive

AngularJS modal window directive

I'm trying to make a directive angularJS directive for Twitter Bootstrap Modal.
var demoApp = angular.module('demoApp', []);
demoApp.controller('DialogDemoCtrl', function AutocompleteDemoCtrl($scope) {
$scope.Langs = [
{Id:"1", Name:"ActionScript"},
{Id:"2", Name:"AppleScript"},
{Id:"3", Name:"Asp"},
{Id:"4", Name:"BASIC"},
{Id:"5", Name:"C"},
{Id:"6", Name:"C++"}
];
$scope.confirm = function (id) {
console.log(id);
var item = $scope.Langs.filter(function (item) { return item.Id == id })[0];
var index = $scope.Langs.indexOf(item);
$scope.Langs.splice(index, 1);
};
});
demoApp.directive('modal', function ($compile, $timeout) {
var modalTemplate = angular.element("<div id='{{modalId}}' class='modal' style='display:none' tabindex='-1' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true'><div class='modal-header'><h3 id='myModalLabel'>{{modalHeaderText}}</h3></div><div class='modal-body'><p>{{modalBodyText}}</p></div><div class='modal-footer'><a class='{{cancelButtonClass}}' data-dismiss='modal' aria-hidden='true'>{{cancelButtonText}}</a><a ng-click='handler()' class='{{confirmButtonClas}}'>{{confirmButtonText}}</a></div></div>");
var linkTemplate = "<a href='#{{modalId}}' id= role='button' data-toggle='modal' class='btn small_link_button'>{{linkTitle}}</a>"
var linker = function (scope, element, attrs) {
scope.confirmButtonText = attrs.confirmButtonText;
scope.cancelButtonText = attrs.cancelButtonText;
scope.modalHeaderText = attrs.modalHeaderText;
scope.modalBodyText = attrs.modalBodyText;
scope.confirmButtonClass = attrs.confirmButtonClass;
scope.cancelButtonClass = attrs.cancelButtonClass;
scope.modalId = attrs.modalId;
scope.linkTitle = attrs.linkTitle;
$compile(element.contents())(scope);
var newTemplate = $compile(modalTemplate)(scope);
$(newTemplate).appendTo('body');
$("#" + scope.modalId).modal({
backdrop: false,
show: false
});
}
var controller = function ($scope) {
$scope.handler = function () {
$timeout(function () {
$("#"+ $scope.modalId).modal('hide');
$scope.confirm();
});
}
}
return {
restrict: "E",
rep1ace: true,
link: linker,
controller: controller,
template: linkTemplate
scope: {
confirm: '&'
}
};
});​
Here is JsFiddle example http://jsfiddle.net/okolobaxa/unyh4/15/
But handler() function runs as many times as directives on page. Why? What is the right way?
I've found that just using twitter bootstrap modals the way the twitter bootstrap docs say to is enough to get them working.
I am using a modal to house a user edit form on my admin page. The button I use to launch it has an ng-click attribute that passes the user ID to a function of that scope, which in turn passes that off to a service. The contents of the modal is tied to its own controller that listens for changes from the service and updates values to display on the form.
So.. the ng-click attribute is actually only passing data off, the modal is still triggered with the data-toggle and href tags. As for the content of the modal itself, that's a partial. So, I have multiple buttons on the page that all trigger the single instance of the modal that's in the markup, and depending on the button clicked, the values on the form in that modal are different.
I'll take a look at my code and see if I can pull any of it out to build a plnkr demo.
EDIT:
I've thrown together a quick plunker demo illustrating essentially what I'm using in my app: http://embed.plnkr.co/iqVl0Wb57rmKymza7AlI/preview
Bonus, it's got some tests to ensure two password fields match (or highlights them as errored), and disables the submit button if the passwords don't match, or for new users username and password fields are empty. Of course, save doesn't do anything, since it's just a demo.
Enjoy.
There is a working native implementation in AngularStrap for Bootstrap3 that leverages ngAnimate from AngularJS v1.2+
Demo : http://mgcrea.github.io/angular-strap/##modals
You may also want to checkout:
Source : https://github.com/mgcrea/angular-strap/blob/master/src/modal/modal.js
Plunkr : http://plnkr.co/edit/vFslNmBAoKPVXtdmBXgv?p=preview
Well, unless you want to reinvent this, otherwise I think there is already a solution.
Check out this from AngularUI. It runs without twitter bootstrap.
I know it might be late but i started trying to figure out why the handler got called several times as an exercise and I couldn't stop until done :P
The reason was simply that each div you created for each modal had no unique id, once I fixed that everything started working. Don't ask me as to what the exact reason for this is though, probably has something to do with the $('#' + scope.modalId).modal() call.
Just though I should post my finding if someone else is trying to figure this out :)

Resources