bind dropdown and set selected value using angularJS - angularjs

I have a form which populates location data, using angularJS. The form has 3 dropdowns for Location Type, Time Zone and Parent. For an existing location, I want the attributes to be selected in the dropdowns when the data is loaded. However, in following implementation, the dropdowns are populated, but the values are not selected.
HTML:
<tr>
<td style="width:20%"><label for="locationType">{{'_LocationTypeLabel_' | i18n}}:</label></td>
<td style="width:25%"><select data-ng-model="vm.locationSettings.basicSettings.locationType.locationTypeId" data-ng-options="l.locationTypeDisplayName for l in vm.locationTypes track by l.locationTypeId" /></td>
<td style="width:20%"><label for="parent">{{'_LocationParentLabel_' | i18n}}:</label></td>
<td style="width:25%"><select data-ng-model="vm.locationSettings.basicSettings.parent" data-ng-options="l.locationName for l in vm.parentLocations track by l.locationId" /></td>
</tr>
<tr>
<td style="width:20%"><label for="timezone">{{'_TimeZonesLabel_' | i18n}}:</label></td>
<td style="width:25%"><select data-ng-model="vm.locationSettings.basicSettings.timeZone" data-ng-options="l.displayName for l in vm.timeZones track by l.timeZoneId" /></td>
<td></td>
<td></td>
</tr>
controller:
function loadLocationData() {
clientcontext.clientlookup.getAllPublic().then(function (data) {
for (var i = 0; i < data.results.length; i++) {
vm.locationTypes.push(data.results[i]);
}
clientcontext.location.getLocations(vm.clientId, 1)
.then(function (data) {
for (var i = 0; i < data.length; i++) {
vm.parentLocations.push(data[i]);
}
systemcontext.systemlookup.getTimeZones()
.then(function (data) {
for (var i = 0; i < data.length; i++) {
vm.timeZones.push(data[i]);
}
//set the location attributes
vm.locationSettings.basicSettings = basicSettingsFactory.init().then(function () {
systemcontext.systemlookup.getTimeZoneById(vm.locationSettings.basicSettings.timeZone)
.then(function (data) {
vm.locationSettings.basicSettings.timeZone = data;
});
});
});
});
});
}
the location attributes are populated using a separate factory, as - vm.locationSettings.basicSettings = basicSettingsFactory.init()
function basicSettingsFactory($q, $http, $route, $location, $rootScope, $window, common, clientcontext, localize) {
var basicLocationSettings = {};
function getLocationDetails() {
clientcontext.location.getLocationById($route.current.params.clientId, $route.current.params.id)
.then(function (data) {
basicLocationSettings.id = data.locationId;
basicLocationSettings.parent = data.fkParentLocationId;
basicLocationSettings.locationType = data.locationType;
basicLocationSettings.locationName = data.locationName;
basicLocationSettings.locationDisplayName = data.locationDisplayName;
basicLocationSettings.locationCode = data.locationCode;
basicLocationSettings.isActive = data.activeStatus;
basicLocationSettings.timeZone = data.fkTimeZoneId;
});
}
return {
// Initializes the entire monitoring probe scope variables.
init: function () {
getLocationDetails();
return basicLocationSettings;
}
};
}
})();
Can someone please point out what I'm doing wrong, that doesn't set the selected value in the dropdowns?
Thanks in advance
UPDATE:
Could the issue be that, the attribute locationtype has a integer value like 3, but what's bound to the dropdown is a LocationType object?

Look your updated code, it might help you.
function basicSettingsFactory($q, $http, $route, $location, $rootScope, $window, common, clientcontext, localize) {
var basicLocationSettings = {};
// Need to put the default Ids for selection display.
//The code look like this
basicLocationSettings.id = default; //defaylt Id
function getLocationDetails() {
clientcontext.location.getLocationById($route.current.params.clientId, $route.current.params.id)
.then(function (data) {
basicLocationSettings.id = data.locationId;
basicLocationSettings.locationName = data.locationName;
basicLocationSettings.locationDisplayName = data.locationDisplayName;
});
}
return {
// Initializes the entire monitoring probe scope variables.
init: function () {
getLocationDetails();
return basicLocationSettings;
}
};
}
})();

Related

