Retain scroll position while model is updated in angular js - angularjs

i have a list of teams and user can add a team to list of teams. the problem i having is that when i add an item to an list, angular re-renders the list and scroll position is reset to the top.
this is the template
<div ng-controller="scores">
<ul>
<li ng-repeat="team in teams">
{{team.name}}:
<button ng-click="decr(team)">-</button>
{{team.score}}
<button ng-click="incr(team)">+</button>
</li>
</ul>
(+)Add Team
</div>
here is the controller code
function scores($scope){
$scope.teams = [
{name:'red', score:100},
{name:'blue', score:100},
{name:'green', score:100}
];
$scope.decr= function(team){team.score-=1;};
$scope.incr= function(team){team.score+=1;};
$scope.add= function(){$scope.teams.push({name:"...", score:100});};
}
you can see working example here. http://jsbin.com/asedib/5

The problem is that you have href="#", which resets the anchor / scroll position to the top of the page every time you click the link.
I see two easy solutions:
The easiest is to change the anchor to a button. This still makes it clear that this is a clickable element, but without the anchor element:
<button ng-click="add()">(+) Add Team</button>
If you prefer the anchor-style appearance, you can remove the href="#", but then update your CSS to style the non-anchor link to look like a link. Something like this:
<a ng-click="add()" class="clickable">(+) Add Team</a>
And the CSS:
a, a.clickable {
color: blue;
text-decoration: underline;
cursor: pointer;
}
Both of these solutions solve the immediate problem without any extra JavaScript.

Related

Get active slide index outside angular-ui bootstrap carousel

I have a problem getting the active slide in an Angular-UI Bootstrap carousel outside the carousel.
I have a panel, with the carousel inside, and want to put buttons in the footer of the panel that makes actions using the selected slide, but using jquery selectors is not an option.
I want to implement it using something in pure angular.
I think I can use the active attribute, but maybe there is something clever that can do the trick more smoothly.
Some code (Jade syntax):
.panel.panel-info
.panel-body
carousel.imgCarousel(interval='5000')
slide(ng-repeat='media in selCard.superviseTab.media')
img.img-responsive(preload-image ng-src='/api/cards/{{selCard.superviseTab.sID}}/media/{{$index}}')
.carousel-caption
multiSelect
h4 Slide {{$index+1}} of {{selCard.superviseTab.media.length}}
p {{media.originalFilename}}
.panel-footer
.navbar-collapse.collapse
ul.nav.navbar-nav.navbar-left
li
a.btn.btn-danger
i.fa.fa-unlink
If you look at the AngularUI documentation, you can see this is how the slides are integrated into the HTML:
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
...
</slide>
</carousel>
We can see that the active slide is determined by the active property on each slide.
So, you should be able to iterate through the slides and return the first slide with the active property on it. As long as you haven't modified the slides array outside of this carousel, it should give you the index of the current slide.
For example, something like:
function isActive(slide) {
return slide.active;
};
$scope.getActiveSlide = function() {
var activeSlides = $scope.slides.filter(isActive)[0];
//return the first element, since the array should only return one item
};
Should do the job (or however you choose to implement your find functionality).

ui bootstrap tooltip cutoff in iframe

