Failed initializing html tab with server data - javascript

I am creating an html page with two tabs. When you click on tab 1, it loads table data 1. When you click on tab 2,
it loads table data 2. Tab 1 is working as expected. However, when I click on tab 2, the data isn't loaded. The controllers
are identical. What is the difference?
Here is the relevant html code. tab with id "tableData" loads with data and tab with id "correlations" doesn't load.
<div>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation">Table Data</li>
<li role="presentation">Correlations</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tableData">
<h2 class="sub-header">Health Data</h2>
<div class="table-responsive" data-ng-app="myApp" data-ng-controller="journalCtrl">
<div data-ng-include="'screens/tablescreen.html'"></div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="correlations">
<h2 class="sub-header">Correlations Data</h2>
<div class="table-responsive" data-ng-app="correlationsApp" data-ng-controller="correlationsCtrl">
<div data-ng-include="'screens/tablescreen.html'"></div>
</div>
</div>
</div>
</div>
Here is my correlationsCtrl. init() is never invoked. Why?:
var correlationsApp = angular.module('correlationsApp', []);
correlationsApp.controller('correlationsCtrl', function ($scope, $http) {
$scope.init = function () {
$http.get("https://localhost:4567/foo/1/correlations")
.then(function (response) {
var json = response.data.records;
$scope.records = json;
$scope.headers = response.data.headers;
});
};
//This is not invoked. Why?
$scope.init();
});
Here is my controller which does get invoked:
var app = angular.module('myApp', []);
app.controller('journalCtrl', function ($scope, $http) {
$scope.init = function () {
$http.get("https://localhost:4567/journal/1")
.then(function (response) {
var json = response.data.records;
$scope.records = json;
$scope.headers = response.data.headers;
});
};
//This is invoked on page load. Why does this work and the other doesn't?
$scope.init();
});
Here is the html table:
<table class="table table-striped">
<thead>
<tr>
<th data-ng-repeat="header in headers">{{header}}</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="record in records track by $index">
<td data-ng-repeat="header in headers">{{ record.data[header] }}</td>
</tr>
</tbody>
</table>

In html you declare data-ng-controller="fooCtrl" but you have no controller fooCtrl. No need to declare two different module for two tabs you can declare two controller for two tabs in same module.
like:
var app = angular.module('myApp',[]);
app.controller('correlationsCtrl', function ($scope, $http) {
$scope.init = function () {
// your code
};
$scope.init();
}).controller('journalCtrl', function ($scope, $http) {
$scope.init = function () {
// your code
};
$scope.init();
});
so you use ng-app = "myApp" in root element like <html ng-app="myApp"> or <body ng-app="myApp"> and use only data-ng-controller in your tab page.
<div class="table-responsive" data-ng-controller="journalCtrl">
<div data-ng-include="'screens/tablescreen.html'"></div>
</div>
and
<div class="table-responsive" data-ng-controller="correlationsCtrl">
<div data-ng-include="'screens/tablescreen.html'"></div>
</div>
See PLUNKER DEMO two tabs show data from two different controllers.

Related

Load Data from Database Without Blinking Angular Js

