How to set focus on last element in ng-repeat? - angularjs

I display a list of items through ng-repeat
<div ng-repeat="{item in items}" >
<h3>{{item.name}}</h3>
<h3>{{item.price}}</h3>
<h3>{{item.date}}</h3>
</div>
I have an add where i click and add new items..I display through ng-repeat in a div and that contains scroll..Whenever i add a new item the scroll bar stand still and i can see the newly added item by scrolling down only.
I used ng-focus="{$last}" to set focus on last item but it didnt work.
I need to set focus on last element in ng-repeat even i have 50 elements in div.
Plss help me in this..

I'd recommed using a directive to achieve this behaviour.
module.directive('setFocus', function(){
return{
scope: {setFocus: '='},
link: function(scope, element){
if(scope.setFocus) element[0].focus();
}
};
});
And on your HTML:
<div ng-repeat="{item in items}" set-focus="$last">
<h3>{{item.name}}</h3>
<h3>{{item.price}}</h3>
<h3>{{item.date}}</h3>
</div>
When you load the page, .focus() is ran on the last element.
If you add an element, .focus() is ran on that new last element.
Now your problem lies on which elements are focusable across different browsers. I suggest you check which HTMLElement can receive focus.
So, you may want to add a hidden focusable element inside your div, and modify the directive to focus on that, or maybe add a tabindex attribute to your ng-repeat div. (tabindex="some number other than -1")
<div ng-repeat="{item in items}" set-focus="$last" tabindex="0">
<h3>{{item.name}}</h3>
<h3>{{item.price}}</h3>
<h3>{{item.date}}</h3>
</div>
I hope this helps!
To clarify: ng-focus is used to specify behaviour ON focus, not to trigger focus on the element.

You can use $anchorScroll in AngularJS.
Just place a link (< a> < /a>) at the bottom of your div with the id="bottom" and ng-hide="true", so you dont actually see the link.
<div id="scrollArea" ng-repeat="item in items">
<h3>{{item.name}}</h3>
<h3>{{item.price}}</h3>
<h3>{{item.date}}</h3>
<a id="bottom"></a>
</div>
<button type="button" ng-click="addNewItem" value="Add"/>
When you click on your "add" button or whatever, call a function in the Controller that leads you to the bottom link with the id="bottom".
$scope.addNewItem = function() {
//Add new item here...
//After adding item, go to bottom:
$location.hash('bottom');
$anchorScroll();
};
You can read more about this on the Documentaion of AngularJS:
Documentaion of $anchorScroll.

Related

Angular 1.5 Binding ng-repeat created controls?

Angular 1.5
In an ng-repeat I create a button that will display a Bootstrap popup with anchor links.
How do I bind the onAction call so that it calls my $scope.onAction() function ? (onAction() is not bound to $scope.onAction().)
<div ng-repeat="item in model.Holdings track by $index" bs-popover>
<button class="popoverBtn"
data-content="<a ng-click='onAction(1)'>Buy</a>...and more"
click me to show popup
</button>
</div>
Here's my directive that turns the Bootstrap popover on:
app.directive('bsPopover', function () {
return function (scope, element, attrs) {
element.find(".popoverBtn").popover({ placement: 'auto', html: 'true' });
????COMPILE GOES HERE???////
};
});
It sounds like you want the onAction method to take an item identifier.
Perhaps something like <a ng-click='onAction(item.id)'>Buy</a> ??
From what I recall, you are in the scope of the controller that stores the data. If you have nested ng-repeats, look into $parent.
If you are looking to pass the index value of an item into your function on a click event, you need only pass it $index instead of an explicit value. For example:
<div ng-repeat="item in model.Holdings track by $index">
<button class="btn btn-primary"
data-content="<a ng-click='onAction($index)'>Buy</a>...and more">
click me to show popup
</button>
</div>
UI-Bootstrap project seems to have simple to use controls for Angular + Bootstrap.
https://angular-ui.github.io/bootstrap/
This worked

Angular- Getting closest element on mouseover

