How to display "No data" message using AngularJS? - angularjs

The code looks as following:
<table>
<tr ng-repeat="action in actionList">
<td></td>
...
</tr>
<tr ng-show="!actionList.length">
<td>
No data.
</td>
</tr>
</table>
This works, but not in way I want because it initially displays "No data" message. I need to display nothing initially and the table with data if actionList.length is not 0. If actionList.length is 0 then display "No data" message, but not as a part of table.
Update:
I've added in my controler:
$scope.isButtonClicked = false;
$scope.queryResult = function () {
$scope.isButtonClicked = true;
$scope.actionList = [];
$scope.actionsQuery.resetPage();
appendPage();
};
But, "No data." message appears on every click. When there's some data it appears very shortly and disappears and when there's no data, it appears correctly.

Why you confusing? Lot of way of you can think to solve this.
Try this simple way
<table>
<tr ng-show="actionList.length!=0" ng-repeat="action in actionList">
<td></td>
...
</tr>
<tr >
<td ng-show="actionList.length==0">
No data.
</td>
</tr>
</table>
Update 1:-
Also you need to check actionList is undefined or null
And You should $scope.actionList is a array
You can check the actionList is null or undefined with ng-if Statement (try with ng-if instead of ng-show in the div tag)
Something like this below way
<div ng-show="actionList !='null' && actionList !='undefined'">
<table>
<tr ng-show="actionList.length!=0" ng-repeat="action in actionList">
<td></td>
...
</tr>
<tr >
<td ng-show="actionList.length==0">
No data.
</td>
</tr>
</table>
</div>
<div ng-show="actionList =='null'|| actionList =='undefined'">
No data.
</div>
Update 2 :-
Another simple way to instead of my update 1
try this below code.
<table>
<tr ng-show="actionList!='undefined' && actionList!='null' && actionList.length!=0" ng-repeat="action in actionList">
<td></td>
...
</tr>
<tr >
<td ng-show="actionList=='undefined' ||actionList=='null' || actionList.length==0 ">
No data.
</td>
</tr>
</table>
Here you can try with ng-if instead of ng-show
Update 3:
I want because it initially displays "No data" message. I need to display nothing initially and the table with data if actionList.length is not 0. If actionList.length is 0 then display "No data" message, but not as a part of table.
So Simple ...
Create a new Boolean Scope variable like a named as IsButtonClick
Globally declare $scope.IsButtonClick==false
Set $scope.IsButtonClick==true on your button click event
Then copy past this below code instead of your html code.
<div ng-show="IsButtonClick">
<table>
<tr ng-show="actionList!='undefined' && actionList!='null' && actionList.length!=0" ng-repeat="action in actionList">
<td></td>
...
</tr>
</table>
</div>
<div ng-show="IsButtonClick"> <span ng-show="actionList=='undefined' ||actionList=='null' || actionList.length==0 "> No data.</span> </div>
Update 4 :
But, "No data." message appears on every click. When there's some data it appears very shortly and disappears and when there's no data, it appears correctly
try this way
$scope.queryResult = function () {
$scope.isButtonClicked = false;
$scope.actionList = [];
$scope.actionsQuery.resetPage();
appendPage();
if($scope.actionList.Length==0)
{
$scope.isButtonClicked = true;
}
};
and the html is
<div ng-show="IsButtonClick">
<table>
<tr ng-show="actionList!='undefined' && actionList!='null' && actionList.length!=0" ng-repeat="action in actionList">
<td></td>
...
</tr>
</table>
</div>
<div ng-show="IsButtonClick"> <span ng-hide="actionList !='undefined' || actionList!='null' || actionList.length!=0 "> No data.</span> </div>

Try this :
<div ng-switch="!!actionsList.length">
<div ng-switch-when="true">
<table>
<tr ng-repeat="...">
<td> ... </td>
</tr>
</table>
</div>
<div ng-switch-when="false">
No data
</div>
</div>

try to put
<tr ng-show="!actionList.length">
<td ng-bind="noData">
</td>
</tr>

Related

Ng-if to show and hide td data

Attached is my code, tried showing td data when the condtion of ng-if is true
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report"
ng-if="(fellow.F_Id==value.fellowship_id)? (show_row = true) : (show_row=false)">
<td ng-show="show_row">{{value.Completed}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Not_Updated}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Total_schedule}}</td>
<td ng-hide="show_row">0</td>
</div>
</tr>
</tbody>
Its just giving 0 as result. Though data_report is having values
Tried adding span in td with conditions in td and result in span.
still the result is zero
May I know where the logic is going wrong and how it can be achieved?
Changed the code to
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<td>
<span ng-repeat="value in data_report" ng-show ="fellow.F_Id==value.fellowship_id">{{value.Completed}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Not_Updated}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Total_schedule}}</span>
</td>
</tr>
</tbody>
Here i am getting values but how can i set default value to zero if there are no values present?
In your case ng-if returns no boolean
The usage is (DOCs):
<ANY
ng-if="expression">
...
</ANY>
I think you dont need ng-if at all. You can write something like:
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report">
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Completed: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Not_Updated: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Total_schedule: 0}}</td>
</div>
</tr>
</tbody>
Its not best solution, in Javascript you can set for example value.Completed to be by default 0. It will help you to simplify your HTML

nested ng-repeat in angular js not showing anything

