AngularJS bootstrap collapsed init - javascript

I have the following html:
<div class="pull-right text-success m-t-sm">
<button class="btn btn-default" ng-init="isCollapsed = false" ng-click="isCollapsed = !isCollapsed" data-toggle="tooltip" data-placement="top" title="" data-original-title="Se kompetencer"><i class="fa {{isCollapsed == true ? 'fa-arrow-down': 'fa-arrow-up';}}" ng-click=""></i></button>
</div>
<div collapse="isCollapsed" class="panel-body collapse" style="height: 0px;">
<h4>Kompetencer</h4>
</div>
As you can see from this code i ng-init the isCollapsed variable to false.
However when i run my page I get the following view:
As you can see all of the boxes are visible? Can anyone tell me what might be going on here?
Note - I am not overwriting a variable or anything.
Maybe it has something to do with lazy load here is my config.router
.state('app.competence', {
url: '/Competence',
templateUrl: 'tpl/app_competence.html',
data: {
authorizedRoles: [USER_ROLES.lb, USER_ROLES.superadmin, USER_ROLES.subadmin]
},
resolve: {
deps: ['$ocLazyLoad',
function ($ocLazyLoad) {
return $ocLazyLoad.load(['ngGrid']).then(
function () {
return $ocLazyLoad.load(['js/controllers/competence/CompetenceController.js','js/controllers/competence/CompetenceUserController.js', 'js/controllers/competence/CompetenceTableController.js', 'js/controllers/headerController.js']);
}
);
}]
}
})
Html scope:
<tab ng-controller="CompetenceUserController as cuCtrl">
<tab-heading>
<i class="icon-users text-md text-muted wrapper-sm"></i>Brugere
</tab-heading>
<div class="wrapper-md">
<div class="row">
<div class="col-xs-12">
<div class="panel no-body">
<div class="panel-heading wrapper b-b b-light">
<input class="form-control" ng-model="search.$" placeholder="Søg">
<select class="form-control" ng-model="search.competence" ng-options="comp.name "></select>
</div>
<ul class="list-group">
<li class="list-group-item" ng-repeat="user in users | filter:search:strict">
<div class="media">
<span class="pull-left thumb-sm"><img
src="{{user.image_path || 'img/AdamProfil.png'}}" alt="..."
class="img-circle"></span>
<div class="pull-right text-success m-t-sm">
<button class="btn btn-default" ng-init="init(false)"
ng-click="isCollapsed = !isCollapsed" data-toggle="tooltip"
data-placement="top" title=""
data-original-title="Se kompetencer"><i
class="fa {{isCollapsed == true ? 'fa-arrow-down': 'fa-arrow-up';}}"
ng-click=""></i></button>
</div>
<div class="media-body">
<div><a href="">{{user.profile.firstname +' '+user.profile.lastname ||
user.username}}</a></div>
<small class="text-muted">{{user.title.name}}</small>
</div>
<div collapse="isCollapsed" class="panel-body collapse"
style="margin-top: 10px;">
<h4 class="h4">Kompetencer</h4>
<div class="table-responsive">
<table class="table table-striped b-t b-light">
<thead>
<th>Kompetence Navn</th>
<th>Niveau</th>
</thead>
<tbody>
<tr ng-repeat="comp in user.user_has_competences">
<td>{{comp.competence.name}}</td>
<td>{{comp.competence_level_id}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</tab>
My controller:
app.controller('CompetenceUserController', ['$http', '$scope', '$sessionStorage','competenceService', '$log', 'Session', 'api', function ($http, $scope, $sessionStorage, $log, Session, api, competenceService) {
$scope.init = function(value) {
$scope.isCollapsed = value;
};
$scope.competences = [];
competenceService.getRawList().then(function(response)
{
$scope.competences = response;
});
$scope.users = [];
$http.get(api.getUrl('userCompetence', null)).success(function (response) {
$scope.users = response;
});
}]);

It because you are initialising isCollapsed to false rather than true.

You are assigning value to isCollapsed to false which is not defined previously.ng-init="isCollapsed = false"
I prefer in this case to call a function and assign the value to variable.
<button class="btn btn-default" ng-init="init(false)" ng-click="isCollapsed = !isCollapsed" data-toggle="tooltip" data-placement="top" title="" data-original-title="Se kompetencer"><i class="fa {{isCollapsed == true ? 'fa-arrow-down': 'fa-arrow-up';}}" ng-click=""></i></button>
In controller
$scope.init = function(value) {
$scope.isCollapsed = value;
}
You can alsoe directly assign
$scope.isCollapsed = false;
in controller.

I don't think it has anything to do with the lazy loading, but rather that the isCollapsed isn't available in the scope you're referring it.
You can ensure it's available by wrapping it in an object (and maybe even declare your ng-init somewhere more up level).

Related

AngularJS application: unable to update $index

I am working on an app in AngularJS 1.6, using the Giphy.com api.
There is a Plunker HERE.
I iterate over an array of "giphys"coming from https://api.giphy.com/v1/gifs/trending?api_key=myApyKey and display them into Bootstrap 4 cards.
There is a view single giphy functionality. In the controller I have:
// Create controller for the "giphyApp" module
app.controller("giphyCtrl", ["$scope", "$http", "$filter", "$timeout", function($scope, $http, $filter, $timeout) {
var url = "https://api.giphy.com/v1/gifs/trending?api_key=PTZrBlrq8h2KUsRMeBuExZ5nHyn7dzS0&limit=120&rating=G";
$scope.giphyList = [];
$scope.search = "";
$scope.filterList = function() {
var oldList = $scope.giphyList || [];
$scope.giphyList = $filter('filter')($scope.giphys, $scope.search);
if (oldList.length != 0) {
$scope.pageNum = 1;
$scope.startAt = 0;
};
$scope.itemsCount = $scope.giphyList.length;
$scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);
};
$http.get(url)
.then(function(data) {
// giphy arary
$scope.giphys = data.data.data;
$scope.filterList();
console.log($scope.giphys);
// Paginate
$scope.pageNum = 1;
$scope.perPage = 24;
$scope.startAt = 0;
$scope.filterList();
$scope.currentPage = function(index) {
$("html, body").animate({
scrollTop: 0
}, 500);
$timeout( function(){
$scope.pageNum = index + 1;
$scope.startAt = index * $scope.perPage;
},0);
};
$scope.prevPage = function() {
if ($scope.pageNum > 1) {
$scope.pageNum = $scope.pageNum - 1;
$scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
}
};
$scope.nextPage = function() {
if ($scope.pageNum < $scope.pageMax) {
$scope.pageNum = $scope.pageNum + 1;
$scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
}
};
$scope.selectedIndex = null;
$scope.selectedGiphy = null;
$scope.fetchSinglegGiphy = function(giphy, index) {
console.log(index);
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
}
});
}]);
The Grid
<div class="row grid" ng-if="giphyList.length > 0">
<div data-ng-repeat="giphy in giphyList | limitTo : perPage : startAt"
class="col-xs-12 col-sm-6 col-lg-4 col-xl-3 d-flex mb-4">
<div class="giphy d-flex flex-column w-100">
<div class="thumbnail pb-2 text-center" data-toggle="modal"
data-target="#giphyModal"
ng-click="fetchSinglegGiphy(giphy, $index)">
<img ng-src="{{giphy.images.downsized.url}}" class="img-fluid">
</div>
<div class="text mt-auto">
<p class="m-0 meta">{{giphy.import_datetime | dateParse | date : "MMMM dd y" }}</p>
<p class="rating m-0">
<i class="fa fa-star" aria-hidden="true"></i> {{giphy.rating | capitalize}}
</p>
<ul class="list-unstyled mb-0 text-center">
<li ng-if="giphy.username != ''" class="text-muted">{{giphy.type | capitalize}} file uploaded by
<br><strong>{{giphy.username | capitalize }}</strong>
</li>
<li ng-if="giphy.username == ''" class="text-muted">{{giphy.type | capitalize}} file uploaded by
<br> <strong>Unknown</strong>
</li>
<li class="h6">{{giphy.title | titlecase }}</li>
</ul>
</div>
</div>
</div>
</div>
The Modal
<div class="modal fade" id="giphyModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title h-3">{{selectedGiphy.title | titlecase }}</h4>
<button type="button" class="close" data-dismiss="modal">
<span>×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-12">
<div class="image image text-center">
<img ng-src="{{selectedGiphy.images.original.url}}"
alt="{{selectedGiphy.title }}" class="img-fluid">
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<div class="text-muted">Image ID: {{selectedGiphy.id}}</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-success" data-dismiss="modal">
<i class="fa fa-times-circle"></i> Close
</button>
</div>
</div>
</div>
</div>
</div>
This part of the application works fine.
I had expected to be able to easily add a next and previous giphy to the modal above:
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphy(giphy, $index = $index - 1)" class="left">
<i class="fa fa-chevron-left"></i>
</a>
<a href="#" ng-click="fetchSinglegGiphy(giphy, $index = $index + 1)" class="right">
<i class="fa fa-chevron-right"></i>
</a>
</div>
To my surprise this does not work. When I click any one of the controls, the GIF file remains the same, wile all the text in the modal disappears.
Questions:
What is wrong with this approach?
Do you see a viable alternative?
index.html
<div class="modal fade" id="giphyModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="controls text-center">
<i class="fa fa-chevron-left"></i>
<i class="fa fa-chevron-right"></i>
</div>
<div class="modal-header">
<h4 class="modal-title h-3">
{{ selectedGiphy.title | capitalize }}
</h4>
<button type="button" class="close" data-dismiss="modal">
<span>×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-12">
<div class="image image text-center">
<img ng-src="{{ selectedGiphy.images.original.url }}" alt="{{ selectedGiphy.title }}" class="img-fluid" image-on-load ng-hide="modalImageLoading" />
<div class="spinner-border" ng-if="modalImageLoading"></div>
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<div class="text-muted">
Image ID: {{ selectedGiphy.id }}
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-success" data-dismiss="modal">
<i class="fa fa-times-circle"></i> Close
</button>
</div>
</div>
</div>
</div>
</div>
MODIFICATIONS:
<i class="fa fa-chevron-left"></i>
<i class="fa fa-chevron-right"></i>
fetchSinglegGiphyModal handles both previous and next Giphy based on the condition that acts on the argument prev or next value that we pass in the function.
I have also added the following code to introduce loader which comes with bootstrap to indicate that GIF image is being loaded in the background.
<div class="image image text-center">
<img ng-src="{{ selectedGiphy.images.original.url }}" alt="{{ selectedGiphy.title }}" class="img-fluid" image-on-load ng-hide="modalImageLoading" />
<div class="spinner-border" ng-if="modalImageLoading"></div>
</div>
app.js
$scope.modalImageLoading = false;
$scope.fetchSinglegGiphy = function (giphy, index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
$scope.modalImageLoading = true;
};
$scope.fetchSinglegGiphyModal = function (dir) {
let selectedGiphy = null;
if (dir === "prev") $scope.selectedIndex -= 1; // To load previous
else if (dir === "next") $scope.selectedIndex += 1; // To load next
selectedGiphy = $scope.giphyList[$scope.selectedIndex];
if (selectedGiphy) {
$scope.selectedGiphy = selectedGiphy;
$scope.modalImageLoading = true;
}
};
$scope.fetchSinglegGiphyModal acts on the condition we pass in the parameter and shows the corresponding Giphy data.
I have implemented a custom directive to show the image element and hide the loader when the image is downloaded. Here is the directive code:
app.directive('imageOnLoad', function () {
return {
restrict: 'A',
controller: 'giphyCtrl',
link: function (scope, element, attrs) {
element.bind('load', function () {
scope.$apply(function () {
scope.modalImageLoading = false;
});
});
}
}
});
Here is the modified plunker code.
Hope it helps!
When I click any one of the controls, the GIF file remains the same
Check to see if giphy equals what you expect:
$scope.fetchSinglegGiphy = function(giphy, index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
if ( giphy != $scope.giphyList[index] ) {
$scope.selectedGiphy = $scope.giphyList[index];
};
};
Update the selectedGiphy in the case that it is not.
You not only use $index outside of the ng-repeat block, but also you use giphy outside of that block, where it is not defined.
I assume you have $scope.giphyList defined in your controller. So all you have to do is to send the index.
$scope.selectedIndex = null;
$scope.selectedGiphy = null;
$scope.fetchSinglegGiphy = function(index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = $scope.giphyList[index];
}
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphy(selectedIndex-1)" class="left">
<i class="fa fa-chevron-left"></i>
</a>
<a href="#" ng-click="fetchSinglegGiphy(selectedIndex+1)" class="right">
<i class="fa fa-chevron-right"></i>
</a>
</div>
I hope this helps,
Cheers
Where you move the giphy to the modal, you should also send the $index (as you really did), so in the modal you know who your index is, regardless of $index.
<div class="controls text-center">
<i class="fa fa-chevron-left"></i>
<i class="fa fa-chevron-right"></i>
</div>

