AngularJS (ng-grid) order by original index - angularjs

When the grid is initially rendered, it follows the ordering of the list (model) behind it. How would one revert to that same natural ordering after a sort by column has occurred?

Within an ng-repeater you could set a custom data attribute to {{$index}}
<li class="sortable" ng-repeat="item in items" data-index="{{$index}}">
Then when the DOM is manipulated to produce your column sort the index when rendered will be preserved within data-index

Related

Add class to every last element on the row AngularJS

I am trying to add a class to the every last element in that row. Here I have a ng-repeat and showing it in three columns in a row so every 3rd(last) column should have a class. Though I am in the beginning stage of Angular I couldn't figure it out.
Thanks for your kind answers.
You could try to use $last (a exposed property of ng-repeat) and ng-class
<div class="container" ng-repeat="item in items">
<div ng-class="{'yourClass':$last}"> your content...</div>
</div>
I would have tried to provide a better example, but its hard to guess the structure of what you are working on based on your input.

How to preserve DOM elements when using ng-repeat with filter?

I have an ng-repeat with a filter. When some items are filtered out by the filter and then they are restored after another filter change there are new DOM elements created for these items. If there was any DOM manipulation on the item it gets lost after item is hidden and restored with filter.
Is there a way to keep the DOM elements, even when item is removed by filter?
I tried using track by, but it doesn't help.
Here is a fiddle that recreates the problem.
Steps to recreate:
Click the button to apply colors to DOM elements
Type something in the filter input (for example 'ap') to hide some of the elements
Remove the filter. The restored elements lost their style.
Angualr is dynamically adding and removing those templates. By template I mean whatever tag(s) are inside your ng-repeat. There is no way to preserve that in an ng-repeat. Instead, if you want this color change to be preserved, it needs to be a part of the model you are ng-repeat ing over. Does that make sense?
Add the color directly to the template style="color: {{fruit.color}}"
See this for what I am talking about
http://jsfiddle.net/nferjvsp/1/

Animate element moving between lists

Using AngularJS, I would like to animate an element being added to one list from another, as in a clone of the element should appear to move in the page from the menu of items, and be added to the target list.
<ul class="list">
<li ng-click="choose(item)" ng-repeat="item in originItems">{{item.name}}</li>
</ul>
<ul class="list">
<li ng-repeat="item in targetItems track by $index">{{item.name}}</li>
</ul>
Where the function that adds the items does a simple push
$scope.choose = function(item) {
$scope.targetItems.push(item);
}
You can see this in action (with no animation) at this Plunker
I've considered custom directives and events, but not really got anywhere. What's a good structure of directives and/or events to allow this movement animation be achieved, keeping this a separate from the business of adding to a list as possible?
Note: my exact situation in terms of business logic and animation is a bit different, but I'm hoping the solution to this is flexible enough to allow some changes/additions to what happens in the menu, during the "move" animation, and what happens in the target list.
Demo http://plnkr.co/edit/XYnf7U?p=preview
I removed list style to ensure proper position of list item while moving. If you have to enable list style, you have to consider that.
The demo works by: when user add an item, it get the position of original and final items, and apply a jquery animation to the cloned list item between those two positions.
Use $event.target to identify original item.

In AngularJS, what is the correct way to filter an array based on odd or even $index property?

I want to filter an array based on even and odd $index property and I want to add odd elements in a separate div and even elements in another div, I could easily do this in JavaScript or jQuery, but I wanted to know the correct way to implement the same in AngularJS.
This is what I've done so far:
<div ng-app>
<div ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
<div class="row" ng-repeat="name in names">
<div class="col-xs-6" ng-show="(($index + 1)%2) == 0">{{name}}</div>
<div class="col-xs-6" >{{name}}</div>
</div>
</div>
</div>
It shows empty spaces in place of odd elements in first case, and when I add the odd expression for second div, the elements in the second div disappear and appear in first div. Here is the fiddle for the same issue.
Please advise.
EDIT:
I have got what I wanted, I split the main array into two different arrays odd and even array; this fiddle may be useful for people who stumble upon the same issue in the future.
Since Angular 1.2.0-rc1, ngRepeat exposes the $odd and $even properties on the local scope. You can simply use an ngSwitch based on one of this properties:
<div ng-repeat="item in itemsList" ng-switch="$even">
<div ng-switch-when="true">{{item}} is even</div>
<div ng-switch-default>{{item}} is odd</div>
</div>
Notice that if you just want to change the class based on the parity, ngClassOdd and ngClassEven are available since 1.0.0:
<div ng-repeat="item in itemsList" ng-class-even="'even'" ng-class-odd="'odd'">
{{item}}
</div>
All-in-one Fiddle
I think you're going to have some trouble with what you're looking to do, due to the way ng-repeat works. It generates a new scope for each iteration of the repeat. So you'll end up with two divs each time through the loop, one visible and one hidden.
To explain the weird behavior you've been seeing:
In your first case, the loop is alternating between showing two divs and showing one div. In a row that displays only one div, it understandably looks like a blank was inserted in the second column.
In the second case, the ng-repeat loop alternates between showing the first div and the second one. Without some CSS styling to show the difference, it looks like one div. You can make it pop by adding a style such as text-info to one of the divs.
I hope that explains what's going on behind the scenes, but the better question is... what are you trying to accomplish with the two divs?
Update: Since it looks like your goal is to take that array and pump it out into a 2-column layout, you can probably do away with your row div and your 2 column divs. Instead, try repeating a single 6-width column div. It'll handle the row wrapping for you every other column. You can use odd and even styling as #Blackhole pointed out if you want to differentiate the divs. I've got an example fiddle set up here that may be of use.

Applying ng-class conditionally by model method

I have a list of DIVs that are generated by ng-repeat.
I need to apply an ng-class to those that're selected. To find out if the div is selected, I call to a model function ( not ng-model, just standard conceptual model ).
<div class="default" ng-class="{selected : myModel.isSelected({{item.id}})}" ng-repeat="item in items">
<!--Div content-->
</div>
This doesn't work, and none of the divs get the selected class.
However, when I call the model function from the inspector (myModel.isSelected(id)) for a specific id constant, I get "true".
Any ideas?
Thanks!

Resources