How to click a button and focus on another input in angularjs? - 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

Related

angular - scroll to element on div element display visiable

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.

How does AngularJS encode the ngClick calls to a controller?

Here's a brief example here: http://plnkr.co/edit/x1sSw8?p=preview.
This is the HTML file:
<body ng-controller="MainCtrl as main">
<p>Hello {{main.name}}!
My current value for <code>main.value</code> is {{main.value}}.</p>
<button ng-click="main.doSomething()">Click Me</button>
</body>
Here is the app.js file:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function() {
this.name = 'World';
this.value = 0;
this.doSomething = function(){
this.value += 5;
}
this.doSomethingElse = function(){
this.value -= 5;
}
});
When I click the button, I normally expect the counter to go up in increments of 5. When I inspect the button and change the ng-click function to doSomethingElse(), why does it still continue to increment?
I understand I'm not directly changing the event listeners, so I wonder how AngularJS is protecting the controllers from outside tampering (like in the example I described). My guess is that it builds event listeners up after it parses the DOM for the first time (reading ng-click attributes and all).
When I inspect the button and change the ng-click function to doSomethingElse(), why does it still continue to increment?
You should check out the compilation & linking processes in Angular. The short reason is that, angular goes over these elements once they are created, not every time you click it. Since it is scanned and parsed by angular when the element is created, manually changing it by hand does not change anything, because angular does not check out what's written in there.
More info: https://docs.angularjs.org/guide/compiler

AngularJS: Create new controller and scope for dynamic content

Have a template that I'd like to load using ng-include and assign a controller instance to. This new template/scope/controller needs to be loaded in response to a user interaction (hover or click).
The content of the template has to be set using element.innerHTML because the content is set by a 3rd party.
The user can then click out of the new div and I would like to destroy the controller/scope that was created.
Pseudocode for what I want to achieve:
popup.setContent("<div ng-controller='PopupController'><div ng-include=\"views/LayerPopup.html\"></div></div>");
How do I tell angular to process the ng-include and ng-controller just as though the page was being loaded for the first time?
Thanks!
Edit:
Add plunker to illustrate question
http://plnkr.co/edit/DPuURCoq2hJ0LCLIN2dc?p=preview
http://jsfiddle.net/ADukg/5420/
Not using ngInclude, but it does fill these criteria:
You pass in a templateURL.
Pass in the name of the controller you would like to use.
Pass in the third party content (which in turn gets set with $element.innerHTML).
Setup a click listener someplace outside the $scope of the popup, which triggers a kill command on the popup.
This is how I imagine you would instantiate it:
<directive tpl="tpl.html"
ctrl="DirectiveController"
third-party-content="{{thirdPartyContent}}">
</directive>
Not sure this will suit you, but I had a fun time putting it together and maybe it'll prove useful to someone else.
In any case, I have to agree with the comments you've recieved so far. It's a bit cryptic as to what you have to work with right now and what possible options are available to you.
Here is a plunker of what you are trying to do. If you click on a button, a popup will show a template, and you can click on the template and it will stay up, but if you click out of it, it will get removed.
HTML
<body ng-controller="MainCtrl" ng-click="closePopup()">
<button ng-click="openPopup($event)" id="clicktarget">Click</button>
<p>Hello {{name}}!</p>
<div ng-include="getPopup()" ng-click="$event.stopPropagation()">
</div>
<script type="text/ng-template" id="theTemplate.html">
<div ng-controller="PopupController">
<div ng-include="'LayerPopup.html'"></div>
</div>
</script>
</body>
JS
angular.module('plunker', [])
.controller('MainCtrl', function($scope, $templateCache) {
$scope.name = 'World';
$scope.popupTmpl = null;
$scope.openPopup = function($event){
$scope.popupTmpl = 'theTemplate.html';
$event.stopPropagation();
};
$scope.getPopup = function(){
return $scope.popupTmpl;
};
$scope.closePopup = function(){
$scope.popupTmpl = null;
};
})
.controller('PopupController', ['$scope', function($scope) {
$scope.aVariableMaybe = 'lulz something';
}]);
On a side note, try to get rid of that JQuery stuff when you are using Angular. Angular can do everything on its own

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/

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