Pagination with JS how to implements

I want to implement a paging, using Jquery or angular in my application but I'm not sure how ... I'm getting the back end of it ..
my inforation is alredy filter by API i using this method
#RequestMapping( value = "/distritosPaginacao", params = { "page", "size" }, method = RequestMethod.GET)
public Page<Distritos> findPaginated( #RequestParam("page") int page, #RequestParam("size") int size) {
Page<Distritos> resultPage = distritosService.paginacao(page, size);
return resultPage;
}
and in my js i have this ...
app.controller("buscaDistritoController", function($scope, $http, $location) {
$scope.distritos = [];
$scope.distrito = {}; // binding com o form
carregarDistritos = function() {
token = localStorage.getItem("userToken");
var search = $location.search();
var page = search.page||0;
var size = search.size||15;
var sort = search.sort||'type,desc';
$http({
method: 'GET',
url: '/user/distritosPaginacao?page=' + page + '&size=' + size + '&sort=' + sort
}).then(function(response) {
$scope.distritos = response.data.content;
$scope.page = response.data.totalPages;
$scope.sort = sort;
}, function(response) {
console.log(response.data);
console.log(response.status);
});
};
});
my html
<div ng-controller="buscaDistritoController">
<div class="container">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3>Distritos</h3>
<br></br>
<button id="btnSalvar" type="button" data-toggle="modal" data-target="#modalAdicionarDistrito" class="btn btn-default ">Adicionar novo distrito</button>
<button id="btnImprimir" type="button" class="btn btn-default pull-right ">Imprimir</button>
<div >
<div class=" jPager">
<div class="input-group col-lg-3 col-md-3 col-sm-3 col-xs-12 pull-left">
<select class="form-control" data-pager-action='pagesize'>
<option value="5">Ver 5</option>
<option value="15">Ver 15</option>
<option value="20">Ver 20</option>
<option value="25">Ver 25</option>
<option value="50">Ver 50</option>
<option value="100">Ver 100</option>
</select>
</div>
<div class="input-group col-lg-6 col-md-6 col-sm-6 col-xs-12">
<span class="input-group-addon btn btn-primary" data-pager-action='first'><i class="fa fa-angle-left"></i> Primeira</span>
<span class="input-group-addon btn btn-primary" data-pager-action='previous'><i class="fa fa-angle-double-left"></i> Anterior</span>
<input type="text" class="form-control" data-pager-action='pagenum'>
<span class="input-group-addon btn btn-primary" data-pager-action='next'><i class="fa fa-angle-double-right"></i> Próxima</span>
<span class="input-group-addon btn btn-primary" data-pager-action='last'><i class="fa fa-angle-right"></i> Última</span>
</div>
</div>
</div>
<div>
<div class="panel-body">
<table id="idTabela" class="table">
<thead>
<tr>
<th>Id</th>
<th>Nome</th>
<th>Código DNE</th>
<th>Opções</th>
</tr>
</thead>
<tbody ng-repeat="dis in distritos ">
<tr>
<td>{{dis.idDistrito}}</td>
<td>{{dis.nome}}</td>
<td>{{dis.codigoDne}}</td>
<td>
<div class="btn-group">
<button id="opcoes" type="button" class="btn btn-danger vermDigifred btn-xs dropdown-toggle glyphicon glyphicon-pencil" data-toggle="dropdown"> </button>
<ul class="dropdown-menu" role="menu">
<li><a id="btnExcluirRegistro" ng-click="excluirDistritos(dis)"><span class="glyphicon glyphicon-trash"></span> Excluir registro</a></li>
<li> <a id="btnAlterarRegistro" data-toggle="modal" data-target="#modalAlterarDistrito" ng-click="alterarDistritos(dis)" ><span class="glyphicon glyphicon-edit"></span> Alterar registro</a></li>
</ul>
</div>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
I have no idea how to implement the next and return buttons and also the buttons see results by pages.
can anybody help me? I'm not very experienced.

