i want hide only specific list element - angularjs

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;
}

Related

Ng-show not updating after value changed

JS
$scope.getDiffs = function () {
return Module.getDiffs($scope.item.account_id, $scope.item.year)
.then(function (res) {
angular.forEach(res, function (v) {
angular.forEach($scope.months, function (m) {
if (m.month == v.month) {
m.diff = v.diff != 0;
}
});
});
});
};
Blade
<ul class="nav nav-tabs mbtm-10">
<li role="presentation" ng-repeat="m in months"
ng-class="{active: item.month == m.month}">
<a href="" ng-click="item.month = m.month;fetchTrx()">
#{{m.text}}
<i ng-show="m.diff != null" class="fa fa-circle"
ng-class="{'text-success': !m.diff, 'text-danger': m.diff}">
</i>
</a>
</li>
</ul>
My code will show the green circle on the taps interface if the value is m.diff != null. However, It will not updating if value is m.diff == null. Once the tap is show the green circle then it show forever green circle no matter in what value.
Use angular.copy:
$scope.getDiffs = function () {
return Module.getDiffs($scope.item.account_id, $scope.item.year)
.then(function (res) {
angular.forEach(res, function (v) {
angular.forEach($scope.months, function (m,i,arr) {
if (m.month == v.month) {
m.diff = v.diff != 0;
arr[i] = angular.copy(m);
}
});
});
});
};

Hide element with a condition

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);
}

Vue.js re-rendering sorted array

I have a basic sorting UI to sort comments based on some values:
Part of CommentsSection template:
<div v-if="numComments" class="tabs d-flex">
<span class="text-muted">Sort by:</span>
<div class="tab" :class="{active: tab === 0}" #click="sortComments(0)">Rating</div>
<div class="tab" :class="{active: tab === 1}" #click="sortComments(1)">Newest</div>
<div class="tab" :class="{active: tab === 2}" #click="sortComments(2)">Oldest</div>
</div>
<ul v-if="numComments" class="comments-list">
<li is="comment" #delete="numComments -= 1" v-for="comment in sortedComments" :data="comment"></li>
</ul>
CommentsSection:
export default {
name: 'comments-section',
components: {
CommentForm,
Comment
},
props: ['comments', 'submissionId'],
data() {
return {
tab: 0,
numComments: this.comments.length,
sortedComments: this.comments.slice()
}
},
created() {
this.sortComments();
},
methods: {
sortComments(type = 0) {
this.tab = type;
if (type === 0) {
this.sortedComments.sort((a, b) => b.rating - a.rating);
} else if (type === 1) {
this.sortedComments.sort((a, b) => moment(b.create_time).unix() - moment(a.create_time).unix());
} else {
this.sortedComments.sort((a, b) => moment(a.create_time).unix() - moment(b.create_time).unix());
}
},
...
}
...
}
CommentSingle (component being rendered in list):
export default {
name: 'comment-single',
props: ['data'],
data() {
return {
agree: this.data.rated === 1,
disagree: this.data.rated === -1
}
}
...
}
The CommentSingle template is not being re-rendered so agree and disagree don't update. But the actual list does render the proper sort when clicking each sorting tab, but each comment in the list has the wrong agree and disagree (the original sorted array's values). Any idea how to fix this?
Solved by binding a key to the rendered component:
<li is="comment" #delete="numComments -= 1" v-for="comment in sortedComments" :key="comment.id" :data="comment"></li>
Reference: https://v2.vuejs.org/v2/guide/list.html#key

check a checkbox by clicking a link in angularJs

I have the folowing code :
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item,checkBoxModel)">
<input class="align"
ng-click="checkItem(item,checkBoxModel)"
type="checkbox" ng-checked="master"
ng-model="checkboxModel"/>
{{ item.title }}
</a>
</li>
in my controller i have checkItem function:
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.master=true;
$scope.checkBoxModel = false;*
} else {
....
$scope.master = false;
$scope.checkBoxModel = true;
}
}
The problem is that when I click on a link all of the checkboxes are checked. I just want the checkbox associated to the link to be checked.
Instead of setting a value master on the controllers $scope object, set it on the actual item that you pass in, and set it's ng-checked="item.master" and it's ng-model="item.checkBoxModel"
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
item.master=true;
item.checkBoxModel = false;
} else {
....
item.master = false;
item.checkBoxModel = true;
}
}
Change your app logic. You have to declare a variable for each item. But as i see, you have one for all in the global $scope named master. The master should have been declared for each item to specify the state of the option box. Then your problem will be solved.
Something like this:
app.js
$scope.items = [
{
name: 'example',
master: false,
checkboxModel: false
},
{
name: 'example',
master: false,
checkboxModel: false
}
];
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.items[item].master = true;
...
} else {
....
$scope.items[item].master = false;
...
}
}
index.html
<input class="align"
ng-click="checkItem(item, checkBoxModel)"
type="checkbox" ng-checked="item.master"
ng-model="item.checkboxModel"/>
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item)">
<input class="align"
ng-click="checkItem(item)"
type="checkbox" ng-checked="item.checked"
/>
{{ item.title }}
</a>
in my controller i change the value of item.checked

AngularFire add in reverse order

I need to add objects to Firebase in reverse order. Or reverse data when goes data binding. Or sort objects by time of create.
var ref = new Firebase("https://[url].firebaseio.com/");
$scope.messages = $firebase(ref);
$scope.addMessage = function(e) {
$scope.messages.$add({title: $scope.title, body: $scope.msg, time: $scope.getDate() });
}
<div class="well span3 pull-left note" ng-repeat="(key, msg) in messages">
<button type='button' class='close' ng-click="messages.$remove(key)">×</button>
<b>{{msg.time| date: 'medium'}}</b>
<span>{{msg.title}}</span>
<span>{{msg.body}}</span>
<button ng-click="changeMessage(key)" class="btn btn-mini pull-right"><i class="icon-pencil"></i></button>
</div>
I try to use OrderBy atribute for ng-repeat but this is not easy because in messages are stored objects.
Check out the chat example in angularFire-seed. It uses a custom reverse filter
The reverse filter looks like so:
app.filter('reverse', function() {
function toArray(list) {
var k, out = [];
if( list ) {
if( angular.isArray(list) ) {
out = list;
}
else if( typeof(list) === 'object' ) {
for (k in list) {
if (list.hasOwnProperty(k)) { out.push(list[k]); }
}
}
}
return out;
}
return function(items) {
return toArray(items).slice().reverse();
};
});
And the usage is like so:
<ul id="messages" ng-show="messages">
<li ng-repeat="message in messages | reverse">{{message.text}}</li>
</ul>

Resources