Using cmponents inside ngIf in Angular 2. - javascript

I want to use ngIf to show a component like this:
<ul class="nav nav-tabs">
<li (click)="resetTab(1)" [ngClass]="{'active': first}" id="active"><a>Tab 1</a></li>
<li (click)="resetTab(2)" [ngClass]="{'active': second}" ><a>Tab 2</a></li>
</ul>
<div class="tab-content">
<div *ngIf="first" class="tab-pane fade in active">
Content of tab 1
</div>
<div *ngIf="second" class="tab-pane fade">
Content of tab 2:
<events-list></events-list>
</div>
</div>
However for some reason I don't see my component appears when switching tabs (tabs itself switch just fine)
My component's code:
resetTab(tab: number) {
this.first = (tab == 1) ? true : false;
this.second = (tab == 2) ? true: false;
}

I try this for sidebar menu and working fine you can try this:
in html
<div class="sidebar-category">
<ul class="nav nav-pills nav-stacked">
<li [class.active]="panelshow == 'tab1'">
<a (click)="setPanel('tab1')">Tab1</a>
</li>
<li [class.active]="panelshow == 'tab2'">
<a (click)="setPanel('tab2')">Tab2</a>
</li>
</ul>
</div>
<div *ngIf="panelshow == 'tab1'">
</div>
<div *ngIf="panelshow == 'tab2'">
</div>
and in component:
public panelshow:string;
private setPanel(name) {
this.panelshow = name;
}

Related

add custom css to navigation tab wizard