Am loading data from database to a table in html with angualar js. am also using interval so as to make the table reload every 10 seconds to get new data that has just been inputed by other users.
Problem:
The table blinks every time it reloads. making the page look funny like it has a glitch.
What am looking for:
Is there a way i can make the new data just slide in from the top of the table and become number one while the rest re adjust underneath it And become number two, three and so on. i was made to believe Angular Js is magical reason why i opted for it instead of using my usual AJAX
Angular Code
var supDetails = angular.module("supDetails", ['datatables']);
supDetails.controller('supportController', function($scope, $http, $interval) {
$scope.names = [];
$scope.isFirst = true;
$scope.loadData = function() {
var httpRequest = $http({
method: 'GET',
url: 'anfil.php?ins=sup'
}).success(function(data, status) {
console.log('loading..');
$scope.names = data;
if(!$scope.isFirst){
angular.forEach(data,function(key,val){
$scope.names[key] = data[key];
});
}
$scope.isFirst = false;
});
};
$scope.loadData();
// Function to replicate setInterval using $timeout service.
$interval(function () {
$scope.loadData();
}, 10000);
});
My HTML
<!-- /.col -->
<div class="col-md-9" ng-app = "supDetails" ng-controller="supportController">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Messages</h3>
<!-- /.box-tools -->
<div class="box-tools pull-right">
<div class="has-feedback">
<button type="button" ng-click="loadData()" class="btn btn-default btn-sm"><i class="fa fa-refresh"></i></button>
</div>
</div>
</div>
<!-- /.box-header -->
<div class="box-body no-padding">
<div class="mailbox-messages">
<table datatable="ng" class="table table-hover table-striped">
<thead>
<tr>
<th>Stat</th>
<th>Name</th>
<th>Problem</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names">
<td class="mailbox-star"><i class="fa fa-circle text-blue"></i></td>
<td class="mailbox-name">{{x.user_id}}</td>
<td class="mailbox-subject"><b>{{x.ticket_title}}</b> - {{x.subject}}
</td>
<td class="mailbox-date">{{x.ticket_open_date}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Stat</th>
<th>Name</th>
<th>Problem</th>
<th>Time</th>
</tr>
</tfoot>
</table>
<!-- /.table -->
</div>
<!-- /.mail-box-messages -->
</div>
<!-- /.box-body -->
</div>
<!-- /. box -->
</div>
<!-- /.col -->
I think its your css problem which doesn't have a minimum height as you can see in this snippet its not blinking..
If you still want data to appear slide from up to down, You can uncomment the code in the answer, in this way it will remove row one by one from the table and replace it with the new one.
var app = angular.module('myApp', []);
function PeopleCtrl($scope, $http,$interval) {
$scope.people = [];
$scope.isFirst = true;
$scope.loadPeople = function() {
var httpRequest = $http({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/users'
}).success(function(data, status) {
console.log('loading..');
$scope.people = data;
/* if(!$scope.isFirst){
angular.forEach(data,function(val,key){
$scope.people[key] = data[key];
});
}
$scope.isFirst = false;*/
});
};
$scope.loadPeople();
$interval(function () {
$scope.loadPeople();
}, 10000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div ng-app="myApp">
<div ng-controller="PeopleCtrl">
<table class="table">
<tr>
<th>Id</th>
<th>Name</th>
<th>UserNmae</th>
</tr>
<tr ng-repeat="person in people">
<td>{{person.id}}</td>
<td>{{person.name}}</td>
<td>{{person.username}}</td>
</tr>
</table>
</div>
</div>
There are a few ways to solve your problems:
1) Write algorithm, that load your data then compare it with existing data. If there any diffs you, should add just new records to your table.
2) Use WebSockets, they will give you ability to get from server only new records in real-time.

Passing ng-click value to one controller and use it in another controller

I am using a table and a button inside the table pops up a modal. I want to pass the Id value in that row to the modal controller so that I can use it to pass it to the the rest api call and then subsequently load valus in the modal table.
App.js
var app = angular.module("UiApp", ["ServiceApp"]);
app.service('sharedProperties', function () {
var idValue = 'test string value';
return {
getId: function () {
return idValue;
},
setId: function (value) {
idValue = value;
}
}
});
app.controller("PortFolioController", function ($scope, GetPortfolios,sharedProperties) {
$scope.Portfolios = GetPortfolios.query({ pmid: 2 });
console.log($scope.Portfolios);
$scope.addOrder = function (id) {
sharedProperties.setId(id)
};
});
app.controller("OrderController", function ($scope, GetOrders,sharedProperties) {
$scope.item = sharedProperties.getId();
$scope.Orders = GetOrders.query({ id: item});
});
Service.js
var app = angular.module("ServiceApp", ["ngResource"]);
app.factory('GetPortfolios', function ($resource) {
return $resource("http://localhost:61347/api/PortfolioManager/GetPortfolios/");
});
app.factory('GetOrders', function ($resource) {
return $resource("http://localhost:61347/api/PortfolioManager/GetPortfolioOrders/");
});
HTML
<div >
<table class="table table-striped table-hover table-bordered" id="editable-sample" ng-controller="PortFolioController">
<thead>
<tr>
<th>Portfolio ID</th>
<th>Portfolio Name</th>
<th>Portfolio Type</th>
<th>Portfolio Description</th>
<th>Show Stocks</th>
</tr>
</thead>
<tbody>
<tr class="" ng-repeat="portfolio in Portfolios">
<td>{{portfolio.portfolioId}}</td>
<td>{{portfolio.portfolioName}}</td>
<td>{{portfolio.type}}</td>
<td>{{portfolio.description}}</td>
<td> <button type="button" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#myModal" ng-click="addOrder(portfolio.portfolioId)" >Show <i class="fa fa-info-circle"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<!--Modal start-->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">My Portfolio</h4>
</div>
<div class="modal-body">
<h3>Stock List</h3>
<div class="space15"></div>
<table class="table table-striped table-hover table-bordered" id="editable-sample" ng-controller="OrderController">
<thead>
<tr>
<th>Symbol</th>
<th>Stock Name</th>
<th>Quantity</th>
<th>Market Price</th>
</tr>
</thead>
<tbody>
<tr class="" ng-repeat="order in Orders">
<td>{{order.symbol}}</td>
<td>{{order.executedQuantity}}</td>
<td>{{order.price}}</td>
<td>{{order.createTStamp}}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close <i class="fa fa-times"></i></button>
</div>
In PortFolioController Controller, you can do:
$rootScope.$broadcast('eventName', id);
and listen to the event in OrderController Controller:
$scope.$on('eventName', function (event, id) {...});
Also you can use AngularJS Service Passing Data Between Controllers to see some examples
or the simpleset way without any service is to use $rootScope and $broadcast an event from one Controller and listen to it in the other Controller
thus, No need of writing an extra service sharedProperties
Something like this :-
app.controller("PortFolioController", function ($scope, GetPortfolios,$rootScope) {
//Other Codes
$scope.addOrder = function (id) {
$rootScope.$broadcast('ID-Clicked', { Id: id});
};
}
app.controller("OrderController", function ($scope, GetOrders,$rootScope) {
//Other Codes
//Listen for the event
$rootScope.$on('ID-Clicked', function(event, data){
$scope.item = data.Id;// data.Id has the Clicked Id
});
}
This approach can be done using 2 ways.
First Way is to broadcast some events from the parent rootscope instance and capture that on the $scope elements.This format is not considered as a good way of coding.
Secondly, to communicate data between controllers use a service.Yeah you are currently on the right,clean & widely accepted path.
Remember that services are singletons.so once instansiated it is available to all controllers.But the challenge here is as soon as you click on button element your service sets your idValue in the service.Now how does the second controller know that.The answer would be register a $watch service to watch if the idValue in the service is changed as below.
app.controller("OrderController", function ($scope, GetOrders, sharedProperties) {
$scope.$watch(function () {
return sharedProperties.getId()
}, function (newValue, oldValue) {
if (newValue != oldValue) {
$scope.item = newValue;
$scope.Orders = GetOrders.query({ id: item });
}
});
});

How to define a function inside angular ui modal controller

I try to define a function inside angular ui modal controller by default a found the two function $scope.ok and the $scope.cancel and I want to add my function that remove an item form a list of items that a send to that controller
This my angular ui modal controller code :
myapp.controller('ModalInstanceCtrl', function ($scope,$location,$uibModalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
alert("redirection");
$location.path('/questionnaire');
};
$scope.closeListeChoix = function () {
$uibModalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
$scope.deleteChoix=function($index)
{
alert("supp")
$scope.items.splice($index, 1);
};
});
and here where I send the liste of items to modal controller
$scope.ListeChoixOneQuestion=[];
$scope.openListeChoix = function ($index) {
$scope.ListeChoixOneQuestion=$scope.questions[$index].choix ;
console.log("*********** choix de la question **********")
for(var i=0;i<$scope.ListeChoixOneQuestion.length;i++){
console.log("choix : "+$scope.ListeChoixOneQuestion[i].designation);
}
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'listeOfChoix.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.ListeChoixOneQuestion;
}
}
});
and this my html code when i call the function deleteChoix in my ng-click nothing happen and the item did not remove from the list of items
any solution
<div class="modal-body">
<div class="row">
<div class="table-responsive">
<table id="Table2" class="table table-bordered table-striped">
<thead>
<tr>
<th>Designation</th>
<th>Image</th>
<th>Aller à la question</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="choix in items track by $index">
<td>{{choix.designation}}</td>
<td>{{choix.imageUrl}}</td>
<td>{{choix.gotoQuestion}}</td>
<td class="text-center" style="width: 50px;">
<span class="btn btn-danger btn-xs fa fa-remove" style="cursor: pointer;" ng-click="deleteChoix($index);"></span>
</td>
<tr>
</tbody>
</table>
</div>
</div>
</div>
As said in comment the short solution is
$parent.deleteChoix($index);
It is a scope problem du to limit of inheritancy in Javascript.
If you don't want to have this problem, always use an inermediary object like :
$scope.context = {};// NEVER forget to initialize it in your controller or it won't work even if you don't put anything in at the start.
$scope.context.deleteChoix = [...];
So you won't need to wonder if you should use $parent or even $parent.$parent.
Check http://zcourts.com/2013/05/31/angularjs-if-you-dont-have-a-dot-youre-doing-it-wrong/ for more information.

