Cleanup All populated elements in ng-repeat (Angularjs) - angularjs

Using Angularjs, Created a search with ng-repeat (2 levels) and populate divs with results, How do remove the search result when a new search is requested
<table>
<div ng-repeat="one in all" >
<div id="resultTableParent" ng-repeat="two in one">
<div id="results">{{two.details}}</div>
</div>
</div>
</table>

you can pass an empty array to all: $scope.all= [] or put the new results instead: $scope.all = newResult

You just must put the new results on the variable of your controller("all" in your case), using the two way databinding angular feature. If you want only clear the results, so clean the "all" variable.

Your ng-repeat uses the array $scope.one, so any modifications to it will be updated in the ng-repeat. If what you're trying to achieve is replacing it just populate it again with the new results. If you want it to appear empty you can empty the array using
$scope.one = [];

Since this is a two level ng-repeat, I added:
$scope.all.items = []
The 'items' were what was holding the result in to "one" (in first ng-repeat)
Thank you all for responding and opening the doors.

Related

Hiding ng-repeat expression & filter logic in html?

I have a simple ng-repeat with a filter on it below. However in my html I see my logic in the html. Is there a way to hide this?
<div ng-repeat="row in rowData.players| filter:{name:"Dan"})">
{{row.name}}
</div>
When I look at my page though all my repeated divs have the above logic expression in them. Is there a directive or best practice to hide this?
<div ng-repeat="row in rowData.players| filter:{name:'Dan'})">
{{row.name}}
</div>
Try using single quotes instead of double quotes.
You have an extra ")" at the end of your:
"row in rowData.players| filter:{name:'Dan'})"
not sure if it has to be there or not, check it out, also #Divyesh is right, try to use simple ticks '' instead of "" when already enclosed by doble ticks
Rather than filtering in your html template, you can create a scoped variable that holds these filtered values, and then iterate over them. That way users who inspect your DOM will not see the filtered values.
For example, in your controller, you could have:
.controller('SomeCtrl', function($scope, $filter) {
$scope.rowData.players = $filter('someFilter')(filterArgs1, filterArgs2, etc);
})

angularjs - track by in a for loop