I need to highlight selected tabs in the navigation tab wizard. tab functionality is working fine..but I need to add the CSS(border-style) for all the selected tab. for example, if I have 4 tabs. If I have selected the first and second tab(next button) those tab needs to be highlighted(apply border) and again if I click the back button the highlight needs to be removed.Any help would be appreciated. please find the image below for reference.
public tabs: string[] = ['tab1', 'tab2', 'tabs3', 'tabs4']
public next(): void {
const currentIndex: number = this.tabs.indexOf(this.selectedTab);
const newIndex = currentIndex + 1;
this.selectedTab = this.tabs[newIndex];
}
public back(): void {
const currentIndex: number = this.tabs.indexOf(this.selectedTab);
const newIndex = currentIndex - 1;
this.selectedTab = this.tabs[newIndex];
}
.tab-highlight {
border-top: 2px solid blue;
cursor: pointer;
}
<ul class="nav nav-tabs side_nav" role="tablist">
<li *ngFor="let tab of tabs; let i= index;" [attr.data-index]="i" role="presentation"
class="accounts_li"
[class.active]="selectedTab===tab" (click)="toggle($event)">
<a (click)="selectedTab = tab" aria-controls="one" role="tab" data-toggle="tab">{{tab}}</a>
</li></ul>
<div class="tab-content">
<div id="tab1" *ngIf="selectedTab === tabs[0]" role="tabpanel" class="tab-pane active">
tab1 content
</div>
<div id="tab2" *ngIf="selectedTab === tabs[1]" role="tabpanel" class="tab-pane active">
tab2 content
</div>
<div id="tab3" *ngIf="selectedTab === tabs[2]" role="tabpanel" class="tab-pane active">
tab3 content
</div>
</div>
<button class="button" (click)="back()"><span>
Back</span>
</button>
<button class="button" (click)="next()"><span>
Next</span>
</button>
image
If you want to select multiple tabs then you should change the selectedTab property with an array which will hold all selected tabs. Then you could create a method which will check if the tab is selected or not in order to push/remove from the selected array. Lastly, for the conditional class name you could use [ngClass]="isSelected(tab) ? 'tab-highlight' : null", this will add the class only if the condition is evaluated to true (more on this here https://angular.io/api/common/NgClass)
Component code:
tabs: string[] = ["tab1", "tab2", "tab3", "tab4"];
selectedTabs: string[] = [];
onTabClick(tab) {
if (this.isSelected(tab)) {
let index = this.selectedTabs.indexOf(tab);
this.selectedTabs.splice(index, 1);
} else {
this.selectedTabs.push(tab);
}
}
isSelected(tab: string) {
return this.selectedTabs.indexOf(tab) > -1;
}
HTML code for the tab menu:
<ul class="nav nav-tabs side_nav" role="tablist">
<li *ngFor="let tab of tabs; let i= index;" [attr.data-index]="i" role="presentation"
[ngClass]="isSelected(tab) ? 'tab-highlight' : null">
<a (click)="onTabClick(tab)" aria-controls="one" role="tab" data-toggle="tab">{{tab}}</a>
</li>
</ul>
Stackblitz: https://stackblitz.com/edit/question63192497?file=src%2Fapp%2Fapp.component.ts

(ASP.NET Core) How to update view component on view

When I select a item (ul,li),
I need to update the view component dynamically,but cannot achieve.
How do I modify the code ?
Do not use (Controller)"return view" method
(Partial code)
(chtml)
<div>
<ul class="nav nav-tabs">
<li role="tab"> <a href="#" onclick=change1();>1</a></li>
<li role="tab"> <a href="#" onclick=change2();>2</a></li>
</ul>
</div>
<div role="tabpanel" class="tab-pane active">
#{
string item = ViewBag.NowPay;
switch (item)
{
case "Card1":
#await Component.InvokeAsync("DownloadConfig1", new { reconciliationConfig = Model });
break;
case "Card2":
#await Component.InvokeAsync("DownloadConfig2", new { reconciliationConfig = Model });
break;
default:
break;
}
}
</div>
(script)
function change1() {
$.ajax({
type: 'POST',
url: '/ReconciliationConfig/TestChane1',
success: function (data) {
}
})
}
Controller
public String TestChane1()
{
ViewBag.NowPay = "Card1";
var Result = ViewBag.NowPay;
return Result;
}
Thanks for answer
First Solution
if you don't want to go again to server, you have to render each case in separate div and show/hide with javascript
View Code cshtml
<style>
.d-none, .hidden { display: none; }
</style>
<div>
<ul class="nav nav-tabs">
<li role="tab"> <a href="#" onclick=change('Card1');>1</a></li>
<li role="tab"> <a href="#" onclick=change('Card2');>2</a></li>
</ul>
</div>
<div role="tabpanel" class="tab-pane active">
#{
string item = ViewBag.NowPay;
}
<div id="Card1" class="cards #(item == "Card1" ? "" : "hidden d-none")">
#await Component.InvokeAsync("DownloadConfig1", new { reconciliationConfig = Model });
</div>
<div id="Card2" class="cards #(item == "Card2" ? "" : "hidden d-none")">
#await Component.InvokeAsync("DownloadConfig2", new { reconciliationConfig = Model });
</div>
</div>
<script>
function change(name) {
$('.cards').addClass('hidden d-none'); // hide all cards
$('#'+ name).removeClass('hidden d-none'); // show only one
}
</script>
Not currently successful
cshtml
<style>
.d-none, .hidden { display: none; }
</style>
<div>
<ul class="nav nav-tabs">
<li role="tab"> <a href="#" onclick=changeCard1();>1</a></li>
<li role="tab"> <a href="#" onclick=changeCard2();>2</a></li>
</ul>
</div>
<div role="tabpanel" class="tab-pane active">
<div id="Card1" class="d-none">
#await Component.InvokeAsync("DownloadConfig1", new { reconciliationConfig = Model });
</div>
<div id="Card2" class="d-none">
#await Component.InvokeAsync("DownloadConfig2", new { reconciliationConfig = Model });
</div>
</div>
<script>
function changeCard1() {
$('Card1').removeClass('d-none'); // show only one
$('Card2').addClass('d-none');
}
function changeCard2() {
$('Card1').addClass('d-none'); // show only one
$('Card2').removeClass('d-none'); // show only one
}
</script>

How to invoke javascript method based on a Value of ViewBag