Display data in many html's doesn't work using angular

I want to display data in HTML. First HTML disc-log.html looks like:
<div>
<h2>Discs</h2>
<jhi-alert></jhi-alert>
<div class="container-fluid">
<div class="row">
<div class="col-xs-4 no-padding-left">
<!--<button class="btn btn-primary" ui-sref="disc.new" >-->
<!--<span class="glyphicon glyphicon-plus"></span>-->
<!--<span >-->
<!--Create new Disc-->
<!--</span>-->
<!--</button>-->
</div>
</div>
</div>
<br/>
<div class="table-responsive">
<table class="jh-table table table-striped">
<thead>
<tr>
<!--<th><span>ID</span></th>-->
<th><span>Name</span></th>
<th><span>Connection</span></th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="disc in vm.discs track by disc.id">
<!--<td><a ui-sref="disc-detail({id:disc.id})">{{disc.id}}</a></td>-->
<td>{{disc.name}}</td>
<td>
<a ui-sref="connection-detail({id:disc.connection.id})">{{disc.connection.userHost}}</a>
</td>
<td class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit"
ui-sref="disc-detail({id:disc.id})"
class="btn btn-info btn-sm">
<span class="glyphicon glyphicon-eye-open"></span>
<span class="hidden-sm-down"></span>
</button>
<!--<button type="submit"-->
<!--ui-sref="disc.edit({id:disc.id})"-->
<!--class="btn btn-primary btn-sm">-->
<!--<span class="glyphicon glyphicon-pencil"></span>-->
<!--<span class="hidden-sm-down"></span>-->
<!--</button>-->
<button type="submit"
ui-sref="disc.delete({id:disc.id})"
class="btn btn-danger btn-sm">
<span class="glyphicon glyphicon-remove-circle"></span>
<span class="hidden-sm-down"></span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
After open this website, all data is displayed. But when I copied the table to another file, then the table is empty. Why? Should I add something in controllers or services?
Disc Log Controller:
(function() {
'use strict';
angular
.module('deviceManagerApp')
.controller('DiscLogController', DiscLogController);
DiscLogController.$inject = ['$scope', '$state', 'DiscLog'];
function DiscLogController ($scope, $state, DiscLog) {
var vm = this;
vm.discLogs = [];
loadAll();
function loadAll() {
DiscLog.query(function(result) {
vm.discLogs = result;
vm.searchQuery = null;
});
}
}
})();
Github repository:
https://github.com/Ice94/DeviceManager
In controller you are adding result in discLogs variable vm.discLogs = result; and in html you are using discs variable in ng-repeat <tr ng-repeat="disc in vm.discs track by disc.id">
That is why it does not display anything. Try to use same variable.
Note: "yourControllerName as vm" should be in your ng-controller attribute or controllerAs: 'vm' in your routes if using router

