Removing the clicked item from menu list using angular 4 - arrays

Hi,
I have a notification menu list in which i am binding the data which is coming from the REST API. My notification menu will look like this. See below image for clarity.
In the notifications, when ever i click on any of the list item then it should be removed from the list and on the above also there is notification bubble in red color with some count that how many notifications i have received. What i want to achieve is when i click on the notification menu list then the clicked list item should be removed from it also the count should decrease in red color bubble above the bell icon. For example, when i click on notification list item of first item the it should be removed as well as the count should be decreased.
notification.component.ts
try {
this.currentUser = JSON.parse(this.cookieService.get('user-is-logged-in-details'));
console.log(this.currentUser.uid);
this._userService.getBellNotification(this.currentUser.uid)
.subscribe(data => this.cookieData = data);
} catch (e) {
console.log("Catch Block Error from Notification.Component.ts");
//console.log("currentUser", this.currentUser.uid);
}
apiservice.service.ts
getBellNotification(uid: any){
const urlBell = this.config.apiUrl+'api/supplier-notification/'+uid+'?_format=json';
let headers = new Headers();
headers.append("Content-Type", 'application/json');
headers.append('Authorization', 'Basic ' + btoa('apiuser:#piUser#2017Supplier'));
let requestoptions = new RequestOptions({headers: headers});
return this.http.get(urlBell, requestoptions)
.map(response => response.json())
.catch(this.handleErrorObservable);
}
notification.component.html
<span
class="notification"
dropdown (onShown)="onShown()"
(onHidden)="onHidden()"
(isOpenChange)="isOpenChange()">
<a
href dropdownToggle
(click)="false">
<i
class="glyphicon glyphicon-bell"
[ngClass]="cookieData?.search_unread_count != 0 ? 'notification-icon': ' '">
<span *ngIf="cookieData?.search_unread_count != 0">{{cookieData.search_unread_count}}</span>
</i>
</a>
<ul
*dropdownMenu
class="dropdown-menu notify-drop">
<div
class="notify-drop-title">Notifications</div>
<div
class="drop-content"
*ngFor="let item of cookieData.search_result">
<li
data-id="{{item.id}}"
class="notification-items unread">
<i
class="fa fa-dot-circle-o"
aria-hidden="true">
</i>
<a
data-link="admin-invoice-list"
href="javascript:;">{{item.message}}
</a>
</li>
</div>
</ul>
</span>
Can anyone please suggest me how it can be achieved?

#federico scamuzzi ise explained what you missed exactly. but him answer is need some correction for your objects and requirements. I have update that in here, try it and let me know if you have any clarification.
<div
class="drop-content"
*ngFor="let item of cookieData.search_result">
<li (click)="remove(item)"
data-id="{{item.id}}"
class="notification-items unread">
<i
class="fa fa-dot-circle-o"
aria-hidden="true">
</i>
<a
data-link="admin-invoice-list"
href="javascript:;">{{item.message}}
</a>
</li>
and your remove function should be
remove(item:any){
//ALSO CALL A BACKEND API... TO REMOVE THEM .. THIS IS ONLY FRONT END
this.cookieData.search_result = this.cookieData.search_result.filter(xx=>xx.id != item.id);
this.cookieData.search_unread_count=this.cookieData.search_result.length;
}

have youtried to attach a (click) function on each so to remove (or do the action you want) on the click of item?...something like:
<div
class="drop-content"
*ngFor="let item of cookieData.search_result">
<li (click)="remove(item)"
data-id="{{item.id}}"
class="notification-items unread">
<i
class="fa fa-dot-circle-o"
aria-hidden="true">
</i>
<a
data-link="admin-invoice-list"
href="javascript:;">{{item.message}}
</a>
</li>
then in your ts file:
remove(item:any){
//ALSO CALL A BACKEND API... TO REMOVE THEM .. THIS IS ONLY FRONT END
this.cookieData = this.cookieData.filter(xx=>xx.id != item.id);
this.cookieData.search_unread_count=this.cookieData.search_result.length;
}
Hope it helps you!!

Related

how to change classes on clicking in react?