i am having this inside my controller method.
var employee = [{name:"ankur",dept:"IT",company:"wipro",under:[{name1:"ashish"},{name1:"akash"},{name1:"tyagi"},{name1:"mogra"}]}];
$scope.employee = employee;
and this inside html page.
<table>
<tr ng-repeat="emp in employee">
<td>{{emp.name}}</td>
<td>{{emp.dept}}</td>
<td>{{emp.company}}</td>
<td ng-repeat="(key , value) in emp.under">
a<td>{{key}}</td>
b<td>{{value}}</td>
</td>
</tr>
</table>
However, first ng-repeat is working fine, but it shows nothing at place of nested ng-repeat.
Your ng-repeat is fine, The problem is with the td inside another td, to do that you can do like this instead :
Fiddle
<div ng-app='app' ng-controller='mainCtrl'>
<table>
<tr ng-repeat="emp in employee">
<td>{{emp.name}}</td>
<td>{{emp.dept}}</td>
<td>{{emp.company}}</td>
<td ng-repeat="(key , value) in emp.under">{{value.name1}}
<table>
<tr>
a<td>{{key}}</td>
b<td>{{value.name1}}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
If you just want to check if your ng-repeat is working, remove the <td>'s and check like this :
<td ng-repeat="(key , value) in emp.under">
a{{key}}
b{{value}}
</td>

ng-repeat with click modifying input

<input ng-model = "val">
<a href ng-click="val = 1"> val = 1 </a>
<div class="test" ng-controller="Ctrl">
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="val = 1">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
Is there a way to make an input change based on a click in an ng-repeat?
In this jsfiddle you can the input change with a click outside of an ng-repeat, but in the repeat it doesn't change the input.
http://jsfiddle.net/Hp4W7/2403/
The problem is that you are setting the val property in a child scope created by ng-repeat.
The solution is to create a function that assigns this value to the parent scope:
$scope.changeVal = function(val){
$scope.$parent.val = val;
}
And call it with ng-click="changeVal(1)"
Fiddle here: http://jsfiddle.net/nawd7jjc/
ng-repeat always make new scope for every iteration so if you change any primitive value inside ng-repeat ("val" in this case) then it will not refer to the actual "val". So to solve it, it should be a object type, for ex. obj.val something
Below is the working solution for this problem:
<div class="test" ng-controller="Ctrl" ng-init="obj.val=12345">
<input ng-model = "obj.val">
<a href ng-click="obj.val = 2"> val = 2 </a>
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="obj.val = thing.num">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
</table>
<div>

Nested ng-repeat Issue to open list of rows with in the row

I want to open all the list of items at a time of their respective repeated row, here is plunker http://embed.plnkr.co/omBL2czm9fRBEVIeQUyD/
please help me out.
Here is my object:
$scope.names=[
{no:'1', name:'Jani', country:'Norway',
cities:[{city:'A1'},city:'A2'},{city: 'A3'}]},
{no:'2', name:'Hege',country:'Sweden',
cities:[{city:'b1'},{city:'b2'}, {city: 'b3'}]},
{no:'3', name:'Kai',country:'Denmark',
cities:[{city:'c1'},{city:'c2'}, {city: 'c3'}]}];
Here is my html :
<table>
<tbody ng-repeat="name in names">
<tr >
<td>
{{name.no}}
</td>
<td>
{{name.name}}
</td>
<td>{{name.country}}</td>
<td>
<button data-ng-click="isOpenPayablePayments[$index] = !isOpenPayablePayments[$index]; togglePayablePayments(name.no, $index)" >Paid</button>
</td>
</tr>
<tr data-ng-show="isOpenPayablePayments[$index]">
<td>
<table>
<thead>
<tr>
<th>City</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="city in cities">
<td>{{city.city}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Call back on button click within the repeat
var getCities = function (no) {
for (i = 0; i <= $scope.names.length; i++) {
if (no === $scope.names[i].no) {
console.log($scope.names[i].cities);
return $scope.names[i].cities;
}
};
};
$scope.togglePayablePayments = function (no, index) {
$scope.cities = getCities(no);
};
I want to open the nested list with respective row. plunkr explains the issue.
The problem isn't clearly explained however i see that when i open a 2nd tree all the items of all tree are the same. No need of the $scope.cities, it's the source of your problem.
i just changed the 2nd ng-repeat :
<tr data-ng-repeat="city in cities">
<td>{{city.city}}</td>
</tr>
to this :
<tr data-ng-repeat="city in name.cities">
<td>{{city.city}}</td>
</tr>

Loading text before data is loaded AngularJS

Does anyone have a clue how to create a loading text before angular loads data in to a list?
I have this code for getting info from different subwebs (in sharepoint). But before (or while) the list is loaded I want to display a text "Loading...":
context.executeQueryAsync(Function.createDelegate(this, function () {
var webs = this._webs.getEnumerator();
while (webs.moveNext()) {
var subWeb = webs.get_current();
$scope.sites.push({
title: webs.get_title(),
});
$scope.$apply();
}
}
}),
HTML:
<div ng-controller="MainCtrl">
<table>
<thead>
<tr>
<th>
Site
</th>
<th>
Created
</th>
</tr>
</thead>
<tbody ng-repeat="site in sites">
<tr>
<td>
{{site.title}}
</td>
<td>
{{site.created | date:dateFormat}}
</td>
</tr>
</tbody>
</table>
<tbody ng-if="sites.length == 0">
<tr>
<td>
<img src="loading.gif">
</td>
</tr>
</tbody>
<tbody ng-repeat="site in sites" ng-if="sites.length > 0">
<tr>
<td>
{{site.title}}
</td>
<td>
{{site.created | date:dateFormat}}
</td>
</tr>
</tbody>
This produce 2 watchers but it will help.
some links of loading indicator : angular-spinner or angular-sham-spinner
also BLOG detailing on how the spinner works with angularjs
and in case you want to implement it yourself, below code will get you started...
app.directive("spinner", function(){
return: {
restrict: 'E',
scope: {enable:"="},
template: <div class="spinner" ng-show="enable"><img src="content/spinner.gif"></div>
}
});
warning : i havent tested the code but directive wont be more complex than this...

Resources