I'm new to Angular JS and i'm trying to create a small web app for learning.. I am trying to make a Tooltip text on mouseover but i'm not sure how to get it done the "Angular way"..
I created 2 spans, when hovering the first, i want to show the second
I tried using ng-mouseover and ng-mouseleave to call the actions-
<span class="info" ng-mouseover="info_in();" ng-mouseleave="info_out();">
<img src="images/info.png" />
</span>
<span class="info_bubble" ng-show="info">The Tooltip Text</span>
And that's where i got with the JS-
$scope.info_in = function() {
this.parent().find('.info_bubble') = true;
};
$scope.info_out = function() {
this.parent().find('.info_bubble') = false;
};
There are going to be more than 1 Tooltip text on each page and i'm not sure how to get it done.. I tried with "next()" and "closest()" but couldn't get it to work
When i try to mouseover the element, i get "this is not a function"
You've got the right idea but your implementation is moving toward the jQuery way, not the Angular way. :)
Try this:
<span class="info" ng-mouseover="info=true" ng-mouseleave="info=false">
<img src="images/info.png" />
</span>
<span class="info_bubble" ng-show="info">The Tooltip Text</span>
No controller code is necessary for this to work.
What you're doing is that when the mouse enters the image, Angular will set $scope.info to true. And since your tooltip is watching that scope variable, it will trigger the ng-show directive to fire which will show your tooltip.
The ng-show directive can be translated as: When $scope.info == true, then show() this element. When $scope.info == false, then hide() this element.
In fact, you could be more verbose (which is good for learning) writing your tooltip element like this:
<span class="info_bubble" ng-show="info==true">The Tooltip Text</span>
I notice that you're using the jQuery method of specifically trying to find an element in the DOM in order to work with it.
The Angular way is to change variables on the $scope. Other HTML elements will monitor variables on the $scope and will automatically change themselves depending on what the new value is. The jQuery way is to reach out and specifically touch and set a value on a DOM element. The Angular way is akin to shouting to the wind, "Hey, my name is $scope.info and I'm now true!" and expecting that some other element will hear it and go, "Ok cool, now I can show myself because $scope.info is true."
That's the main difference between the way jQuery and Angular work.

ui-sref in parent div overriding all nested links

We have a series of notifications and want to make the overall item clickable to the related item. This has been implemented using ui-sref and functions correctly. However, within that, there are to be a series of nested links that go to other relevant information. The problem at the moment is this parent ui-sref overrides all of these links. I've tried implementing these nested links as standard anchor and ui-sref but it has the same effect. So the hyperlink shows correctly, and when clicking on it, it goes to it for a split second, then reverts back to the ui-sref link.
Here is a code example:
<div class="NotificationItemBalanced">
<div class="notificationItem" ui-sref="community.act({slug: slug, id: id})">
<div class="messageBodyWrapper">
<span class="messageText"><strong><a ui-sref="user.posts({username: username})"></a></strong> commented on your post</span>
</div>
</div>
</div>
Is this related to the ui-sref or is there a specific setting in the routes to fix this?
Thanks
Just create a directive like:
myApp.directive('preventBubbling', function() {
return {
link: function($scope, element) {
element.on("click", function(e) {
e.stopPropagation();
});
}
};
});
And add it to your inner links:
<a ui-sref="user.posts({username: username})" prevent-bubbling></a>
Basically, when you click on a nested element, the click event bubbles up to the DOM tree. So we are simply stopping it to propagate.
https://developer.mozilla.org/en/docs/Web/API/Event/stopPropagation
Update
Also, if your inner links are inheriting properties from parent ui-sref then you should use ui-sref-opts as well:
<a ui-sref="user.posts({username: username})" ui-sref-opts="{inherit: false}" prevent-bubbling></a>

onclick on hyperlink should add a div horizontally using angularjs