I have an app running in an iframe and it makes use of angular ui boostrap tooltips. Unfortunately if the element with the tooltip is on the edge of the iframe, the tooltip will be cutoff by the iframe. Is there any solution to this? Should I play with its position within the iframe, or the z-index value?
UPDATE
So I'm trying to override the tooltip positions (note that I an using angularjs ui bootstrap). I have 2 tooltips which each require their own positioning. I managed to change the css styles (colours and fonts) globally, but I'm having trouble targeting each one to give them unique positions. I have the following html and css:
<div id="my-div">
<ul>
<li tooltip="Foo">A</li>
<li tooltip="Bar">B</li>
</ul>
</div>
Tooltip "Foo" needs a different position that "Bar". So I'm trying to access the li tags using the following css, but it doesn't work.
#my-div > ul > li:nth-child(1).tooltip.top {
margin-left: 10px;
}
#my-div > ul > li:nth-child(2).tooltip.top {
margin-left: 30px;
}
Note that .tooltip.top is the bootstrap class added via the angularjs tooltip directive. I'm guessing this doesn't work because the directive is actually adding another element somewhere.
So it turns out angular will insert a div element right after the element defined as the tooltip. So in my case, when the tooltip event for A is triggered, angular inserts the new element like so:
<div id="my-div">
<ul>
<li tooltip="Foo">A</li>
<div><!-- tooltip for foo --></div>
<li tooltip="Bar">B</li>
</ul>
</div>
Therefore the solution I came up with was to add id's to each of my li tags:
<li id="foo-tip" tooltip="Foo">A</li>
<li id="bar-tip" tooltip="Bar">B</li>
and then access the css tooltip element like so:
#foo-tip + div {
margin-left: 25px;
}
#bar-tip + div {
margin-left: 15px;
}

Angular js - slide in div on click of element

I am completely new to Angular js and I want to perform an operation i.e. clicking on a button would slide in a div from the right and clicking back again would send it back to right. Basically toggle it.
I know how to do with jquery as below, but the need is to do it in angular.
HTML:
<body>
<div>
Click me
</div>
<div id="content">
<div id="list">
</div>
</div>
</body>
CSS:
#clickhere {display:block; width:50px; height:50px; background:#999;}
#list{width:200px; height:100%; position:absolute;top:0;right:-200px;background:#323232;}
.slidein{right:0;}
JS:
$("#clickhere").click( function(){
if($("#list").css("right")== "0px")
{
$("#list").animate({right:"-200px"}) }
else{
$("#list").animate({right:"0"})
}
})
jsfiddle - http://jsfiddle.net/RJJwu/3/
Can anyone please help me with the angular code. I looked over a couple of examples such as :
1) Different transitions with AngularJS
2) http://mgcrea.github.io/angular-motion/ - in section Slide, 2nd button
The above links represent my actual need. I tried doing it via 1st link, but its not working.
Hint : add or remove a class (ngClass or ngHide) when the user click on the button (ngClick) and do the animation in CSS (transition).

Hide a div after user selects one option

i did not found the answer i was looking for, so that why i'm creating this question. I have a div that shows another one on click but i need to hide it (the div that appears on click) after the user selects one of the options, how can i do that?
When user's click on "#showmenu" the div ".mob" appears, after clicking in one of the ".mob" li's the ".mob" div dissapears.
P.S: Sorry for my bad english.
HTML:
<div id="showmenu"><img src="images/mobile.png" /></div>
<div class="mob" style="display: none;">
<ul>
<a data-scroll href="#home"><li>INÍCIO</li></a>
<a data-scroll href="#servicos"><li>EU FAÇO</li></a>
</ul>
</div>
Code:
$(document).ready(function() {
$('#showmenu').click(function() {
$('.mob').slideToggle("fast");
});
});
I dont have any idea of the bootstrap or jquery plugins you are using but based on what is given, i'd say this should work.
$(document).ready(function() {
$('#showmenu').click(function() {
$('.mob').slideToggle("fast");
$('.mob a').click(function () {
$('.mob').slideToggle("fast");
});
});
});
Point to note there is a performance issue here , i.e code could be optimized better to search for classes or elements within a specific div than the whole document
Should those really be <a> if you don't intend to go anywhere? Can they just be <li>?
After that I think you want to give id's to the <li> that you have and then create a function much like the one you did for $('showmenu').click... that would hide the .mob.
Or if the <li> all get treated the same, maybe give them all the same class and just have one function for the class.

ng-grid hiding bootstrap styled dropdowns

