Adding active class to element in child state - javascript

I am using ui-router within my AngularJS app. I have two states, one of which is a child.
.state('patents', {
url: '/patents',
component: 'patents'
})
.state('patents.patent', {
url: '/{patentId}',
component: 'patent'
})
In the parent state (patents), I have a table with a column with dynamic buttons, some which direct users to separate states, but one needs to direct the user to tab content, which is third in the ul within the child state patents.patent.
//Child state
<div class="view-tabs">
<ul class="nav view-pills">
<li ng-click="activeSelectedTab = 0; $ctrl.activePatentItemMenu = 'Patent Info'" ng-class="{active : $ctrl.activePatentItemMenu === 'Patent Info'}">Patent Info</li>
<li ng-click="activeSelectedTab = 1; $ctrl.activePatentItemMenu = 'Cost Analysis'" ng-class="{active : $ctrl.activePatentItemMenu === 'Cost Analysis'}">Cost Analysis</li>
<li ng-click="activeSelectedTab = 2; $ctrl.activePatentItemMenu = 'Renewal History'" ng-class="{active : $ctrl.activePatentItemMenu === 'Renewal History'}">Renewal History</li>
</ul>
</div>
<uib-tabset type="pills" active="activeSelectedTab">
//ALL TAB CONTENT WHICH IS DISPLAY APPROPRIATELY
</uib-tabset>
In the controller, activePatentItemMenu is set to Patent Info, so the first li item and its content is the first thing anyone sees, which is the default. I need the active class to be set to the 3rd li item Renewal History only if the user clicks on the specified button in the table, labeled renewal history.
Question
How do I set an active state to the third li item in the child state, only when a specific button is clicked in the parent state?

You should consider using ui-sref and ui-sref-active
<ul class="nav view-pills">
<li ui-sref-active="active">
<a ui-sref="patents.patent({patentId: 'Patent Info'})">Patent Info</a>
</li>
...
</ul>
Then use state.params in your controller to find the active uib-tabset

Related

Angular - how to use one function to manage multiple toggles / click events?

Please see attached image.
So, this is a navbar, where clicking on any of the tabs, the content below the nav will change based on which tab is selected.
Here is code for an example of how the function works for when click event is handled when Bespoke Manufacturing is clicked:
toggleBespoke() {
this.showBespoke = true;
this.showHow = false;
this.showCasting = false;
this.showForging = false;
this.showInjection = false;
this.showPressing = false;
this.showTurning = false;
}
As you can see, it's simple, the about showAbout variable is set to true whilst all the others are manually set to false.
ngClass is used which gives the blue highlighted effect so only one of the tabs gets highlighted when selected as only one can be true whilst others are false.
The same logic is then applied to the 6 other tabs.
But this is my question, what is the way to prevent code duplication and handle such click events in one function only?
You can use a property in your component which stores the active tab.
export class AlarmsComponent {
activeTab = 'bespoke';
}
And then you can use it in your template like this:
<ul class="tabs">
<li>
<a (click)="activeTab = 'bespoke'"
[ngClass]="{active: activeTab === 'bespoke'}"
>
Bespoke manufacturing
</a>
</li>
<li>
<a (click)="activeTab = 'how'"
[ngClass]="{active: activeTab === 'how'}"
>
How it works
</a>
</li>
</ul>
<div class="tab-bespoke" *ngIf="activeTab === 'bespoke'">
Bespoke manufacturing tab content
</div>
<div class="tab-how" *ngIf="activeTab === 'how'">
How it works tab content
</div>
Another solution (dirtier than the previous one) is to create a single function executed on click passing the $event param.
For instance you have something like the following to manage the nav item:
<li class="nav-item"><a id="bespoke" class="nav-link" href="#" tabindex="-1" (click)="onClick($event)">BESPOKE MANUFACTURING</a> </li>
And inside the class you have onClick function as the following:
onClick(ev){
let clickedId = ev.target.id;
//clickedId is the id of the clicked element and you can add class accordingly
if(clickedId === 'bespoke'){
//the user clicked the bespoke item
}
}
Create a variable to store the current active tab, in interaction with tab set current clicked tab to activeTab, then apply active inactive class using this variable ,for example in
app.component.ts
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
activeTab: string = 'tab1';
isActive(tabName){
return this.activeTab === tabName;
}
makeActive(tab){
this.activeTab = tab;
}
}
in Html
app.component.html
<ul class="nav nav-tabs">
<li class="nav-item">
<a [ngClass]="{'nav-link': true, 'active':isActive('tab1')}" (click)="makeActive('tab1')">Tab 1</a>
</li>
<li class="nav-item">
<a [ngClass]="{'nav-link': true, 'active':isActive('tab2')}" (click)="makeActive('tab2')">Tab 2</a>
</li>
<li class="nav-item">
<a [ngClass]="{'nav-link': true, 'active':isActive('tab3')}" (click)="makeActive('tab3')">Tab 3</a>
</li>
<li class="nav-item">
<a [ngClass]="{'nav-link': true, 'active':isActive('tab4')}" (click)="makeActive('tab4')">Tab 4</a>
</li>
</ul>
<div>
<div class="tab-bespoke" *ngIf="isActive('tab1')">
tab 1 content
</div>
<div class="tab-bespoke" *ngIf="isActive('tab2')">
tab 2 content
</div>
<div class="tab-bespoke" *ngIf="isActive('tab3')">
tab 3 content
</div>
<div class="tab-bespoke" *ngIf="isActive('tab4')">
tab 4 content
</div>
</div>
here is the running sample https://stackblitz.com/edit/angular-bootstrap-4-starter-cbrzm5
I'd go with the framework and actually use proper routing instead of hiding content by hand.
as a bonus, you'll get the current tab get set to automatically when the user refresh the page.