Here is the code:
state: {
button: "notclicked"
}
changeclass = () => {
this.setState({ button: "clicked" })
}
<ul>
<li className="linkactive">
<a class="vote-up-off" onClick={ this.changeclass } href="/">
<Icon className={ this.state.button } className=" fa fa-area-chart"/>
</a>
</li>
<li>
<a class="vote-up-off"href="/">
<Icon className="fa fa-bar-chart fa-2x"/>
</a>
</li>
<li>
<a class="vote-up-off" href="/>
<Icon className="fa fa-line-chart"/>
</a>
</li>
</ul>
I am able to change the class on clicking <li>, But on clicking another <li>, how to make prev class back to notclicked?
I want to show the user which tab he is currently on
What happen now with your changeClass() function is that every time you click on the link, the state.button is set to "clicked".
What you could do in this method is start by checking the value of button and set it to the other value.
eg:
changeclass=()=>{
if(this.state.button === "notclicked"){
this.setState({button:"clicked"})
}
else {
this.setState({button:"notclicked"})
}
}
Then, if you want each <li> to trigger your changeclass function, onClick must be set for each one of them.
Also, there are a few typos in your code:
onClicke must be onClick
in the last <a> tag, the string besides href is not closed (there is a missing ")
To summarize, this code should work as expected:
state:{
button:"notclicked"
}
changeclass = () => {
if(this.state.button === "notclicked"){
this.setState({button:"clicked"})
}
else {
this.setState({button:"notclicked"})
}
}
<ul>
<li className="linkactive"><a class="vote-up-off" onClick={this.changeclass} href="/"><Icon className={this.state.button} className=" fa fa-area-chart"/></a></li>
<li><a class="vote-up-off"href="/" onClick={this.changeclass}><Icon className="fa fa-bar-chart fa-2x"/></a></li>
<li><a class="vote-up-off" href="/" onClick={this.changeclass}><Icon className="fa fa-line-chart"/></a></li>
</ul>
you can try it like this
// lets assume initial state is false
state = {clicked : false}
later on your component, you make ternary if by doing it like this
changeClicked = ()=>{
// this setState will take what you have previously, and
// will change it to opposite value
this.setState(prev=>({clicked: !prev.clicked}))
}
//...
<a onClick={this.changeClicked}>
<Icon className={clicked ? "clicked":"notclicked"} />
</a>
my suggestion is if you have something opposite like clicked-notclicked, on-off, up-down, etc that inherently one will always be true when the opposite is false, use boolean.
it will help you down the road.

How to change the uib-typeahead array based on button choice?

I can't seem to change the array that the uib-typeahead uses for the autocomplete on a search field. I have a button that chooses the categories to search by name, title, education, expertise and the button is working to filter the search results. But I am having issues trying to do the same thing for the uib-typeahead autocomplete.
I have a few arrays that pull the correct information and if I put them in and publish the page it works as intended, but I can't get them to switch out dynamically when a new filter is chosen.
The arrays that I am using. The default is the searchText with every category included. I tested them all and if I switch out searchText for any other one it works fine.
$scope.searchText = []; // all text that will be searched
$scope.searchname = []; // Name text that will be searched
$scope.searchtitle = []; // Title text that will be searched
$scope.searchexpertise = []; // Expertise text that will be searched
$scope.searcheducation = []; // Education text that will be searched
$scope.searchpositionsHeld = []; // PositionsHeld text that will be searched
Here are my button and input sections.
<button type="button" class="btn btn-outline dropdown-toggle rounded-0" data-toggle="dropdown">
<span id="search_selection">Search by</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<a class="dropdown-item" ng-click="changeFilterTo('name'); changeSearchTo('$scope.searchname')" href="#name">Name</a>
<a class="dropdown-item" ng-click="changeFilterTo('title'); changeSearchTo('$scope.searchtitle')" href="#title">Title</a>
<a class="dropdown-item" ng-click="changeFilterTo('tags'); changeSearchTo('$scope.searchtags')" href="#tags">Lab Capability</a>
<a class="dropdown-item" ng-click="changeFilterTo('expertise'); changeSearchTo('$scope.searchexpertise')" href="#expertise">Expertise</a>
<a class="dropdown-item" ng-click="changeFilterTo('education'); changeSearchTo('$scope.searcheducation')" href="#education">Education</a>
<a class="dropdown-item" ng-click="changeFilterTo('positionsHeld'); changeSearchTo('$scope.searchpositionsHeld')" href="#positionsHeld">LANL Positions</a>
</ul>
</div>
<input
class="form-control"
id="search_param"
placeholder="Type something"
type="text"
ng-model="search[filter]"
uib-typeahead="item for item in searchText | filter:$viewValue | limitTo:25"
ng-change="changeHandler()"
/>
And here is what I was trying to set out the uib-typeahead attribute.
$scope.changeSearchTo = function(pr) {
$scope.searchText = [];
$scope.searchText = pr;
}
So far nothing I have tried can switch out the arrays and I have tried searching for more answers, but nothing seems to match. I appreciate the help anyone can provide. Thank you!
remove $scope in the template. Try changeSearchTo(searchname) without the comma.
Merlin was mostly correct I removed $scope and then used this code to set the attribute:
$scope.changeSearchTo = function(prs) {
$scope.searchText = [];
$scope.searchText = $scope[prs];
}

add active class to menu item clicked add remove from others

I want to add isActive class to an item menu when user click on this item, and remove isActive class from all others items.
I am trying to compare the id, this is the angularJS code:
$rootScope.isActive = function(idVal, event){
return idVal === event.target.id;
}
This is a part from Menu Html code:
<ul class="sidebar-nav">
<li>
<a ui-sref="" id='101' ng-class="{active: isActive($event, 101)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Rules
</a>
<ul class='dropdown sidebar-nav-dropdown' >
<li>
Transaction Mapping
</li>
<li>
File Setup
</li>
<li>
Code Setup
</li>
</ul>
</li>
<li>
<a href="#" id='102' ng-class="{active: isActive($event, 102)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Administrative Rules
</a>
<ul class='dropdown sidebar-nav-dropdown'>
<li>
<a ui-sref="admin.mapping-rules">Transaction Mapping</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">File Setup</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">Code Setup</a>
</li>
</ul>
</li>
</ul>
Thanks,
First of all, you shouldn't use the root scope. You should use the scope of the controller associated to that view.
Second, your code doesn't make much sense. $event can be used as a parameter of a function called... to react to an event:
ng-click="doSomething($event)"
But with ng-class, there is no $event.
All you need to have in your scope is the ID (or name, or whatever identifies a menu item) of the selected menu item:
$scope.selectedMenuItem = null;
When an item is clicked, you need to change the selected menu item:
ng-click="selectMenuItem(101)"
$scope.selectMenuItem(item) {
$scope.selectedMenuItem = item;
}
Then to associated a css class with the selected menu item, you simply need
ng-class="{active: selectedMenuItem === 101}"
That said, if all your links navigate to a given router state, you don't even need that selectedMenuItem. All you need is to add the active class if the current router state is the one the that the link allows navigating to (assuming $state is on your scope):
ng-class="{active: $state.includes('admin.mapping-rules')}

How to set active class on ng-click?

I have this:
<div class="account-item">
<div class="account-heading" ng-class="active">
<h4 class="account-title">
<a href="#/Messages" onclick="SetActiveAccountHeading(this);">
7. #Translate("SYSTEM_MESSAGES")</a>
</h4>
</div>
</div>
<div class="account-item">
<div class="account-heading" ng-class="active">
<h4 class="account-title">
<a href="#/Info" onclick="SetActiveAccountHeading(this);">
7. #Translate("SYSTEM_INFO")</a>
</h4>
</div>
</div>
In angular i have this:
$scope.active = "active";
but how can i change this on click so if user click on menu once it would be active if again click it would be NOT active?
Ok say you have multiple menu items and you want to toggle the class according to click,
you can create a array in the controller which represents the menu items as,
$scope.menuItems = ['Home', 'Contact', 'About', 'Other'];
assign the default selected ,menu item
$scope.activeMenu = $scope.menuItems[0];
create a function to assign the selected Menu value, this function will assign the $scope.activeMenu a last selected menu item.
$scope.setActive = function(menuItem) {
$scope.activeMenu = menuItem
}
in HTML
loop through the menuItems array and create the menu.
in the ng-class check last clicked menu item is equal to item in the repeat.
if click on the menu then call setActive() function in the controller and pass the menu item name as an argument.
<div class="account-item" ng-repeat='item in menuItems'>
<div class="account-heading" ng-class="{active : activeMenu === item}">
<h4 class="account-title">
{{ item }}
</h4>
</div>
</div>
here is the DEMO
here is a DEMO without ng-repeat
This is what you need.
<div class="account-item" ng-init="active = true">
<div class="account-heading" ng-class="{'active': active === true}" ng-click="active = !active">
<h4 class="account-title">
7. #Translate("SYSTEM_MESSAGES")
</h4>
</div>
</div>
No other scripting. +1 if it helps.
Angular4:
<a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
<a [routerLink]="['calendar']" routerLinkActive="active">
Documentation: https://angular.io/api/router/RouterLinkActive
If you are using [ui-router] you not need to write anything just you have add this ui-sref-active="active-menu" property in your tag which you want to active after click/navigate.
For cleaner code try this:
<div class="account-item" ng-init="active = true">
<div class="account-heading" ng-class="{'active': active}">
<h4 class="account-title">
7. #Translate("SYSTEM_MESSAGES")
</h4>
</div>
</div>
You can remove the onclick event SetActiveAccountHeading(this);.
Here's the JsFiddle link.
You can view the result in the developer's console.
Hope it helps.

$scope is only visible in function and thats why is not working

My layout page looks like this:
<li class="dropdown">
<ul class="submenu">
<li>#Translate("MY_ACCOUNT")</li>
</ul>
</li>
In layout page i have : #RenderBody()where i have Index page.In index page im using <div ng-view></div>. What im trying to do is when user click on a href to redirect him on that page and set class to this menu that is render in ng-view:
<div class="account-item">
<div class="account-heading" ng-class="{active : activeMenu === 'Settings'}">
<h4 class=" account-title has-sub">
<a data-toggle="collapse" data-parent="#accordion" href="#settings" ng-click="activeMenu='Settings'">5. #Translate("SETTINGS")</a></h4>
</div>
<div id="settings" class="account-collapse collapse in">
<div class="account-body">
#Translate("PERSONAL_INFORMATION")
#Translate("NOTIFICATIONS")
#Translate("CHANGE_PASSWORD")
#Translate("GAME_SETTINGS")
</div>
</div>
</div>
When i try this nothing happens:
$scope.SetActiveMenuForPersonalInfo = function () {
$scope.activeMenu = 'Settings';
$scope.activeLink = "PersonalInfo";
}
$scope.activeMenu and $scope.activeLink are visible only in function and thats why i cant set class on menu. When i put it out of function it works
Try changing the tripple equality sign in ng-class="{'active-link' : activeLink==='PersonalInfo'}" to double ==
PS: I do not understand the last paragraph

Resources