API call on click of link in angular JS

I am trying to call an api on click of a link and show the data in a new view , but i am not seeing any data neither an error on console.I tried using Log also but thats also not giving me any clue.
Here is my code in View:
<tr class="well-new" ng-repeat="product in gettempdata.FoodItems| orderBy:'Id' | filter:search"">
<td class="tdCenter" >
{{product.Id}}
</td>
<td class="tdCenter">
<img ng-src="{{product.ImageUrl}}" alt="{{product.Name}}" />
</td>
<td>
<b>{{product.Name}}</b><br />
{{product.Category}}
</td>
</tr>
</table>
I am trying to call GetItemDetails(Id).
Controller code:
myStore.controller("Home", function ($scope, StoreService, $log, $window) {
var onComplete = function (data) {
$scope.gettempdata = data;
}
var onError = function (reason) {
alert(reason.errorcode);
}
$scope.GetItemDetails = function (Id) {
$log.info("wait for 5 secs");
StoreService.getItemDetails(Id).then(onComplete, onError);
$log.info("done");
}
});
App.js code:
var myStore = angular.module('groceries', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.
when("/Home", {
templateUrl: "/Index.html",
controller: "Home"
}).
when("/Name", {
templateUrl: "Store/Product.html",
controller: "Home"
}).
otherwise
({
redirectTo: "/Home"
})
});
The Home view:
<html ng-app="groceries">
<head>
<script> ALL scripts</scripts>
<title></title>
</head>
<body>
<!--
bootstrap fluid layout
(12 columns: span 10, offset 1 centers the content and adds a margin on each side)
-->
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 offset1">
<h1 class="well">
<b>Store </b>
</h1>
<!-- Click here to navigate to Store-->
<div ng-view ></div>
</div>
</div>
</div>
</body>
</html>
Please check the case of the variables, .id instead of .Id
{{product.id}} {{product.imageUrl}}{{product.name}}{{product.category}}
Anchor tag has precedence for href over ng-click and so that won't work.
I modifed my code as below:
<td >
<a ng-href="" ng-click="GetItemDetails(product.Id,window.location.href='/Name')"><b>{{product.Name}}</b></a><br /></td>