How to make li active after page loads

I am having a list which is reused in other webpage so i included it in one file and require the same in other webpage where required
I want to make them active for example if MY RESUME IS CLICKED THE li of myresume become active instead of dashboard so i implement jquery in the same file
but everytime i click on other link other than dashboard the active class is only present in Dashboard l . Is it due to because every time I am going to other page the active class is present on dashboard or due to jquery code(i have included cdn of jquery)??
.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active"><i class="ti-dashboard"></i>Dashboard</li>
<li><i class="ti-wallet"></i>My Resume</li>
<li><i class="ti-wallet"></i>Browse Jobs</li>
<li><i class="ti-wallet"></i>Assessment</li>
<li><i class="ti-hand-point-right"></i>Applied Jobs</li>
</ul>
What i want is that my li become active after my page loads not after clicked
$(document).ready(function() {
$("li").click(function() {
// remove classes from all
$("li").removeClass("active");
// add class to the one we clicked
$(this).addClass("active");
});
});
Try this, give your url name as the class name for all the li like below
<ul>
<li class="dashboard"><i class="ti-dashboard"></i>Dashboard</li>
<li class="resume"><i class="ti-wallet"></i>My Resume</li>
<li class="employer-list"><i class="ti-wallet"></i>Browse Jobs</li>
<li class="assess"><i class="ti-wallet"></i>Assessment</li>
<li class="jobs"><i class="ti-hand-point-right"></i>Applied Jobs</li>
</ul>
Then change your jQuery as below, logic is that, from the url will get the class name you given for each li and assign active class accordingly.
$(document).ready(function() {
var relativePath = location.pathname.split("/");
var activeMenu = relativePath[relativePath.length-1].replace(".php", "")[0];
$('li.'+activeMenu).addClass("active");
});

How to make list tag as selected or active by default on page load

I am using ui-sref-active="active" to make the selected <li> tag active but I want a list tag to be active as default out of three list tags
<li ui-sref-active="active" class="item active"><a data-ng-click="search.status = ''" href="">ALL PROJECTS</a></li>
<li ui-sref-active="active"><a data-ng-click="search.status = 'PORTFOLIO'" href="">PORTFOLIO</a></li>
<li ui-sref-active="active"><a data-ng-click="search.status = 'CATEGORY'" href="">NOTIFICATIONS</a></li>
I want the first list tag to be active by default and then when user clicks on anyother list tag it should deactivate and activate other list tag
I am using this directive: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-sref-active
you can use ng-class to dynamically turn class 'active' on and off.
<li ui-sref-active="active" ng-class="{active: activeTab1}"><a data-ng-click="search.status = ''" href="">ALL PROJECTS</a></li>
<li ui-sref-active="active" ng-class="{active: activeTab2}"><a data-ng-click="search.status = 'PORTFOLIO'" href="">PORTFOLIO</a></li>
<li ui-sref-active="active" ng-class="{active: activeTab3}"><a data-ng-click="search.status = 'CATEGORY'" href="">NOTIFICATIONS</a></li>
In your controller you can switch the activeTab1,2 and 3 on and off based on which list tag the user clicks. You can set activeTab1 true by default.
UPDATED
added {} in ng-class because of the syntax
Here is a working example in Plunker

To add class="current" Dynamically