I'm working on small mvc application, and on my view there is tab control which has 3 tabs, and depending on ViewBag value I need to open my third tab, here is image of a how my view looks:
So when View is loaded, I need to check for a value of my ViewBag and depending on that I need to open my TAB 3, so here is what I've tried:
<div class="" role="tabpanel" data-example-id="togglable-tabs">
<ul id="myTab" class="nav nav-tabs bar_tabs" role="tablist">
#if (ViewBag.SuccessBody == null)
{
<li role="presentation" class="active">
TAB 1
</li>
<li role="presentation" class="">
TAB 2
</li>
<li role="presentation" class="">
TAB 3
</li>
}
else
{
<li role="presentation" class="">
TAB 1
</li>
<li role="presentation" class="">
TAB 2
</li>
<li role="presentation" class="active" onload="RedirectToTab();">
TAB 3
</li>
}
</ul>
As you can see guys depending on a value od ViewBag.SuccessBody I tried to load corresponding HTML, so if there is a value then I would load HTML which include TAB3 To own class="active" (please read code detailed).
But unfortunatelly with this approach, TAB3 becoming active but not also OPENED, so its content is not visible, it's being kept acctually on TAB1 while TAB3 looks like it's active, and that is bad :( .
So what I've done is :
I wrote javasscript method which should really open TAB3, but I couldn't know how to invoke it so I guess I could invoke it using onload method on my li element, so guys as you can see in code above I wrote on my li
onload="RedirectToTab();"
but unfortunatelly nothing happens..
And here is definition of my RedirectToTab javascript method:
function RedirectToTab() {
var customVal = $("#editViewBag").val();
if (customVal == 'True') {
$('#myTab a[href="#tab_content3"]').tab('show');
}
}
So guys one more time, how can I open TAB3 depending on a vaue of my ViewBag?
Thanks guys
Cheers
Just use the razor engine to output your ViewBag value in the javascript:
function RedirectToTab() {
var customVal = '#ViewBag.SuccessBody';
if (customVal == 'True') {
$('#myTab a[href="#tab_content3"]').tab('show');
}
}
Now you can call this from the doc ready:
$(document).ready(function () {
RedirectToTab();
});
You don't need to use JavaScript to open the tab. You can do it your Razor view which has the benefit of not seeing the active tab switch from 1 to 3 when the page loads. Here is a simple example with 3 tabs:
#{
string tab1 = null, tab2 = null, tab3 = null;
if (ViewBag.SuccessBody == null)
{
tab1 = "active";
}
else
{
tab3 = "active";
}
}
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="#tab1">Tab 1</li>
<li role="presentation" class="#tab2">Tab 2</li>
<li role="presentation" class="#tab3">Tab 3</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane #tab1" id="tab1">
tab 1
</div>
<div role="tabpanel" class="tab-pane #tab2" id="tab2">
tab 2
</div>
<div role="tabpanel" class="tab-pane #tab3" id="tab3">
tab 3
</div>
</div>

AngularJS routing with redirection

I'm working on AngularJS with ng-route, have a navigation Matches, Standings and when I click on Matches I want to open a sub navigation All, 1st Round, Semi Finals ... and I want by default the allmatches.html view to be displayed below.
I wrote something like this:
$routeProvider
.when('/matches', {
templateUrl: 'views/matchesmenu.html',
controller: 'matchesmenuCtrl',
})
to display the matches sub navigation once I click on Matches and it works fine. What can I do now to display the allmatches.html just below it (I mean by that route to matches/all
I tried to add
redirectTo : '/matches/all'
in
.when('/matches', {
templateUrl: 'views/matchesmenu.html',
controller: 'matchesmenuCtrl',
})
but it redirects without displaying the sub navigation.
Example on plnkr: https://plnkr.co/edit/UoTcOlcDQSwveCTbmxyY?p=preview
Allright, here your are - runnable plnkr. This provides a simple tab handling logic for you.
TabView
<div ng-controller="TabCtrl">
<ul class="nav nav-tabs">
<li role="presentation" ng-class="{'active' : activeTab === 'all'}">
<a ng-click="activeTab = 'all'">All</a>
</li>
<li role="presentation" ng-class="{'active' : activeTab === 'first-round'}">
<a ng-click="activeTab = 'first-round'">1st Round</a>
</li>
<li role="presentation" ng-class="{'active' : activeTab === 'semi-finals'}">
<a ng-click="activeTab = 'semi-finals'">Semi Finals</a>
</li>
<li role="presentation" ng-class="{'active' : activeTab === 'finals'}">
<a ng-click="activeTab = 'finals'">Final</a>
</li>
</ul>
<div>
<div class="" ng-switch="activeTab">
<div ng-switch-when="all">
<div data-ng-include="'first-round.html'"></div>
<div data-ng-include="'semifinals.html'"></div>
<div data-ng-include="'finals.html'"></div>
</div>
<div ng-switch-when="first-round">
<div data-ng-include="'first-round.html'"></div>
</div>
<div ng-switch-when="semi-finals">
<div data-ng-include="'semifinals.html'"></div>
</div>
<div ng-switch-when="finals">
<div data-ng-include="'finals.html'"></div>
</div>
</div>
</div>
</div>
AngularJS application
var app = angular.module('myApp',['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/matches', {
templateUrl: 'matchesmenu.html'
})
.when('/matches/all', {
templateUrl: 'allmatches.html'
})
}).controller('TabCtrl', function ($scope) {
$scope.activeTab = 'all';
});
Try this
Define your sub menu in controller level
$scope.tabs = [
{title: 'All', url: 'allmatches.html', active: true, type: 'all'},
{title: '1st Round', url: 'semiFinals.html', active: false, type: 'semi'}
];
//handle tab click event
$scope.tabClick = function (index) {
angular.forEach($scope.tabs, function (tab) {
tab.active = false;
});
$scope.selectedTab = index;
$scope.tabs[index].active = true;
};
After that matchesmenu.html load content using ng-include option
<div class="row clearfix">
<div class="col-xs-12">
<ul class="nav nav-tabs">
<li role="presentation" ng-class="{'active':tab.active}" ng-repeat="tab in tabs" ><a href="#/log/{{tab.type}}" >{{tab.title}}</a></li>
</ul>
</div>
</div>
<div class="row clearfix">
<div class="col-xs-12" ng-repeat="tab in tabs" ng-model="tab" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ng-include src="tab.url" ng-if="tab.active"> </div>
</div>
</div>
</div>