Angular ng-click load controller

I'm trying to practice angular and I'm stuck this this.
How do I make ng-click load the displayController? Or am I doing this wrong way?
The Angular
var bible = angular.module('bible', []);
// Load the Books
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$http.get('books.json').success(function(data) {
$scope.books = data
});
}]);
bible.controller('displayController', function($scope) {
$scope.test = "TEST TEXT";
});
The HTML
<div class="row">
<div class="col-md-12" ng-controller="listController">
<table class="table">
<thead>
<th>Testament</th>
<th>Title</th>
<th>Chapters</th>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{book.testament}}</td>
<td>{{book.title}}</td>
<td>{{book.chapters}}</td>
</tr>
</tbody>
</table>
<div class="display-book" ng-controller="displayController">
{{test}}
</div>
</div>
</div>
You don't need the additional controller there. I guess you want to display additional infos about the clicked book.
Use a reference and ngIf
var bible = angular.module('bible', []);
// Load the Books
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$scope.selectedBook = null;
$http.get('books.json').success(function(data) {
$scope.books = data
});
}]);
And html:
<div class="row">
<div class="col-md-12" ng-controller="listController">
<!-- will be shown, as long as not book is selected -->
<table data-ng-if="selectedBook == null" class="table">
<thead>
<th>Testament</th>
<th>Title</th>
<th>Chapters</th>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{book.testament}}</td>
<td>{{book.title}}</td>
<td>{{book.chapters}}</td>
</tr>
</tbody>
</table>
<!-- will be shown, when a book got selected -->
<div data-ng-if="selectedBook != null" class="display-book">
<!-- display the selection table again -->
<button data-ng-click="selectedBook = null">Back</button>
{{selectedBook.title}}
</div>
</div>
</div>
Why do you want to call a separate controller cant you implement the functionality in a separate function like below ,
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$http.get('books.json').success(function(data) {
$scope.books = data
});
$scope.display = function(){
// **YOUR CODE COMES HERE**
}
}]);
<td>{{book.title}}</td>

Categories

Resources