I have Menu list which contains Sub-Menu as shown in the code below.
<li class="current">
<span class="icon4"></span>Subscriptions
<ul class="sub-menu">
<li>View Subscriptions
</li>
<li class="#((ViewBag.PageName == " Subscription ") ? "active " : " ")">Manage Subscription Plans
</li>
</ul>
</li>
<li class="current">
<span class="icon5"></span>Administration
<ul class="sub-menu">
<li class="#((ViewBag.PageName == " AssetPage ") ? "active " : " ")">Assets
</li>
<li>Configure Text
</li>
<li>Error Log
</li>
<li>Product Settings
</li>
</ul>
</li>
<li class="current">
<span class="icon6"></span>Promo Codes
<ul class="sub-menu">
<li>Manage Promo Code
</li>
<li>Used Promo Code
</li>
</ul>
</li>
Here Subscription,Administration,Promo Codes are Menu Lists which contains Sub-Menu Lists under them.
The thing is I want to apply class=current dynamically when a user clicks on Subscription,Administration,Promo Codes`.
And I am doing this in LayoutPage of MVC.
Any help will be appreciated.
Here you have a working solution: https://jsfiddle.net/c4h3sup9/
You have to use a little bit of Javascript for that.
You have to give the listitems a other class name like in my example "operator"
document.body.addEventListener("click", function(e){
if(e.target && e.target.className == "operator"){
var actives = document.getElementsByClassName("active");
actives[0].setAttribute("class", "operator");
e.target.setAttribute("class", "active");
}
});
for this example you need to assing one element as active from the beginning.
Note:
LI elements are never parents of UL.
The order is:
Unordered List (Plural) -> List item (Singular, Child).
You might want to correct that as it is not standard conform.
To add the class name to the parent <li> element, give the main links a class name. Assuming you also want to remove it from any <li> elements that already have it, also give them a class name
<li class="container">
<span class="icon4"></span>Subscriptions
and the script will be
$('.mainmenu').click(function() {
$('.container').removeClass('current'); // remove any previous
$(this).closest('.container').addClass('current');
});
In addition, if when you navigate to one of the views with this layout, and what to add the class name to the appropriate element, then you can give the <li> elements an id attribute
<li id="subscriptions" class="container">
....
</li>
<li id="administration" class="container">
....
and in the GET method, pass the value of the id to the view (e.g. using ViewBag
public ActionResult ConfigureText()
{
ViewBag.Menu = "administration";
....
return View(...);
}
and add a script that runs when the page first loads
var menu = '#ViewBag.Menu";
$('#' + menu).addClass('current');

Make all direct parent list entries selected in mmenu

I'm working on a project where I'm about to use the jQuery plugin mmenu (http://mmenu.frebsite.nl/).
I already had to do some customisations to fit my needs but I don't know what to do with my current issue. In mmenu, when i click on an list entry I will be navigated to the given href and the clicked item becomes active by mmenus css class ".mm-selected". So far so good.
Now I want to additionally mark the parent list item (and thats parent, and so on until menu root) as selected. This should be so when the user goes one level up in the menu he should be able to see in which category he currently is.
Below is an example of the menus html structure after mmenu was applied. This shows the code for a menu with 4 main pages (index, page1, page2 and page3) and 3 subpages (2.1, 2.2, 2.3).
<nav id="nav" class="mm-menu mm-horizontal mm-offcanvas mm-hasheader mm-current mm-opened">
<ul class="mm-list mm-panel mm-opened mm-current" id="mm-0">
<li class="mm-selected">
Index
</li>
<li>
Page 1
</li>
<li>
<a class="mm-subopen mm-fullsubopen" href="#mm-1"></a>
<span>Page 2</span>
</li>
<li>
Page 3
</li>
</ul>
<ul class="mm-list mm-panel mm-highest" id="mm-1">
<li class="mm-subtitle">
<a class="mm-subclose" href="#mm-0">Page 2</a>
</li>
<li>
Page 2.1
</li>
<li>
Page 2.2
</li>
<li>
Page 2-3
</li>
</ul>
</nav>
It would be great if you had some idea where and how I could achive such functionality.
So, for the moment I did some jQuery hacking. This seems to work for my case mentioned above. It should also work for deeper menus as it's using recursion. If there's a better way to achieve this, please let me know.
var nav = $("#nav");
nav.find("li > a:not(.mm-subopen)").click(function () {
nav.find("li.active").removeClass("active");
selectParentEntry($(this));
});
var selectParentEntry = function (a) {
var li = a.parent(),
ul = li.parent(),
back = ul.find("li > a.mm-subclose").first(),
cID = "#" + ul.attr("id"),
pID = back.length ? back.attr("href") : null;
li.addClass("active");
if (pID != null) {
var subOpen = nav.find("ul" + pID + " > li > a.mm-subopen").filter(function () {
var self = $(this);
if (self.attr("href") === cID) return self;
}).first();
if (subOpen) selectParentEntry(subOpen);
}
};

Categories