My html:
<div id="contentDiv">
<div id="headerDiv" ><div id="titleDiv"> Queries</div></div>
<div id="valuesDiv" ><div id="yearDiv"> 2015</div></div>
<div id="graphDiv" ><div id="chartDiv">graph</div></div>
</div>
Like this div, I have another div but the content in the div is different.
How to add a new div horizontally when I click on hyperlink using angularjs?
How can I do this? please help me out regarding this
Looks like what you need is a two way binding with the ng-model directive. So the idea would be that you bind the new div to a variable in your scope which is initially in an empty or undefined state (for example, there are better ways). When the hyperlink is clicked it calls the function specified by an ng-click directive which will fill your bound object, which in turn will cause the new div to be rendered.
EDIT:
Based on your comments here is a simple example.
HTML page:
<div id="newDiv" ng-repeat="item in items">
<!-- Div content -->
<!-- example -->
<input type="text" ng-model="item.name">
</div>
<input type="button" ng-click="addItem()">
Controller:
$scope.items=[];
$scope.addItem = function() {
var newItem = {};
newItem.name = "new item name";
$scope.items.push(newItem);
}
What's happening here is the data for each div is stored in an array of objects. The ng-repeat directive will repeat the div for each object in the array. You can then fill the elements in the div using the object. Adding a new div is as simple as adding a new item to the array and angular will take care of the rest for you. Please note that I have not tested this example, but hopefully it's enough to point you in the right direction.
RE aligning the divs horizontally, this will be done with CSS, using the inline-block display mode. So you could give the div a class of, for example, "horizontalDiv" and add the following class to your CSS file:
.horizontalDiv {
display: inline-block;
}

Hide/show an element in Angularjs using custom directive, ng-show and $scope

When a link is clicked in the app navigation a dropdown with ui-view content shows below each respective link.
The HTML:
<div class="sc-dash-header">
<ul>
<li>
<a class="navbar-brand" show-nav-popup href="">download</a>
<div id="nav-download-progress" class="dash-hdr-popup" ng-show="showPopup">
<div ui-view="hdr-download-progress"></div>
</div>
</li>
<li>
<a class="navbar-brand" show-nav-popup href="">add</a>
<div id="nav-add" class="dash-hdr-popup" ng-show="showPopup">
<div ui-view="hdr-add-content"></div>
</div>
</li>
<li>
<a class="navbar-brand" show-nav-popup href="">enter pin</a>
<div id="nav-unlock" class="dash-hdr-popup" ng-show="showPopup">
<div ui-view="hdr-unlock"></div>
</div>
</li>
</ul>
</div>
I've included an ng-show attribute to open the dropdown when $scope.showPopup is set to true.
To achieve this I've created a custom directive with an on click called show-nav-popup.
The JS:
.directive('showNavPopup', function () {
return {
restrict: 'A',
// scope: {},
link: function(scope, el, attrs) {
el.on('click', function(){
scope.$apply(function () {
scope.showPopup = true;
});
console.log(scope);
});
}
};
});
The above works, but the dropdown opens on each element.
Question: I need to isolate the scope, so on each click, only the respective dropdown appears. I uncomment the line // scope: {} - but this doesn't work..
Angularjs n00b here - any help would be much appreciated
Having an isolate scope in this situation wouldn't fix the problem. There are a ton of ways to achieve what you want though. One of which is to assign each show-popup-nav an id, turn $scope.showPopup into an array, and keep an individual true/false for each id. Then for each ng-show, you look at the index corresponding to each id for the true/false value.
I coded it up on that guy's Plunker, working as you expect: http://plnkr.co/edit/CSikLIiuPNT9dfsfZfLk
EDIT: I should say, you COULD use an isolate scope to fix this, but that would require a lot of changes to your DOM, as the ng-show directive is a sibling to your show-popup-nav, and not a child.
When you create the isolate scope, the scope applies to the element that your directive is applied to, and it's child elements. In this case that's just the anchor tag:
<a class="navbar-brand" show-nav-popup href="">download</a>
You are using an ng-show on a tag that is a sibling to the anchor tag:
<div id="nav-download-progress" class="dash-hdr-popup" ng-show="showPopup">
The sibling is not part of the isolate scope, and so it never notices that the value of showPopup has changed.
The ng-show would work if it were applied to a DOM element that was a child of the anchor tag.
EDIT
One way to make this work would be to wrap your two siblings in a parent tag, and use the directive on the parent:
<div show-nav-popup>
Download
<div ng-show="showPopup"></div>
</div>
Then you'd need to modify your directive's code to find the anchor tag and apply the click handler.
You might instead try a completely different approach as suggest in the other answer by #Bill Bergquist

Resources