Programmatically toggle class on ng-repeat element

I'd like to programmatically toggle the class on a single ng-repeat element, but my code appears to set it to all of the elements, and there is no way to reset it. How can I fix this?
instant.html
<div class="item item-button-right" ng-repeat="service in businessServiceList | filter:services">
{{service.title}}
<div class="buttons" style="padding: 0px">
<button class="button {{buttonStyle}}" ng-click="changeButtonStyle()">
<i class="ion-android-done"></i>
</button>
<button class="button button-stable">
<i class="ion-android-more-horizontal"></i>
</button>
</div>
</div>
controller.js
.controller('BookCtrl', function($scope, ServicesData, $stateParams) {
$scope.businessServiceList = ServicesData.getBusinessServiceList ($stateParams.business);
$scope.buttonStyle="button-stable";
$scope.changeButtonStyle = function(){
$scope.buttonStyle="button-positive";
}
})
ng-class, you must use!
<div class="item item-button-right" ng-repeat="service in businessServiceList | filter:services">
{{service.title}}
<div class="buttons" style="padding: 0px">
<button class="button"
ng-class="{ 'button-positive': isButtonClicked }" ng-click="isButtonClicked = !isButtonClicked">
<i class="ion-android-done"></i>
</button>
<button class="button button-stable">
<i class="ion-android-more-horizontal"></i>
</button>
</div>
</div>
So, in the ng-class attribute you can just put all your classes that should be toggled by certain conditions.