basic $scope connection with model

Its my code:
.controller("GetAllAuthors", function ($scope, $http) {
$http.get('http://localhost:8080/authors')
.then(function (response) {
$scope.authors = response.data;
});
$scope.edit = function (index) {
for (var i = 0; i < $scope.authors.length; i++) {
if ($scope.authors[i].id == index) {
$scope.object = $scope.authors[i];
break;
}
}
}
})
Html view:
<tbody ng-repeat="author in authors">
<td><input type="button" ng-click="edit(author.id)" value="Edit"/></td>
<div ng-controller="GetAllAuthors">
{{object.id}} // <--- doesn't display it
</div>
It's not working. I can't use date binding with my object. How fix it?
You need to put http inside edit method.
.controller("GetAllAuthors", function ($scope, $http) {
$scope.edit = function (index) {
$http.get('http://localhost:8080/authors')
.then(function (response) {
$scope.authors = response.data;
for (var i = 0; i < $scope.authors.length; i++) {
if ($scope.authors[i].id == index) {
$scope.object = $scope.authors[i];
break;
}
}
});
}
})
Try this
Initialize $scope.object outside the function.

angularjs object list not binding to ng-repeat

I am using angular 1.5.5 with ui router 0.2.14. I have the view of employee list to be displayed. EmployeeList template is as follows:
<table class="employeeListContainer">
<tr ng-repeat="employee in employees">
<td>
<a ng-bind="employee.EmployeeId" class="employeeId"></a>
<!--ui-sref="employeeDetails{ employeeId: employee.EmployeeId }"-->
</td>
<td ng-bind="employee.FirstName"></td>
<td ng-bind="employee.LastName"></td>
</tr>
<tr>
<td colspan="3" class="paging">
<button ng-disabled="!IsPrevButtonEnabled" ng-click="prevPage()" class="prev-next"><</button>
<span ng-bind="PageNumber"></span>
<button ng-disabled="!IsNextButtonEnabled" ng-click="nextPage()" class="prev-next">></button>
</td>
</tr>
<tr>
<td colspan="3" class="paging">
<span ng-bind="ErrorMessage" ng-show="IsError"></span>
</td>
</tr>
</table>
I have configured the app as follows:
var app = angular.module('app', ['ui.router']);
app.config(function ($urlRouterProvider, $stateProvider, $httpProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('employeeList', {
url: '/List',
templateUrl: '../../Templates/EmployeeList.html',
controller: 'EmployeeListController',
resolve: {
employeeListRs: function (dataService) {
var employeeListRq = getEmployeeListRqInit();
return dataService.callApi('GetEmployees', 'post', [employeeListRq])
.then(function (data) { return data.data; });
},
employeeListRq: function(){
return getEmployeeListRqInit();
},
greeting: function ($q, $timeout) {
var deferred = $q.defer();
$timeout(function () {
deferred.resolve('Hello!');
}, 1000);
return deferred.promise;
}
}
});
$stateProvider.state('default', {
url: '/',
//templateUrl: '../../Templates/EmployeeList.html',
controller: 'defaultController'
});
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
var getEmployeeListRqInit = function () {
return {
PageNumber: 1,
PageSize: 10,
SessionId: "123"
};
}
});
dataService is a service that is wrapper to the original $http.post call. Controller code is as follows:
app.controller('EmployeeListController', function ($scope, employeeListRq, employeeListRs, greeting) {
$scope.PageNumber = employeeListRq.PageNumber;
$scope.PageSize = employeeListRq.PageSize;
$scope.IsError = !employeeListRs.IsSuccess;
$scope.TotalCount = (employeeListRs.EmployeeList == null) ? 0 : employeeListRs.EmployeeList.TotalCount;
$scope.employees = (employeeListRs.EmployeeList == null) ? null : employeeListRs.EmployeeList.Employees;
if ($scope.employees = null) return 1;
var remainder = $scope.TotalCount % $scope.PageSize;
var pageNumber = Math.floor($scope.TotalCount / $scope.PageSize);
var lastPageNumber = remainder > 0 ? pageNumber + 1 : pageNumber;
$scope.IsNextButtonEnabled = $scope.PageNumber != lastPageNumber;
$scope.IsPrevButtonEnabled = $scope.PageNumber != 1;
$scope.IsLoading = false;
$scope.ErrorMessage = employeeListRs.IsSuccess ? '' : employeeListRs.ErrorMessage;
});
I see while debugging in chrome that $scope.employees is set to an array containing 10 objects all with proper fields and values. Also the IsPrevButtonEnabled and IsNextButtonEnabled are set perfectly. The binding is reflected on UI too, perfectly.
But I don't see the table containing employees list. Any suggestions on what I am missing?
Note: I don't get any error on console.
A few things you can try:
(1) Not saying yours is incorrect, but the preferred way to bind the data would be to use expressions. So, instead of this:
<td ng-bind="employee.FirstName"></td>
try this:
<td>{{employee.FirstName}}</td>
(2) This line looks suspicious in your controller:
if ($scope.employees = null) return 1;
It looks like you are assigning a null value to $scope.employees instead of checking for null. I/my teams try to use angular.isDefined($scope.employees) when we want to check for existence.
What are you trying to accomplish with that line?
(3) This looks a little different than how I use services and how I see others use them:
resolve: {
employeeListRs: function (dataService)
It looks to me that employeeListRs returns a promise.
What I typically do is call the service (my angular service which in turn calls the $http service) from inside the controller and then handle the response (both expected and error responses). From there I push the data into the controller's model. I haven't yet mixed service calls into my state machines - I let the controllers make the service calls.
(4) What is inside this css class - employeeListContainer? Could there be something there hiding your table? You might want to share your html and css as well.

Returning REST Data To Another Function

So I am incorporating AngularJS into a SharePoint page that I am creating. I have a function that gathers information from a list in SharePoint via a REST function. What it is supposed to do is populate a table with the data it retrieves from the REST call. It does this fine, however, one of the fields is a 'Person or Group' field and rather than returning the name of the person, it returns their ID which is fine but it calls for me to perform another REST call on another list. I have successfully done so and filtered out the results based on the users ID. What I did was pass a user ID to a function that calls the REST function to the list that contains the users name and then wrote an if statement basically saying if the passed ID equals a given element ID, display the the users name. The problem I am having is while I have retrieved the correct data, I am not able to return the data and I believe the reason why is because I am trying to return data from a nested functions. I have a function and within that function an $http.success function. The data I am trying to retrieve resided in the $http.success function. Sorry if this question is hard to follow but hopefully taking a look at the below code will help to clear things up.
P.S. When I alert the code from the 'displayProjDetails' function I receive an undefined message, but when I alert it from the 'getUser' function it displays the data properly.
Thanks in advance for any assistance.
ANGULAR CODE:
// Function to display Project Details Data
$scope.displayProjDetails = function() {
$http({type: "GET", url:"http://mysiteurl/_api/web/lists/getbytitle('Project%20Details')/items?$top=5000", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.details = [];
var full_funded;
for(i=0; i < data.d.results.length; i++) {
if(data.d.results[i].gibi == $scope.selectedProject.id) {
alert($scope.getUser(data.d.results[i].Project_x0020_POCId)); // CALL TO FUNCTION I AM WORKING ON (LOCATED AT THE BOTTOM OF THE PAGE)
if(data.d.results[i].Fully_x0020_Funded == true) {
full_funded = "Yes";
} else {
full_funded = "No"
}
$scope.details.push({id: data.d.results[i].gibi, poc: data.d.results[i].Project_x0020_POCId, code_poc: data.d.results[i].Code_x0020_312_x0020_POCId,
perc_complete: data.d.results[i].OData__x0025__x0020_Complete, funded: full_funded, pop_from: data.d.results[i].PoP_x0020_From,
pop_to: data.d.results[i].PoP_x0020_To});
}
};
});
}
// Function to retrieve the name of the Point of Contact (Currently working on this...)
$scope.getUser = function(value) {
$http({type: "GET", url: "http://mysiteurl/_api/web/siteusers?$top=5000", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.user_attributes = [];
for(i=0; i < data.d.results.length; i++) {
if(data.d.results[i].Id == value) {
return data.d.results[i].Title;
}
};
});
}
HTML CODE
<div class="col-lg-9" id="project_details_table">
<h3>Project Details</h3>
<table class="table table-striped">
<thead>
<tr>
<th>Project ID</th>
<th>PoC</th>
<th>Code 2532 PoC</th>
<th>% Complete</th>
<th>Fully Funded</th>
<th>PoP From</th>
<th>PoP To</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="detail in details">
<td data-ng-bind="detail.id"></td>
<td data-ng-bind="detail.poc"></td> <!--TRYING TO REPLACE THIS WITH THE USER'S NAME INSTEAD OF THE USER'S ID-->
<td data-ng-bind="detail.code_poc"></td>
<td data-ng-bind="detail.perc_complete"></td>
<td data-ng-bind="detail.funded"></td>
<td data-ng-bind="detail.pop_from | date:'yyyy/MM/dd'"></td>
<td data-ng-bind="detail.pop_to | date:'yyyy/MM/dd'"></td>
</tr>
</tbody>
</table>
</div>
UPDATE:
Upon making the recommended changes to my code, my data is displayed as follows...
As you can see, what I am trying to do is replace the '[object Object]' with the proper name. Here it is just adding new rows to the table rather than placing the name in its correct location. Here is my updated code...
$scope.getUser = function(value) {
return $q(function(resolve, reject){
$http({type: "GET", url: "http:mysiteurl/_api/web/siteusers?$top=5000", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
for(i=0; i < data.d.results.length; i++) {
if(data.d.results[i].Id == value) {
resolve(data.d.results[i].Title);
}
};
});
});
}
// Function to display Project Details Data
$scope.displayProjDetails = function() {
$http({type: "GET", url:"http:mysiteurl/_api/web/lists/getbytitle('Project%20Details')/items?$top=5000", headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.details = [];
$scope.name = [];
var full_funded;
for(i=0; i < data.d.results.length; i++) {
if(data.d.results[i].gibi == $scope.selectedProject.id) {
$scope.name = $scope.getUser(data.d.results[i].Project_x0020_POCId).then(function(user){$scope.details.push({poc: user});});
if(data.d.results[i].Fully_x0020_Funded == true) {
full_funded = "Yes";
} else {
full_funded = "No"
}
$scope.details.push({id: data.d.results[i].gibi, poc: $scope.name, code_poc: data.d.results[i].Code_x0020_312_x0020_POCId,
perc_complete: data.d.results[i].OData__x0025__x0020_Complete, funded: full_funded, pop_from: data.d.results[i].PoP_x0020_From,
pop_to: data.d.results[i].PoP_x0020_To});
}
};
});
}
The problem is that your are working with async calls, so you can't return data, because the alert don't wait for the promise response, so one way to solve the problem is to return the promise from getUser:
return $http ...
then in the alert :
alert($scope.getUser(data.d.results[i].Project_x0020_POCId).then(function(name){return name;}));
$scope.getUser = function(value) {
return $q(function(resolve, reject){
$http({type: "GET", url: "http://mysiteurl/_api/web/siteusers$top=5000",
headers: { "ACCEPT": "application/json;odata=verbose"}})
.success(function(data) {
$scope.results = data.d.results;
$scope.user_attributes = [];
for(i=0; i < data.d.results.length; i++) {
if(data.d.results[i].Id == value) {
resolve(data.d.results[i].Title);
}
};
});
}
$scope.getUser(data.d.results[i].Project_x0020_POCId)
.then(function(user){
alert(user)
});

Filter JSON data by date Angularjs

I'm trying to filter the following JSON, so that I only load the up and coming fixtures, in other words all fixtures from the current time onwards. But nothing loads, do I have something wrong, maybe the format of the date, not sure.
JSON
http://www.football-data.org/teams/354/fixtures/?callback=JSON_CALLBACK
FILTER
angular.module('PremierLeagueApp', [])
.filter('upComingFixtures', function() {
return function (fixtures) {
var filtered_list = [];
for (var i = 0; i < fixtures.length; i++) {
var currentTime = new Date().getTime();
var fixtureDate = new Date(fixtures[i].date).getTime();
if (currentTime <= fixtureDate) {
filtered_list.push(fixtures[i]);
}
}
return filtered_list;
}
});
CONTROLLER
.controller('fixturesController', function($scope, $routeParams, footballdataAPIservice) {
$scope.id = $routeParams.id;
$scope.fixtures = [];
footballdataAPIservice.getFixtures($scope.id).success(function (response) {
$scope.fixtures = response;
});
});
HTML
<tr ng-repeat="fixture in fixtures.fixtures | upComingFixtures">
<td>{{$index + 1}}</td>
<td>{{teamName(fixture.awayTeam)}}</td>
</tr>
I believe your filter should accept a value and then return true/false to either include that value or not. Something like this
<tr ng-repeat="fixture in fixtures.fixtures | upComingFixtures(fixture)">
$scope.upComingFixtures = function(fixture) {
if(fixture time > current time) {
return true; // include this
} else {
return false; // Don't include this
}
}
Sorry, I forgot to declare the filter in the app.js:
angular.module('PremierLeagueApp', [
'PremierLeagueApp.services',
'PremierLeagueApp.controllers',
'PremierLeagueApp.filters',
'ngRoute','ngAnimate'
]).
so all's fine with the code above :) Thanks in any case.

Angularjs ui bootstrap - Don't know how to cycle through table data with Pagination

I currently have a page that has clickable data. When clicked, a modal comes up that has a table built with customer data received from a service. I have included Angularjs ui boostrap plugin and have implemented the pagination directive. I have the pagination working in the sense that the links are able to switch back and forth as well as the previous and next buttons. What I do not know how to do is cycle through the table data displaying the amount specified in the controller. Code is below:
Drilldown Directive:
var drilldownDirective = function () {
return {
restrict: 'E',
scope: {
tableData: '='
},
controller: function ($rootScope, $scope, DashboardFactory) {
var tableData = $scope.tableData;
var dashboardreportid = tableData.dashboardreportid;
var companyid = tableData.companyid;
var companybrandid = tableData.companybrandid;
var startdate = tableData.startdate;
var enddate = tableData.enddate;
var clientdb = tableData.clientdb;
var calltype = tableData.calltype;
var secondarycallval = tableData.secondarycallval;
var onSuccess = function (response) {
var d, t, dt, dtobj, obj;
var dtData = [];
$scope.repdata = [];
$scope.titles = [];
for (d in response.repdata) {
var dtArray = [];
obj = response.repdata[d];
$scope.repdata.push(obj);
//Create data packages for dataTables
for (dt in obj.data) {
dtobj = obj.data[dt];
dtArray.push(dtobj);
};
//Push data package to dtData array for injecting in dataTable
dtData.push(dtArray);
//Dynamically save field name for table headers
if (obj.ID == 0) {
var tlt = obj.data;
for (t in tlt) {
$scope.titles.push(t);
};
$scope.titles.sort();
};
};
//Pagination controls
$scope.totalItems = $scope.repdata.length;
$scope.currentPage = 1;
$scope.maxSize = 5;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
$scope.pageChanged = function() {
console.log('Page changed to: ' + $scope.currentPage);
};
$scope.bigTotalItems = 175;
$scope.bigCurrentPage = 1;
};
var onError = function (response) {
console.log("error");
console.log(data);
};
DashboardFactory.getDashboardReportData(dashboardreportid, companyid, companybrandid, startdate, enddate, clientdb, calltype, secondarycallval).then(onSuccess, onError);
},
templateUrl: "dashboard/drilldownTable.html",
}
}
(directive template) drilldownTable.html
<input type='text' data-ng-model='searchbox' placeholder='search rows'></input>
<div class="table-responsive">
<table id="drilldownTable" class="table table-bordered table-condensed">
<thead>
<th data-ng-repeat="title in titles">{{title}}</th>
</thead>
<tbody>
<!-- <tr data-ng-repeat='rd in repdata | filter:searchbox | limitTo:50'> -->
<tr data-ng-repeat='rd in repdata | filter:searchbox | limitTo:bigTotalItems'>
<td data-ng-repeat='val in rd.data track by $index'>{{val}}</td>
</tr>
</tbody>
</table>
</div>
<pagination total-items="totalItems" data-ng-model="currentPage" data-ng-change="pageChanged()"></pagination>
<pre>Page: {{currentPage}} / {{maxSize}}</pre>
All help is appreciated. Thanks.

Resources