How do I keep a submenu open when clicked?

This was created by someone else, but some submenus stay open while one stays closed when clicked. I have an idea of what I can do, but I have very little knowledge of JS. I was thinking if sub5 (the id for the submenu that stays closed), "something to make it true, then false if not sub5" How can I do this?
HTML
<nav id="rightNav">
<div class="menutitle first" onClick="SwitchMenu('sub1')">fabrics</div>
<div id="sub1" class="submenu">
<ul>
<li>lee jofa</li>
<li>groundworks</li>
<li>threads</li>
<li>gp & j baker</li>
<li>mulberry home</li>
<li>baker lifestyle</li>
<li>blithfield</li>
</ul>
</div>
<!-- end div#sub1 (fabrics) -->
<div class="menutitle" onClick="SwitchMenu('sub2')">furniture</div>
<div id="sub2" class="submenu">
<ul>
<li>lee jofa upholstery</li>
<li>lee jofa occasionals</li>
<li>Bunny Williams Home</li>
<li>holland & co.</li>
<li>macrae</li>
<li>elle & marks</li>
</ul>
</div>
<!-- end div#sub2 (furniture) -->
<div class="menutitle" onClick="SwitchMenu('sub3')">wallcoverings</div>
<div id="sub3" class="submenu">
<ul>
<li>lee jofa</li>
<li>cole & son</li>
<li>groundworks</li>
<li>threads</li>
<li>gP & j baker</li>
<li id="blithfield-wall">blithfield</li>
<li>farrow & ball</li>
<li>lincrusta</li>
</ul>
</div>
<!-- end div#sub3 (wallcoverings) -->
<div class="menutitle">trimmings</div>
<div class="menutitle" onClick="SwitchMenu('sub5')">carpets</div>
<div id="sub5" class="submenu">
<ul>
<li>lee jofa carpet</li>
<li id="gw-carpet">groundworks</li>
<li>threads</li>
</ul>
</div>
<!-- end div#sub5 (carpets) -->
<div class="menutitle" id="archive-collection">designer collections</div>
<div class="menutitle last">archives</div>
</nav>
<!-- end nav#rightNav -->
JS
if (document.getElementById) { //DynamicDrive.com change
document.write('<style type="text/css">\n')
document.write('.submenu{display: none;}\n')
document.write('</style>\n')
}
function SwitchMenu(obj) {
if (document.getElementById) {
var el = document.getElementById(obj);
var ar = document.getElementById("rightNav").getElementsByTagName("div"); //DynamicDrive.com change
if (el.style.display != "block") { //DynamicDrive.com change
for (var i = 0; i < ar.length; i++) {
if (ar[i].className == "submenu") //DynamicDrive.com change
ar[i].style.display = "none";
}
el.style.display = "block";
} else {
el.style.display = "none";
}
}
}
You have a class and a style.
Your style is defined in the class, so you can't access it with element.style.
A simple solution is to change this line:
<div id="sub5" class="submenu">
to
<div id="sub5" class="submenu" style="display:none;">

Categories