Angular js load progress bars on opening modal

I have the following angular js htmlapp:
<!DOCTYPE html>
<html ng-app="StudentProgram">
<head>
<title>Student Program Management</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="css/badge.css"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">{{subcategory.name2}} - Add Courses</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-body">
<div class="panel col-md-5">
<div class="panel-body">
<p><font size="2">Required Credits : <span class="badge badge-machb pull-right">{{subcategory.required2}} </span></p>
<p>Completed Credits : <span class="badge badge-machb pull-right">{{subcategory.completed2}} </span></p>
<p>Planned Credits : <span class="badge badge-machb pull-right">{{subcategory.planned2}} </span></font></p>
</div>
</div>
<!--<input type="checkbox">{{child}}-->
<div class="panel progress col-md-7" style="height:121px;">
<div class="panel-body">
PROGRESS
<div class="progress">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="{{getPercentage()}}" aria-valuemin="0" aria-valuemax="100" ng-style="{width:(getPercentage()+'%')}">
{{getPercentage()}}%
</div>
</div>
</div>
</div>
<div class="panel panel-default" style="float:left;width:525px;">
<div class="panel-body" data-spy="scroll" data-target="#navbar-example" data-offset="0" style="height:200px;overflow:auto;position:relative;">
<table class="table table-hover checkbox">
<tr>
<th>Course</th>
<th>Credits</th>
</tr>
<tr ng-repeat="child in subcategory.children">
<td class="vcenter"><input type="checkbox" ng-checked="selectedCourses.indexOf(child) != -1" ng-click="toggleCheck(child)" value=""/>{{child}}</td>
<td class="vcenter">3</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="ok()">Save</button>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
</div>
</script>
</head>
<body>
<div class="container">
<div class="col-lg-9 col-md-9 col-sm-10">
<div class="" id="content">
<div class="pull-right">
<span class="glyphicon glyphicon-plus-sign"></span>
<span class="glyphicon glyphicon-file"></span>
<span class="glyphicon glyphicon-calendar"></span>
<span class="glyphicon glyphicon-search"></span>
</div>
<br/><br/>
<div ng-controller="mycontroller">
<div ng-repeat="detail in details">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><span class="badge badge-machb pull-right">{{detail.completed}} / {{detail.required}}</span>{{detail.name1}}</h3>
</div>
<div ng-repeat="subcategory in detail.subcategory1" class="panel-body">
<h4><strong>{{subcategory.name2}}
<button class="btn btn-default pull-right" ng-disabled="subcategory.required2 == subcategory.completed2" ng-click="open(subcategory)">Add Course <span class="glyphicon glyphicon-plus"></span></button>
</strong></h4>
<table class="table table-hover">
<tr>
<th>Course</th>
<th>Term</th>
<th>Credit</th>
<th>Grade</th>
</tr>
<tr ng-repeat="subcategory2 in subcategory.subcategory2">
<td>{{subcategory2.course}}</td>
<td>{{subcategory2.term}}</td>
<td>{{subcategory2.credit}}</td>
<td>{{subcategory2.grade}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="js/bootstrap.js"></script>
<script>
var app = angular.module('StudentProgram', ['ui.bootstrap']);
app.controller('mycontroller', function($scope, $modal, $log){
$scope.details=[
{name1:"TIER 1 - CORE FOUNDATIONS", completed:"9", required:"13", subcategory1:[
{name2:"Critical Reading and Writing",completed2:"6",required2:"6",planned2:"0",children:['ENGL-1301','HIST-1301'], subcategory2:[
{course:"HIST 1301",term:"Spring 2012",credit:"3.0",grade:"B"},
{course:"ENGL 1301",term:"Spring 2012",credit:"3.0",grade:"A"}
]},
{name2:"Speaking and Listening",completed2:"3",required2:"3",planned2:"0",children:['SPCH-1311','SPCH-1315','SPCH-1321','ARAB-1311','ARAB-1312','ARAB-1411','ARAB-1412','CHIN-1311','CHIN-1312','CHIN-1411','CHIN-1412','CZEC-1311','CZEC-1312','CZEC-1411','CZEC-1412','FREN-1311','FREN-1312','FREN-1411','FREN-1412','GERM-1311','GERM-1312','GERM-1411','GERM-1412','GREE-1311','GREE-1312','GREE-1411','GREE-1412','ITAL-1311','ITAL-1312','ITAL-1411','ITAL-1412','JAPN-1311','JAPN-1312','JAPN-1411','JAPN-1412','KORE-1311','KORE-1312','KORE-1411','KORE-1412','LATI-1311','LATI-1312','LATI-1411','LATI-1412','PORT-1311','PORT-1312','PORT-1411','PORT-1412','RUSS-1311','RUSS-1312','RUSS-1411','RUSS-1412','SGNL-1301','SGNL-1302','SPAN-1311','SPAN-1312','SPAN-1411','SPAN-1412','VIET-1311','VIET-1312','VIET-1411','VIET-1412'],
subcategory2:[
{course:"SPCH 1311",term:"Spring 2012",credit:"4.0",grade:"A"}
]},
{name2:"Quantitative Reasoning",completed2:"0",required2:"3",planned2:"0",children:['MATH-1314','MATH-1414','MATH-1316','MATH-1324','MATH-1325','MATH-1425','MATH-1332','MATH-1333','MATH-1348','MATH-1350','MATH-1351','MATH-2321','MATH-2421','MATH-2342','MATH-2442','MATH-2412','MATH-2413','MATH-2414','MATH-2415','MATH-2318','MATH-2418','MATH-2320','MATH-2420','MATH-2305'],
subcategory2:[
]},
{name2:"Wellness and The Human Experience",completed2:"0",required2:"1",planned2:"0",children:['ARTS-1311','ARTS-1312','ARTS-1313','ARTS-1316','ARTS-2313','ARTS-2316','ARTS-2326','ARTS-2333','ARTS-2336','ARTS-2341','ARTS-2346','ARTS-2348','ARTS-2356','ARTS-2366','BIOL-1322','BUSI-1307','COMM-1316','COMM-1318','DANC-1245','DANC-1341','DANC-1347','DANC-1351','DRAM-1322','DRAM-1330','DRAM-1351','MUEN-1122','MUEN-1131','MUEN-1132','MUEN-1133','MUEN-1134','MUEN-1135','MUEN-1136','MUEN-1137','MUEN-1151','MUEN-1152','MUEN-1153','MUEN-2123','MUEN-2141','MUSI-1116','MUSI-1181','MUSI-1183','MUSI-1192','MUSI-1263','MUSI-1301','PHED-1100','PHED-1101','PHED-1102','PHED-1104','PHED-1105','PHED-1106','PHED-1107','PHED-1108','PHED-1109','PHED-1110','PHED-1111','PHED-1112','PHED-1113','PHED-1114','PHED-1115','PHED-1116','PHED-1117','PHED-1118','PHED-1119','PHED-1120','PHED-1121','PHED-1122','PHED-1123','PHED-1124','PHED-1125','PHED-1126','PHED-1127','PHED-1128','PHED-1129','PHED-1164','PHED-1165','PHED-1251','PHED-1304','PHED-1306','PHED-1346','SOCI-2301','SOCI-2340','SPCH 2341'],
subcategory2:[
]}
]},
{name1:"TIER 2 - CORE DOMAINS", completed:"10", required:"26", subcategory1:[
{name2:"Qualitative Reasoning, Literacy and Research",completed2:"3",required2:"3",planned2:"0",children:['ENGL-1302'],
subcategory2:[
{course:"ENGL 1302",term:"Summer 2012",credit:"3.0",grade:"A"}
]},
{name2:"Self and Society",completed2:"3",required2:"9",planned2:"0",children:['HIST-1302','HIST-2301','HIST-2328','HIST-2381','GOVT-2305','ANTH-2302','ANTH-2346','ANTH-2351','COMM-1307','CRIJ-1301','CRIJ-1307','ECON-1301','ECON-2302','ECON-2311','GEOG-1302','GEOG-1303','GEOG-2312','GOVT-2304','GOVT-2311','HIST-2321','HIST-2322','HIST-2327','PSYC-2301','PSYC-2306','PSYC-2314','PSYC-2316','SOCI-1301','SOCI-1306','SOCI-2306','SOCI-2319','SOCI-2336','TECA-1303','TECA-1354'],
subcategory2:[
{course:"GOVT 2301",term:"Spring 2012",credit:"3.0",grade:"B"},
{course:"PSYC 2301",term:"Summer 2012",credit:"--",grade:"--"}
]},
{name2:"Humanity, Creativity and the Aesthetic Experience",completed2:"0",required2:"6",planned2:"0",children:['ARTS-1301','ARTS-1303','ARTS-1304','DANC-2303','DRAM-1310','DRAM-2361','DRAM-2366','HUMA-1311','HUMA-1315','MUSI-1306','MUSI-1308','MUSI-1309','MUSI-1310',
'CUST-2370','ENGL-2321','ENGL-2322','ENGL-2323','ENGL-2326','ENGL-2327','ENGL-2328','ENGL-2331','ENGL-2332','ENGL-2333','ENGL-2342','ENGL-2343','ENGL-2351','HUMA-1302','HUMA-1305','HUMA-2319','PHIL-1301','PHIL-1304','PHIL-1316','PHIL-1317','PHIL-2303','PHIL-2306','PHIL-2307','PHIL-2316','PHIL-2317','PHIL-2318','PHIL-2321','ARAB-2311','ARAB-2312','CHIN-2311','CHIN-2312','CZEC-2311','CZEC-2312','FREN-2311','FREN-2312','GERM-2311','GERM-2312','GREE-2311','GREE-2312','ITAL-2311','ITAL-2312','JAPN-2311','JAPN-2312','KORE-2311','KORE-2312','LATI-2311','LATI-2312','PORT-2311','PORT-2312','RUSS-2311','RUSS-2312','SPAN-2311','PAN-2312','SPAN-2321','SPAN-2322','SPAN-2323','SPAN-2324','VIET-2311','VIET-2312'],
subcategory2:[
]},
{name2:"Scientific Discovery and Sustainability",completed2:"4",required2:"8",planned2:"0",children:['ANTH-2401','BIOL-1406','BIOL-1407','BIOL-1408','BIOL-1409','BIOL-1411','BIOL-2401','BIOL-2402','BIOL-2406','BIOL-2416','BIOL-2420','BIOL-2421','CHEM-1405','CHEM-1406','CHEM-1407','CHEM-1411','CHEM-1412','CHEM-2423','CHEM-2425','ENVR-1401','ENVR-1402','GEOL-1401','GEOL-1402','GEOL-1403','GEOL-1404','GEOL-1405','GEOL-1445','GEOL-1447','PHYS-1401','PHYS-1402','PHYS-1403','PHYS-1404','PHYS-1405','PHYS-1407','PHYS-1415','PHYS-1417','PHYS-2425','PHYS-2426'],
subcategory2:[
{course:"BIOL 1406",term:"Spring 2012",credit:"4.0",grade:"B"},
{course:"BIOL 1407",term:"Summer 2012",credit:"--",grade:"--"}
]}
]}
];
$scope.open = function (subcat) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
detail: function() {
return subcat;
}
}
});
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, detail) {
$scope.subcategory = detail;
$scope.selectedCourses= [];
$scope.subcategory.planned2 = parseInt($scope.subcategory.planned2,10);
$scope.subcategory.completed2 = parseInt($scope.subcategory.completed2,10);
$scope.subcategory.required2 = parseInt($scope.subcategory.required2,10);
angular.forEach(detail.subcategory2, function(item) {
$scope.selectedCourses.push(item.course);
});
$scope.toggleCheck = function (course) {
if (($scope.selectedCourses.indexOf(course) === -1) && ($scope.subcategory.planned2 + $scope.subcategory.completed2 < $scope.subcategory.required2)) {
$scope.selectedCourses.push(course);
$scope.subcategory.planned2 += 3;
if (($scope.subcategory.planned2 + $scope.subcategory.completed2) == $scope.subcategory.required2) {
alert('Requirement met');
}
} else {
$scope.selectedCourses.splice($scope.selectedCourses.indexOf(course), 1);
$scope.subcategory.planned2 -= 3;
}
$scope.getPercentage = function () {
return (($scope.subcategory.planned2+$scope.subcategory.completed2)/($scope.subcategory.required2)*100).toFixed(2);
}
};
$scope.ok = function () {
$scope.subcategory.subcategory2 = [];
for(var i = 0; i < $scope.selectedCourses.length; i++){
$scope.subcategory.subcategory2.push({course: $scope.selectedCourses[i], term:"--",credit:"--",grade:"--"});
}
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
</script>
</div>
</body>
</html>
When we click on the add courses button(for example in the self and society section), it opens a modal that has a progress bar to the right. The progress bar changes once we press on some course from the list below it. But i want the progress bar to load along with the modal ie. in the self and society section, the progress bar already has a value of 33.3% but it does not load that until we trigger a course. How do i do it?
Please help
You accidentally defined the getPercentage function inside the toggleCheck function. You need to define it outside toggleCheck, and then call it at the end of toggleCheck:
$scope.getPercentage = function () {
return (($scope.subcategory.planned2+$scope.subcategory.completed2)/($scope.subcategory.required2)*100).toFixed(2);
}
$scope.toggleCheck = function (course) {
if (($scope.selectedCourses.indexOf(course) === -1) && ($scope.subcategory.planned2 + $scope.subcategory.completed2 < $scope.subcategory.required2)) {
$scope.selectedCourses.push(course);
$scope.subcategory.planned2 += 3;
if (($scope.subcategory.planned2 + $scope.subcategory.completed2) == $scope.subcategory.required2) {
alert('Requirement met');
}
} else {
$scope.selectedCourses.splice($scope.selectedCourses.indexOf(course), 1);
$scope.subcategory.planned2 -= 3;
}
$scope.getPercentage();
};

Categories