I have a problem with the refresh button in my Angular application:
I have a json object with two arrays in it -> data = {array1: [], array2: []}
I want to loop both arrays and print the related values. To achieve that, I use the Angular ng-repeat directive like this:
ng-repeat="index in [] | index:getTotalNumberOfObjectsInArray1()"
...
<span ng-bind="data.array1[index]"></span>
<span ng-bind="data.array2[index]"></span>`
My Problem is, that on every click on the refresh-button these data will be recreated on the dom.
I learned the documentation about "track by" but i understand it only on objects (for example: ng-repeat="a in objects track by a.id")
How can I use this track by filter for my ng-repeat above, to prevent the recreation of my data?
You can use $index that is defined in a ng-repeat (cf.doc) but you have to have the two array with the same length.
Another solution could be to merge your arrays together and loop on it but I am not sure if it answer to your question.

How to set a boolean flag to collapse/expand a row with ng-repeat

I have this plunker code.
What I'm trying to do, is to display the gray box one time per row.
To achieve this, I thought to modify the partition filter in order to return a JSON to add it a new property by row to know if the gray box is expanded or not.
But, I could Not successfully return a JSON.
Do you know how to modify the filter to return a JSON or a better way to show the gray box by row?
Related questions:
Push down a series of divs when another div is shown
Update 1
The issue could be easily resolved by using the correct scope for the ng-repeat for the row without modifying the filter, thanks to #m59.
http://plnkr.co/edit/eEMfI1lv6z1MlG7sND6g?p=preview
Update 2
Live Demo
If I try to modify the item, it seems the ng-repeat would be called again losing the props values.
<div ng-repeat="friendRow in friends | partition:2"
ng-init="props = {}">
<div ng-repeat="item in friendRow"
ng-click="collapse(item)"
ng-class="{myArrow: showArrow}">
{{item.name}} {{item.age}} years old.
<div>{{item.name}}</div>
</div>
<div collapse="!props.isExpanded">
some content
<br/>
<input type="text" ng-model="currentItem.name">
</div>
</div>
js
$scope.collapse = function(item){
this.props.isExpanded = !this.props.isExpanded;
this.showArrow = !this.showArrow;
$scope.currentItem = item;
};
This causes the gray box to collapse each time the item is modified. Any clue?
I've updated my code/answer regarding partitioning data. It's important to fully understand all of that before deciding on an approach to your project.
The problem you have in your plnkr demo is that you're modifying the parent $scope and not the scope of the ng-repeat for that row.
Just set a flag on the row and toggle it when clicked:
Live Demo
<div
class="row"
ng-repeat="friendRow in friends | partition:2"
ng-init="isExpanded = false"
ng-click="isExpanded = !isExpanded"
>
<div ng-repeat="item in friendRow">
{{item.name}} {{item.age}} years old.
</div>
<div collapse="!isExpanded">
some content
</div>
</div>
To access the correct scope within a function in the controller, you can use the this keyword instead of $scope. this will refer to the scope the function is called from, whereas $scope refers to the scope attached to the element with ng-controller (a parent of the ng-repeat scopes you want to target).
<div
class="row"
ng-repeat="friendRow in friends | partition:2"
ng-click="collapse()"
>
JS:
$scope.collapse = function() {
this.isExpanded = !this.isExpanded;
};
If you want to keep the ng-click directive on the item element instead of putting it on the row element as I have done, then you're dealing with another child scope because of that inner ng-repeat. Therefore, you will need to follow the "dot" rule so that the child scope can update the parent scope where the collapse directive is. This means you need to nest isExpanded in an object. In this example, I use ng-init="props = {}", and then use props.isExpanded. The dot rule works because the children share the same object reference to props, so the properties are shared rather than just copied, just like in normal JavaScript object references.
Live Demo
<div
class="row"
ng-repeat="friendRow in friends | partition:2"
ng-init="props = {}"
>
<div ng-repeat="item in friendRow" ng-click="collapse()">
{{item.name}} {{item.age}} years old.
</div>
<div collapse="!props.isExpanded">
some content
</div>
</div>
JS:
$scope.collapse = function(){
this.props.isExpanded = !this.props.isExpanded;
};
Update
We keep going through more and more issues with your project. You really just need to experiment/research and understand everything that's going on on a deeper level, or it will just be one question after another. I'll give it one last effort to get you on the right track, but you need to try in the basic concepts and go from there.
You could get past the issue of props reinitializing by putting $scope.expandedStates and then passing the $index of the current ng-repeat to your function (or just using it in the view) and setting a property of expandedStates like $scope.expandedStates[$index] = !$scope.expandedStates[$index]. With the nested ng-repeat as it is, you'll need to do $parent.$index so that you're associating the state with the row rather than the item.
However, you'll then have another problem with the filter: Using my old partition code, the inputs inside the partitions are going to lose focus every time you type a character. Using the new code, the view updates, but the underlying model will not. You could use the partition filter from this answer to solve this, but from my understanding of that code, it could have some unexpected behavior down the road and it also requires passing in this as an argument to the filter. I don't recommend you do this.
Filters are meant to be idempotent, so stabilizing them via some kind of memoization is technically a hack. Some argue you should never do this at all, but I think it's fine. However, you definitely should ONLY do this when it is for display purposes and not for user input! Because you are accepting user input within the partitioned view, I suggest partitioning the data in the controller, then joining it back together either with a watch (continuous) or when you need to submit it.
$scope.partitionedFriends = partitionFilter($scope.friends, 2);
$scope.$watch('partitionedFriends', function(val) {
$scope.friends = [].concat.apply([], val);
}, true); // deep watch

Bound Input gets unfocused in angularjs

I am running this simple code with angularjs :
HTML :
<div ng-app ng-controller="AController">
<code>{{ itemsInArray }}</code>
<div ng-repeat="item in itemsInArray">
<input ng-model="itemsInArray[$index]" />
</div>
</div>
JavaScript :
function AController($scope) {
$scope.itemsInArray = ["strA", "strB", "strC"];
}
Binding appears to be working correctly when indexing into the array but after entering one character the input loses focus.
You can find the working code here on this fiddle : http://jsfiddle.net/QygW8/
I think this is happening because you are manipulating the same item which is iterated over ng-repeat. So ng-repeat sees a change in the item and re-runs the `ng-repeat which regenerates the items.
If you look at your fiddle html, you may notice this effect.
To make it work, one way you can do this
http://jsfiddle.net/cmyworld/CvLBS/
where you change your array to object array
$scope.itemsInArray = [{data:"strA"}, {data:"strB"}, {data:"strC"}];
and then bind to item.data
Try to change the model:
<div ng-repeat="item in itemsInArray">
<input ng-model="item" />
</div>
Even am an newbie to the angularjs, up-to my findings ng-repeat updates/repeats and recreates the whole HTML elements when there is an change in the model. Hence when a single character added to model causes ng-repeat to react and creates the all the HTML elements again which results to losing the focus.
This is an fiddle , In which u will be able to observer the changes with the model inside the ng-repeat and outside the ng-repeat.
Sorry i don't have the solution, Hope using ng-change apart of ng-model may help.

Angularjs: ng-repeat, put a ´divider´ in ng-repeat to separate data that was recently loaded

When the page is loaded the user is presented with a set of products, then if he/she clicks a button more products are fetched and appended to the list. I am trying to find an Angular way to put a row to separate the products that were already loaded from the recently appended. I don't want to manipulate the DOM directly and I can't push an empty row to the array of products because the length of the array is used somewhere else.
How could I do this?
Here is a basic Bin
If you don't want a divider after the last item, just use:
<... ng-repeat="...">
<hr ng-show="!$last" />
...
</...>
$last is true if the repeated element is last in the iterator.
I think you'll need to keep track of this yourself, in another $scope (array) property. In your ng-repeat loop, check to see if $index is in this array. If so, add/show the <hr>.
<... ng-repeat="...">
<span ng-show="showHr($index)"><hr></span>
...
</...>
Function showHr() should return true when you want to display an <hr>.
You could also use ng-switch instead of ng-show.

Resources