Loading text before data is loaded AngularJS - 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...

Related

ng-repeat deosn't the data from JSON object in the HTML Template

I am trying to render a json as a table in a HTML Template using angularjs ng-repeat element. The script file passes the JSON object, but the ng-repeat wont render the contents of JSON.
I followed the steps from this tutorial link.
https://codepen.io/salva341/pen/aYKmvG
html template section where ng-repeat doesn't render properly
<div ng-controller="WorkflowShowCntrl">
<table class="table striped">
<thead>
<th>Job Name</th>
<th>Job Id</th>
<th>Start Time</th>
<th>Status</th>
</thead>
<tbody>
<tr ng-repeat="ttm in records.response" >
<td>{{ttm.name}} </td>
<td>{{ttm.status}} </td>
<td>{{ttm.name}} </td>
<td>{{ttm.name}} </td>
</tr>
</tbody>
</table>
</div>
app.js
angularjs 1.6.6
$http.get("/api/data-depot/currentjob/list")
.then(function(response) {
$scope.records = {"response":response.data}
$scope.parseItem = function(string)
{
var newString = string.replace(/['\']/g,'');
var jsonFormated = JSON.parse(newString);
return jsonFormated.Message;
}
});
Google chrome inspector : Section inspection screenshot
I have used an angularjs add-on inspector for chrome.
It looks like ttm is the array you want to display for. So I believe your ng-repeat should be more like:
<tr ng-repeat="record in ttm" >
<td>{{record.name}} </td>
<td>{{record.status}} </td>
<td>{{record.name}} </td>
<td>{{record.name}} </td>
ttm being the array, and record being a made-up name for each item in that array.
See: https://www.w3schools.com/angular/ng_ng-repeat.asp
As per your code, your are referencing wrong array name in your HTML binding.
Try this
<div ng-controller="WorkflowShowCntrl">
<table class="table striped">
<thead>
<th>Job Name</th>
<th>Job Id</th>
<th>Start Time</th>
<th>Status</th>
</thead>
<tbody>
<tr ng-repeat="item in records.response.ttm" >
<td>{{item.name}} </td>
<td>{{item.status}} </td>
<td>{{item.name}} </td>
<td>{{item.name}} </td>
</tr>
</tbody>
</table>
</div>
Finally I was was able to achieve what I wanted.
I added ng-bind element to display the data on the html template. That is weird. No of the scope variable gets displayed on the html template without ng-bind element. This investigating that is strange this is happening.
I would like to thank #Thaier Alkhateeb for their valuable comment.
Revised code snippet
<tbody ng-repeat="data in records.response ">
<tr ng-repeat="ttm in data">
<td ng-bind="ttm.name"> </td>
<td ng-bind="ttm.appId"> </td>
<td ng-bind="ttm.created"> </td>
<td ng-bind="ttm.status"> </td>
</tr>
</tbody>

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>

ng-repeat ($last) element with ng-if

var dataList = [{Id:1,Name: "xyz",Select: true},
{Id:2,Name: "PQR",Select : false }];
var headerList = [{"ID","Name","null"}]
i got this value from server side i can not make any changes in this array list.
My html code is
<table class= "table table-bordered">
<thead>
<tr ng-repeat="header in headerList">
<td ng-if="!$last">
{{header}}
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in dataList">
<td ng-repeat="value in data" ng-if="!$last">
{{value}}
</td>
</tr>
</tbody>
</table>
I don't want to generate "Select" column. code works propely , but when bordered class applies on table one blank column is display i.e "Select"
so that how can i remove this blank column in html DOM ?
You might want to write
<thead>
<tr>
<td ng-if="!$last" ng-repeat="header in headerList">
{{header}}
</td>
</tr>
</thead>
instead of this
<thead>
<tr ng-repeat="header in headerList">
<td ng-if="!$last">
{{header}}
</td>
</tr>
</thead>

AngularJS ng-include finished

I'm loading a large amount of data using ng-include.
I'd like to know if there is a way to know when a template is "rendered", because sometimes it seems like it's been "frozen", because I want to do a "loading screen" or something.
Thx.
Here's the code
controller code:
$scope.layout = {
current: 'single-table.html'
};
$scope.layout.get = function() {
return $scope.layout.current;
};
templates:
main.html
<div class="btn-group">
<button ng-click="layout.current = 'single-table.html'">Single</button>
<button ng-click="layout.current = 'multiple-table.html'">Multiple</button>
</div>
<div ng-include="layout.get()"></div>
single-table.html
<table class="table table-bordered">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
multiple-table.html
<table class="table table-bordered" ng-repeat="record in records">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
{{ field.display }}
</td>
</tr>
</tbody>
</table>
EDIT
I'm using version 1.2.0
One solution (probably not the best) is doing this (no ng-include)
<table class="table table-bordered" ng-show="layout.current == 'single-table.html'">
<thead>
<th ng-repeat="column in columns">{{ column.title }}</th>
</thead>
<tbody>
<tr ng-repeat="record in records">
<td ng-repeat="field in record.fields"
ng-controller="FieldController"
ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
<table class="table table-bordered" ng-repeat="record in records" ng-show="layout.current == 'multiple-table.html'">
<tbody>
<tr ng-repeat="field in record.fields">
<th>{{ columns[$index].title }}</th>
<td ng-controller="FieldController" ng-class="getClass()">
<span lud-run="{{ field.ng_directive }}"></span>
</td>
</tr>
</tbody>
</table>
I have only 20 records, but (is not in the code), each cells loads a custom directive depends on the data type (string, date, datetime, image...). This "solution" I think runs the same data twice (ng-show, not ng-if), but when a switch the layout mode there is no "lag".
You can use the onload hook on ng-include to update a variable when the include has finished rendering. If you set it to true on clicking your button, then revert it back to false in onload, you should be able to leverage it to temporarily display a loading screen.

How to display "No data" message using 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>

Resources