I am upgrading a table form. Each row in the table has several elements, including two drop downs in specific columns for each row. I have upgraded the table to ng-grid and upgraded the drop-downs from plain select widgets to styled bootstrap drop-down elements to match the others on the site. The essential problem I am having is that the CSS layout of ng-grid causes the actual drop down menu to be put behind the cell below, and so not visible. Examining the elements shows that they are actually being rendered, have proper height, width and content, but are merely displayed behind the content in the other cell. I have tried disabling the CSS overflow: hidden on the desired cells, but it seems this property is also set for the entire grid and turning it off at that level totally breaks the grid layout. I have a working workaround, but it makes me want to take a shower and I am sure there is a more elegant way to do this:
1) put a cell template in for just the visible part, including an ng-click call passing the column (Coffeescript):
{field: "type",
displayName: "Type",
width: 155,
original_width: 155,
pinned: false,
cellClass: "type_col",
headerClass: "type_col",
cellTemplate: """<div ng-click="editor.activeCol(col)" class="btn-group">
<button ng-show="row.entity[col.field]" style="width: 125px"
class="btn dropdown-toggle blk-txt" href="#">
{{row.entity[col.field]}}</button><button class="btn">
<span class="caret"></span></button></div>"""
},
2) Put a select row callback to a different method:
multiSelect: false,
enableRowSelection: true,
afterSelectionChange: angular.bind(#, selectFunc),
3) Have a totally separate angular template of the drop-down options that is classed to always be shown open for bootstrap, but has both a ng-show and ng-style elements to allow my code to change its visibility and exact location:
<div ng-show="editor.utilization" ng-style="editor.dropdown_style">
<div class="btn-group editor-widget open">
<ul class="dropdown-menu">
<li ng-click="editor.selectUtil('heavy')">Heavy</li>
<li ng-click="editor.selectUtil('medium')">Medium</li>
<li ng-click="editor.selectUtil('light')">Light</li>
</ul>
</div>
</div>
When a user clicks on the (apparent) drop down, the following happens:
1) ng-click event delivers the column to the class, this is stored
2) row select (afterSelectionChange) callback triggers with the row and is able to get the column from the previous call, with both the row and column we now know the actual cell
3) The exact screen position of the cell in question is grabbed and the drop-down selections template is made visible directly below the clicked cell, making the illusion of a normal drop-down operation.
This is a long explanation, but wanted to give the background of what I have tried, to show that I am looking for a simpler (hopefully MUCH simpler) way to just include styled bootstrap drop-down widgets in ng-grid cells. The entire thrust of this project is to style and beautify already working forms so solutions that work only by cutting style for pure functionality don't really serve the purpose.
This is how I solved it. I have a cell in the ng-grid and in the cell i have a glyphicon arrow down. When I click it I want the dropdown toggle to show. With the CSS I got what I wanted. However, I have many cells with arrows and thus I had to change the css-style "left" dynamically. I do this with my javascript.
Hope it helps!
Cell Template:
<div class="ngCellText" ng-class="col.colIndex()" class="dropdown">
<span ng-cell-text>{{row.getProperty(col.field)}}</span>
<a class="dropdown-toggle" ng-click="setXchords($event)">
<i class="glyphicon glyphicon-chevron-down"></i>
</a>
<ul class="dropdown-menu">
<li ng-repeat="choice in editableItems">
<a>{{choice}}</a>
</li>
</ul>
</div>
CSS:
.dropdown-menu {
position: fixed;
top: inherit;
left: 85px;
}
JavaScript:
$scope.setXchords = function(e) {
var elem = angular.element(e.currentTarget);
$(elem).next().css('left', e.clientX).css('top', e.clientY);
};
In order to show regular dropdowns, I added this css:
.ngCell { overflow: visible; }
In order to get multiselects to appear, I needed to add a class (I used "field-multiselect") to an editableCellTemplate and then add the following css to the class:
.field-multiselect {
position: relative;
overflow: visible;
z-index: 888; }
This worked for me! (Finally, after quite a bit of trial and error!)

Resources