Alright, this is pretty straight forward: I need to hide one <li> when the percentage of work done is under 10%.
This is the element in my twig file and I want to hide that first li tab and make the second active when the first is hidden:
<nav ng-controller="OverviewController">
<ul class="nav nav-tabs" role="tablist">
<li class="active"></li>
<li></li>
<li></li>
<li ng-if="announcements.length > 0">
</li>
</ul>
</nav>
And there's a variable named "percentage" in my ProjectManager.php that will be the trigger to hide or show if under or above 10%.
Basically, want something like this: if(percentage < 10%) { ng-hide }
EDIT:
OverviewController
define([], function() {
OverviewController.$inject = ['$scope', '$timeout', 'AnnouncementFactory', 'CommentFactory'];
/**
* Overview controller.
*/
function OverviewController($scope, $timeout, AnnouncementFactory, CommentFactory) {
$scope.announcementNotification = AnnouncementFactory.hasUnreadAnnouncements();
$scope.announcements = AnnouncementFactory.getAnnouncements();
$scope.commentNotification = CommentFactory.hasUnreadComments();
// Cached this page date.
var date = new Date().toISOString();
/**
* Set all announcements as read.
*/
$scope.setAllAnnouncementsAsRead = function() {
if (!$scope.announcementNotification) {
return;
}
AnnouncementFactory.setAllAnnouncementsAsRead(date).then(function() {
$scope.announcementNotification = false;
});
};
/**
* Set all comments as read.
*/
$scope.setAllCommentsAsRead = function() {
if (!$scope.commentNotification) {
return;
}
CommentFactory.setAllCommentsAsRead().then(function() {
$scope.commentNotification = false;
});
};
}
return OverviewController;
});
ProjectManager.php
/**
* Update percentage.
*/
public function updatePercentage($project)
{
$done = 0;
$total = 0;
list($pages, $status) = $this->participationManager->getPagesInPath($project);
foreach ($pages as $pageData) {
$widgetsDoneIds = array_keys($status[$pageData['module']]['pages'][$pageData['page']->getId()]['widgetsDone']);
foreach ($pageData['widgets'] as $widget) {
if (in_array($widget->getId(), $widgetsDoneIds)) {
$done++;
}
}
$total += count($pageData['widgets']);
}
$percentage = $total !== 0 ? ($done / $total) * 100 : 0;
$project->setPercentage($percentage);
$this->entityManager->persist($project);
$this->entityManager->flush($project);
}
Related
I am trying to be able to filter multiple columns on multiple values. So far I can filter multiple columns on 1 single value:
myApp.controller('MyCtrl', ['$scope', '$http', function($scope, $http) {
$scope.empList = [];
$http.get('getAllOnline.php')
.success(function(data) {
$scope.empList = data;
});
$scope.column1List = [];
$http.get('getAllSomething.php', {
params: {
wuk: "column1"
}
})
.success(function(data) {
$scope.column1 = data;
});
$scope.column2List = [];
$http.get('getAllSomething.php', {
params: {
wuk: "column2"
}
})
.success(function(data) {
$scope.column2 = data;
});
$scope.column3List = [];
$http.get('getAllSomething.php', {
params: {
wuk: "column3"
}
})
.success(function(data) {
$scope.column3 = data;
});
$scope.setColumn1Value = function(val) {
if ($scope.zelectedColumn1 == val) {
$scope.zelectedColumn1 = undefined;
} else {
$scope.zelectedColumn1 = val;
}
}
$scope.setColumn2Value = function(val) {
if ($scope.zelectedColumn2 == val) {
$scope.zelectedColumn2 = undefined;
} else {
$scope.zelectedColumn2 = val;
}
}
$scope.setColumn3Value = function(val) {
if ($scope.zelectedColumn3 == val) {
$scope.zelectedColumn3 = undefined;
} else {
$scope.zelectedColumn3 = val;
}
}
Then i use this to set my single value filters:
<ul id="Column1" class="collapse">
<li ng-repeat="emp in empList | unique:'Column1'">
<a ng-click="setColumn1Value(emp.Column1);" ng-class="{selected: emp.Column1 === zelectedColumn1}">
<div ng-repeat="someone in Column1List | filter:{Column1_id:emp.Column1}">
{{someone.value}}
</div>
</a>
</li>
</ul>
This works perfect! But now I want to be able to filter on multiple values in 1 column. So I changed my setter functions to:
$scope.zelectedColumn1=[];
$scope.setColumn1Value = function(val) {
var found = jQuery.inArray(val, $scope.zelectedColumn1);
if (found >= 0) {
// Element was found, remove it.
$scope.zelectedColumn1.splice(found, 1);
} else {
// Element was not found, add it.
$scope.zelectedColumn1.push(val);
}
console.log($scope.zelectedColumn1);
}
So now I add or remove indexes to an array instead of storing a single value. This also works, but how do I filter my columns on the contents of an array instead of on a single value as I do now:
<div class='row'>
<div class='col-lg-2 col-md-3 col-sm-6' ng-repeat="emp in empList | filter:{column1:zelectedColumn1,column2:zelectedColumn2,column3:zelectedColumn3} as res">
{{emp.column1}}
{{emp.column2}} <br>
{{emp.column3}} <br>
</div>
</div>
I have been struggling with this al day and hope someone can help me out here!
I'm learning AngularJS following the good Pro AngularJS written by Adam Freeman.
I'm stuck on ng-repeat pagination using filters. I know there are bootstrap ui directives for Angular, but i'm following this book in order to learn how angular works.
My code:
<section class="row-fluid" ng-controller="GetAjax">
<div class="col-md-12">
<h2>Repater Caricato in Ajax</h2>
</div>
<div class="row-fluid">
<div class="col-md-6" style="max-height: 350px; overflow-y: auto" ng-controller="PagedData">
<ul class="list-group">
<li class="list-group-item" ng-repeat="item in data.visitors | filter:query | range:selectedPage:pageSize">
<b>{{item.id}}.</b> {{item.first_name}} {{item.last_name}} | <small><i>{{item.email}} - {{item.country}} {{item.ip_address}}</i></small>
</li>
</ul>
<ul class="pagination">
<li ng-repeat="page in data.visitors | pageCount:pageSize"
ng-click="selectPage($index + 1)"
ng-class="pagerClass($index + 1)">
<a>{{$index + 1}}</a>
</li>
</ul>
</div>
</div>
</section>
Angular filters
angular.module("customFilters")
/******* Filters per la paginazione dei dati ******************/
//Genera il range di dati in base alla page size
.filter("range", function ($filter) {
return function (data, page, size) {
if (angular.isArray(data) && angular.isNumber(page) && angular.isNumber(size)) {
var start_index = (page - 1) * size;
console.log(data.length);
if (data.length < start_index) {
return [];
} else {
return $filter("limitTo")(data.splice(start_index), size);
}
} else {
return data;
}
}
})
//Calcola il numero di pagine
.filter("pageCount", function () {
return function (data, size) {
if (angular.isArray(data))
{
var result = [];
for (var i = 0; i < Math.ceil(data.length / size) ; i++) {
result.push(i);
}
return result;
}
else
{
return data;
}
}
});
Angular Controller
.controller("GetAjax", function($scope, $http){
$http.get('data/visitors.json').success(function(data) {
$scope.data = {visitors : data};
});
})
.constant("activeClass", "active")
.constant("perPage", 30)
.controller("PagedData", function($scope, $filter, activeClass, perPage){
$scope.selectedPage = 1;
$scope.pageSize = perPage;
console.log("page"+ $scope.selectedPage);
$scope.selectPage = function (newIndex) {
$scope.selectedPage = newIndex;
console.log( {idx: newIndex});
}
$scope.pagerClass = function (index) {
return (index == $scope.selectedPage) ? activeClass : "";
}
});
The result is that after 3 range filter invocations during the page render, the data array looses all the data.
Strange is that using the example from the book this code works perfectly.
Please, help me to know my error :D
splice function overwrites array
if you have an array
a = [1,2,3,4];
a.splice(2,1);
// a = [1,2,4]
results is a = [1,2,4]
use slice instead
I got this error in my project. Actually, i have implemented pagination using filters in angular Js, while loading the table with pagination and also showing error in the $scope.$apply() which is in the MainController.
there are two errors in the console,
one is "Error: 10 $digest() iterations reached. Aborting!"
and the other: "Uncaught Error: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function (context) {\n for(var i = 0, ii = length, part; i...]]"
and they seem to go together. And paginate() in filter is repetitively calling many times.
How to fix it? Any help would be appreciated.
Following is the filter.js used for pagination
var filters = angular.module('OptimaQuote.filters', []);
filters.filter('filterDependant', function () {
return function (input, dependant) {
var out = [];
if (!jQuery.isEmptyObject(input) && input != "undefined" && input && input.length) {
for (var i = 0; i < input.length; i++) {
if (input[i].Dependant == dependant){
out.push(input[i]);
}
}
}
return out;
};
});
filters.filter('paginate', function() {
return function(input, currentPage,rowsPerPage) {
if (!input) {
return input;
}
return input;
}
});
filters.filter('getPaginator', function() {
return function(input, totolRowCount,rowsPerPage,paginatorSize,currentPage) {
var pageList = [];
var pages = [];
var noOfPages = parseInt(totolRowCount) / rowsPerPage;
function makePage(number, text) {
return {
number: number,
text: text,
};
}
var startPage = 1;
var endPage = noOfPages;
if(noOfPages!= null && noOfPages!= "undefined"){
if(paginatorSize < noOfPages){
startPage = ((Math.ceil(currentPage / paginatorSize) - 1) * paginatorSize) + 1;
endPage = Math.min(startPage + paginatorSize - 1, noOfPages);
}
}
// Add page number links
for (var number = startPage; number <= endPage; number++) {
var page = makePage(number, number);
pages.push(page);
}
// Add links to move between page sets
if ( paginatorSize < noOfPages ) {
if ( startPage > 1 ) {
var previousPageSet = makePage(startPage - 1, '...');
pages.unshift(previousPageSet);
}
if ( endPage < noOfPages ) {
var nextPageSet = makePage(endPage + 1, '...');
pages.push(nextPageSet);
}
}
return pages;
}
});
filters.filter('getEndPage', function() {
return function(input, totolRowCount, rowsPerPage) {
totalPages = [];
function makePage(number, text) {
return {
number: number,
text: text,
};
}
var noOfPages = parseInt(totolRowCount) / rowsPerPage;
var temp = makePage(noOfPages,noOfPages);
totalPages.push(temp);
return totalPages;
}
});
Following is the template used for implementing pagination by calling filters
<tfoot>
<tr>
<td colspan="{{this.paginatorColSpan}}">
<div>
<ul class="paginate">
<li><a ng-class="" ng-click="{{this.firstPageClick}}">First</a></li>
<li><a ng-class="{firstPage:{{this.currentPageNumber}}+1==1}" ng-click="{{this.prevClick}}">Previous</a></li>
<li ng-repeat="value in pageList|getPaginator:{{this.totalRowCount}}:{{this.pageSize}}:{{this.paginatorSize}}:{{this.currentPageNumber}}+1">
<a ng-class="{active: value.number=={{this.currentPageNumber}}+1}" ng-click="{{this.pageClick}}">[[value.text]]</a>
</li>
<li ng-repeat="value in pageList|getEndPage:{{this.totalRowCount}}:{{this.pageSize}}">
<a ng-class="{firstPage:{{this.currentPageNumber}}+1==value.number}" ng-click="{{this.nextClick}}">Next</a></li>
<li ng-repeat="value in pageList|getEndPage:{{this.totalRowCount}}:{{this.pageSize}}">
<a ng-class="" ng-click="{{this.pageClick}}">Last</a></li>
</ul>
</div>
</td>
</tr>
</tfoot>
Try
{firstPage:((currentPageNumber+1)==1)}
instead of
{firstPage:{{this.currentPageNumber}}+1==1}
Also anywhere else you have done {{}}, I see totalRowCount and currentPageNumber and pageSize and ngClick.
Can you create a jsFiddle of your issue? It seems you are using angular incorrectly.
Before I fixed this issue, it was like this:
{
field : 'appId',
cellTemplate : 'EditView',
displayName : 'operation'
}
After I fixed this issue it was like this:
{
field : 'appId',
cellTemplate : 'EditView',
displayName : 'operation'
}
If you want to use <a></a> in this cellTemplate, you can use . It worked for me!
I have an ngClick directive on elements that are also bound to $swipe. The ngClick doesn't fire (it was firing before the $swipe was added).
I'm using jQuery mobile combined with AngularJS.
Interestingly, my diagnostics show a swipe event with start and end the same - seems to contradict the minimum swipe distance, but perhaps the cancel function is being called. Possibly I could use the cancel function to find out where the click occurred but I feel I shouldn't have to do that.
The site is viewable at http://skimobile.cbdweb.net
HTML
<div id="matrix" data-role="page" ng-controller="matrixCtrl" ng-init="init()">
<div data-role="header">
<?php echo CHtml::encode($this->configs['SITENAME']); ?> Bookings
</div>
<div data-role="content">
<div class="lodgename noborder"> </div>
<div class="oneday onemonth" ng-repeat="m in months" ng-style="callMonthstyle(m)" ng-class="$last ? 'lastcol' : ''" on-finish-days>
{{monthNames[m.month]}} {{m.year}}
</div>
<br clear="both" />
<div class="lodgename noborder"> </div>
<div class="oneday" ng-style="callDaystyle()" ng-class="$last ? 'lastcol' : ''" ng-repeat="d in dates">
{{d.getDate()}}
</div>
<br clear="both" />
<div ng-repeat="lodge in data.lodges">
<div class="lodgename" ng-class="$last ? 'lastrow' : ''">{{lodge.lodgetitle}}</div>
<div class="oneday" ng-style="callDaystyle()" ng-class="($last ? 'lastcol' : '') + ' ' + ($parent.$last ? 'lastrow' : '')" ng-repeat="d in dates" ng-click="showDate(lodge, d)">
</div>
<br clear="both" />
</div>
<div ng-show="data.debug" style="margin-top: 20px;"
<ul>
<li>
move = {{swipe.move}}
</li>
<li>
start = {{swipe.start}}
</li>
<li>
end = {{swipe.end}}
</li>
<li>
scope.startDay = {{startDay}}
</li>
<li>
daysMoved = {{swipe.daysMoved}}
</li>
<li>
daysFinished = {{nDaysFinished}}
</li>
</ul>
</div>
<ul>
<?php foreach(Yii::app()->params['lodges'] as $lodgecode=>$lodge) {
echo "<li>" . $lodgecode . " = " . $lodge['lodgetitle'] . "</li>";
$lci = $this->lodgeconfigs[$lodgecode]['PREFIX_BOOKING_ID'];
echo "<LI>" . $lci . "</li>";
} ?>
</ul>
</div>
</div>
Javascript:
/* NG services */
var matrix = angular.module('Skimobile', ['ngTouch']);
matrix.factory('dayswidth', ['writeDays', function(){ // gets called on window change width
return function(scope, ww) {
var lodgename = $('.lodgename').first().width() + 4; // 4 = padding in lodgename class
var padding = 60 + lodgename;
var oldDisplayDays = scope.displayDays;
scope.displayDays = Math.min(28, (ww - padding)/scope.mindaywidth); // show at most 28 days, fewer if needed to maintain minimum width
scope.dayWidth = Math.floor( (ww-padding) / scope.displayDays );
if(oldDisplayDays!=scope.displayDays) { // avoid changing scope.dates as this will cause infinite recursion in the $digest on ng-repeat d in dates
scope.callWriteDays();
}
};
}]);
matrix.factory('writeDays', function() {
return function(scope) {
var d = new Date();
d.setTime(scope.startDay.getTime());
scope.dates = []; // repeat on this to draw days
scope.months = []; // repeat on this to draw months
var yearShown = false; // only show year once, when the month is long enough
var m = d.getMonth();
var daysLeft = 0; // days shown belonging to each month
for(i=0; i<scope.displayDays; i++) {
scope.dates.push(new Date(d.getTime()));
var oldd = new Date(d.getTime());
d.setDate(d.getDate()+1);
daysLeft++;
var newm = d.getMonth();
if(newm!=m) { // finished a month, display it
var newMonthObj = {month:m, days:daysLeft};
if(!yearShown && daysLeft*scope.dayWidth-1-4>3*scope.mindaywidth) {
newMonthObj.year = oldd.getFullYear();
yearShown = true;
} else {
newMonthObj.year = '';
}
scope.months.push(newMonthObj);
m = newm;
daysLeft = 0;
}
}
if(daysLeft>0) { // final month
newMonthObj = {month:m, days:daysLeft};
newMonthObj.year = yearShown ? '' : oldd.getFullYear();
scope.months.push(newMonthObj);
}
}
});
matrix.factory('daystyle', function(){
return function(scope) {
return {
'width': (scope.dayWidth-1) + 'px'
}; // -1 allows for border
}
});
matrix.factory('monthstyle', function(){
return function(scope, m) {
var days = m.days;
return {
'width': (scope.dayWidth*days-1-4) + 'px'
} // 1 for border, 4 for padding-left
}
});
matrix.directive('onFinishDays', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if(scope.$last === true) { // without this it gets called once per visible month!
$timeout(function() {
scope.$emit('daysFinished');
})
}
}
}
});
/* NG controllers */
function matrixCtrl($scope, dayswidth, writeDays, daystyle, monthstyle, $swipe) {
$scope.callDayswidth = function(w){
dayswidth($scope, w);
};
$scope.callDaystyle = function() {
return daystyle($scope);
}
$scope.callMonthstyle = function(m) {
return monthstyle($scope, m);
}
$scope.callWriteDays = function() {
return writeDays($scope);
}
$scope.data = _main; // passed via Yii layout file
$scope.mindaywidth = 30;
$scope.monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var d = new Date(); // initially the matrix starts from today
$scope.startDay = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
var w = $(window);
$scope.getWindowDimensions = function() {
return {'h': w.height(), 'w': w.width()};
};
$scope.$watch($scope.getWindowDimensions, function(newValue, oldValue){
$scope.callDayswidth(newValue.w);
}, true);
w.bind('resize', function() {
$scope.$apply();
})
$scope.showDate = function(lodge, d){
alert(lodge.lodgetitle + ' ' + d.getDate());
}
$scope.swipe = {};
$scope.nDaysFinished = 0;
$scope.$on('daysFinished', function(event) {
$scope.nDaysFinished++;
$swipe.bind($('.oneday'), {
end:function(loc){
$scope.swipe.end = loc.x;
$scope.swipe.daysMoved = Math.floor((loc.x - $scope.swipe.start) / $scope.dayWidth);
$scope.startDay.setTime($scope.startDay.getTime() - $scope.swipe.daysMoved*24*60*60*1000); // compute new start day at end of drag;
$scope.callWriteDays();
$scope.$apply();
}
})
});
}
i am new to angularjs. i have created list using ng-repeat. just i want to hide the selected list element from list:
html code which i prefered:
<ul>
<li ng-repeat="profile in profileMenu">
<div class="hederMenu" ng-hide="configureDisplay" ng-click="setProfile(profile.name)">
<a class="anchor" style="width:100%" >{{profile.name}}</a>
</div>
</li>
</ul>
here is controller code
$scope.profileMenu = [{
name : "My Profile"
}, {
name : "Configure"
}, {
name : "Logout"
}
];
$scope.profile = "";
$scope.setProfile = function (test) {
$scope.profileSelected = test;
if ($scope.profileSelected == "Configure") {
$location.path("/home/configure"); // if user click configure then this element will hide
$scope.configureDisplay = true;
}
if ($scope.profileSelected == "My Profile") {
$location.path("/home/dashboard");
$scope.configureDisplay = false;
}
if ($scope.profileSelected == "Logout") {
window.location.assign("http://mitesh.demoilab.pune/")
}
return $scope.profileSelected = test;
}
You have to set the configureDisplay property on the actual "Configure" profile item. Not sure what you're doing with the selection list, but I assume you would want the "Configure" item visible again when selecting another item. Therefore you'll also have to reset the "Configure" item back to false when selecting another item.
I modified your example a bit. Notice instead of passing the profile.name on setProfile, i'm passing the profile object. This just simplifies the interaction.
<ul>
<li ng-repeat="profile in profileMenu">
<div class="hederMenu" ng-hide="profile.configureDisplay" ng-click="setProfile(profile)">
<a class="anchor" style="width:100%" >{{profile.name}}</a>
</div>
</li>
</ul>
$scope.setProfile = function (selectedProfile) {
//reset the items
for (var i in $scope.profileMenu) {
$scope.profileMenu[i].configureDisplay = false;
}
if (selectedProfile.name == "Configure") {
$location.path("/home/configure"); // if user click configure then this element will hide
selectedProfile.configureDisplay = true;
}
if (selectedProfile.name == "My Profile") {
$location.path("/home/dashboard");
}
if (selectedProfile.name == "Logout") {
window.location.assign("http://mitesh.demoilab.pune/")
}
return true;
}
you need to do few changes ,
<li ng-repeat="profile in profileMenu">
<div class="hederMenu" ng-hide="profile.configureDisplay" ng-click="setProfile(profile)">
<a class="anchor" style="width:100%" >{{profile.name}}</a>
</div>
</li>
And in controler,
$scope.setProfile = function (test) {
$scope.profileSelected = test.name;
if ($scope.profileSelected == "Configure") {
$location.path("/home/configure");
test.configureDisplay = true;
}
if ($scope.profileSelected == "My Profile") {
$location.path("/home/dashboard");
test.configureDisplay = false;
}
if ($scope.profileSelected == "Logout") {
window.location.assign("http://mitesh.demoilab.pune/")
}
return test;
}