Dynamic multi-columns dropdown - Angular2 and Bootstrap - css

How to create a dynamic multi column dropdown list. I am using angular2 and looking for something like this http://alijafarian.com/bootstrap-multi-column-dropdown-menu/
But here we have the columns fixed at 3 and the list items hardcoded.In my case I have a dynamic list and would like to display 5 items in one column.So for Eg: if the list contains 20 items then we would have 4 columns with 5 items each in one column.And my code looks like below
....
<li role="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown"
href="#" role="button"
aria-haspopup="true" aria-expanded="false">
Artists
<span class="caret"></span></a>
<ul class="dropdown-menu ">
<li *ngFor="let artist of artists">
<a><input type="checkbox"> {{artist.name}} </a>
</li>
</ul>
</li>
.....
I am using ngFor directive to loop through the list of artists and display it in single column now. But would like to display it in multi column depending on the size of the list.

You should be created a new array from the data by using a simple chunk function:
public chunk(arr, size) {
var newArr = [];
for (var i=0; i<arr.length; i+=size) {
newArr.push(arr.slice(i, i+size));
}
return newArr;
}
and do some changes in your view like this:
<ul class="dropdown-menu multi-column columns-2">
<div class="row">
<div class="col-sm-6" *ngFor="let persons of chunk(persons, 3)">
<ul class="multi-column-dropdown">
<li *ngFor="let person of persons">{{person.name}}</li>
</ul>
</div>
</div>
</ul>
Here is an example: plunker

Related

Router Link Active not working in the below scenario, is their any alternate way to activate button dynamically?

HTML code
<div class="card-header">
<h5>Refill by date</h5>
<div class="card-header-right">
<nav class="navbar bg-faded ">
<ul class="nav navbar-nav">
<li class="nav-item" routerLinkActive="active">
<button (click)="setView('branch'); getFranchiseRefillsByDateAndBranch()" class="btn btn-mini btn-bg-c-blue btn-outline-default btn-round btn-action">
<i class="icofont icofont-ui-check"> By branch</i>
</button>
</li>
<li class="nav-item" routerLinkActive="active">
<button (click)="setView('product'); getFranchiseRefillsByDateAndProduct()" class="btn btn-mini btn-bg-c-blue btn-outline-default btn-round btn-action">
<i class="icofont icofont-ui-check"> By product</i>
</button>
</li>
<li class="nav-item" routerLinkActive="active">
<button (click)="setView('list'); getFranchiseRefillsByDateAndList()" class="btn btn-mini btn-bg-c-blue btn-outline-default btn-round btn-action">
<i class="icofont icofont-ui-check"> Refill list</i>
</button>
</li>
</ul>
</nav>
</div>
</div>
part of TS code
getFranchiseRefillsByDateAndBranch() {
this.items = [];
var hrchyIds = this.jwtHelperService.getFRefillHrchyIds();
var ym = this.localStorage.retrieve('frym');
if (hrchyIds) {
this.refillService.getFranchiseRefillsByDateAndYear(hrchyIds, ym, "branch", this.page, this.rec).subscribe(val => {
this.items = val;
});
}
}
CSS code
.nav-item.active button i{
color: #3D94CD !important;
}
I am trying to change color of active button using router link active but this method does not work in this case, is their any alternate way of adding class dynamically, based on current click.
routerLinkActive works if there was a routerLink on this element.
Keep currentActiveItem variable in ts file. Set some default value say "branch"
currentActiveItem : string = "branch"
Change value of this variable in setView function.
And additionally also use ngClass as following on correspondiong li elements.
[ngClass]="{'active' : currentActiveItem == 'branch'}"
[ngClass]="{'active' : currentActiveItem == 'product'}"
[ngClass]="{'active' : currentActiveItem == 'list'}"

Nested Bootstrap Sidebar item throwing the toys out

With thanks to trevorp the basic side nav bar works perfectly. Then I needed to nest some menu items. This seems logical to me
<li class="collapsed active">
<div class="accordion-group">
<a data-toggle="collapse" data-target="#20"><i class="dropdown-toggle"></i>Accounting <span class="caret"></span></a>
<ul class="sub-menu collapse" id="20">
<li class="collapsed active">
<div class="accordion-group">
<a data-toggle="collapse" data-target="#21"><i class="dropdown-toggle"></i>Income <span class="caret"></span></a>
<ul class="sub-menu collapse" id="21">
<li>Customers</li>
</ul>
</div>
</li>
<li>Purchases</li>
<li>General Ledger</li>
<li>Banks</li>
<li>Invoicing</li>
<li>Financials</li>
<li>Utilities</li>
<li>Reports</li>
</ul>
</div>
</li>
But it produced this result
That just closes when clicked, instead of opening the li item... It's probably something very basic, but the art of staring at it hasn't produced any results yet :-)
I suspect clicking on the sub menu item is closing the parent, but no idea how to overcome that. No idea why the formatting is totally different either!
Thank you
======================= UPDATE =======================
If the second accordion-group div is removed it takes care for the blank menu item, and disabling the script
<script>
/* ensure any open panels are closed before showing selected */
$('.accordion-group').on('show.bs.collapse', function () {
$('.accordion-group .in').collapse('hide');
});
that closes the main menu items when another is opened now gives this result..
That now leaves two questions
How can I select a sub menu item without closing the accordion group?
How can I format the sub menu items in the same colour as the others (white not orange)?
Finally managed to find a way to solve question one
If there is a less verbose method I'd love to hear :-)
Add an onlick method to the sub-menu item
<li class="collapsed active">
<a onclick="holdCollapse();" data-toggle="collapse" data-target="#Menu_21" class="dropdown-toggle collapsed"><i class="fa fa-gift fa-lg"></i>Income </a>
<ul class="sub-menu collapse" id="Menu_21">
<li>Customers</li>
</ul>
</li>
and add a hidden field
<input type="hidden" value="0" id="HiddenField" />
add this script
<script>
function holdCollapse(e) {
$('#HiddenField').val('1');
}
and edit the original script
<script>
/* ensure any open panels are closed before showing selected */
$('.accordion-group').on('show.bs.collapse', function () {
var isSubMenu = $('#HiddenField').val();
if (isSubMenu == '0') {
$('.accordion-group .in').collapse('hide');
}
$('#HiddenField').val('0');
});

How can i disable navigation active

navigation image here
how can i disable the green color there whenever i click in gallery page?
Home
<li class="dropdown mega-dropdown">
<a class="dropdown-toggle" href="Gallery.aspx">Gallery<span class="caret"></span></a>
<div class="pc-nav">
<ul class="dropdown-menu mega-dropdown-menu">
<li class="col-sm-3 col-md-push-3">
<ul>
<li class="dropdown-header" style="text-align:left">Company Trips</li>
<li style="text-align:left; visibility:hidden;"> 2016 - Vietnam</li>
<li style="text-align:left;"> 2015 - Guilin</li>
</ul>
</li>
</ul>
CSS here
<ul class="dropdown-menu mega-dropdown-menu">
<li class="col-sm-3 col-md-push-3">
<ul>
<li class="dropdown-header" style="text-align:left">Company Trips</li>
<li style="text-align:left;"> 2016 - Vietnam</li>
<li style="text-align:left;"> 2015 - Guilin</li>
</ul>
</li>
</ul>
I assume the current class indicates the column you have selected. Given the markup you provided in the comments, you can rewrite the rule like this to remove the background color:
.current {
background-color: transparent;
}
If you do not have access to the original code but wish to override it, you can supersede the background-color property like this:
.current {
background-color: transparent !important;
}
But in the end, if you don't wish there to be any special background color for the current column, you can just delete the entire block of code.
EDIT
Based on your feedback, I assume you want to highlight the names of the countries in the list but not the first item of the list. In that case, you can target them like this:
ul.dropdown-menu ul li:not(.dropdown-header) {
background-color: #00b200;
}

how to pass the current tag instance to the events in angular2

I have a left sidebar menu which is populated by <li> and <ul> tag elements. I have handled the menu click event to expand/collapse the sub-menu items.
The problem I am facing here is I am not able to pass/identify the current instance of the tag element to do the expand/collapse i.e. If i expand a particular menu item all the other menus items are also getting affected. How do i handle this issue by identifying the current instance to do the required changes.
Please refer the snapshot about the issue
my HTML looks like below
<li [class.active]="menuLinkActive" (click)="MenuLinkToggle($event)">
<a><i class="fa fa-home"></i> Home <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu" [style.display]="subMenuDisplay">
<li>
Dashboard
</li>
<li>
Dashboard2
</li>
<li>
Dashboard3
</li>
</ul>
</li>
<li [class.active]="menuLinkActive" (click)="MenuLinkToggle($event)">
<a><i class="fa fa-edit"></i> Forms <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu" [style.display]="subMenuDisplay">
<li>
General Form
</li>
<li>
Advanced Components
</li>
</ul>
</li>
my component where i have handled the events
export class Layout {
menuLinkActive: any;
subMenuDisplay: any;
isSubMenuExpanded: any;
isMenuVisible: any;
MenuLinkToggle(event) {
if (this.isSubMenuExpanded) {
console.log("if (this.isMenuExpanded) {");
this.menuLinkActive = "";
this.subMenuDisplay = "none";
this.isSubMenuExpanded = false;
}
else {
console.log("else (this.isMenuExpanded) {");
this.menuLinkActive = "active";
this.subMenuDisplay = "block";
this.isSubMenuExpanded = true;
}
}
}
<li [class.active]="menuLinkActive" #li1 (click)="MenuLinkToggle($event, li1)">
MenuLinkToggle(event, element) {
or
MenuLinkToggle(event) {
event.target...

jQuery Mobile - Footer - navbar - when rendering shows as three columns and two rows grid layout

The page footer added as fixed icon based navbar. but when it come to display, naevbar converted to a grid layout. that is, three columns and two rows grid layout.
Following script I have used for footer nevBar,
<div data-role="footer" class="nav-footer" data-position="fixed">
<div data-role="navbar" class="nav-footer" data-grid="d">
<ul>
<li>H</li>
<li>M</li>
<li>A</li>
<li>T</li>
<li>S</li>
</ul>
</div>
</div>
but it render as follows.
<div class="nav-footer ui-bar-a ui-footer ui-footer-fixed fade ui-fixed-overlay" data-position="fixed" data-role="footer" role="contentinfo">
<div class="nav-footer ui-navbar" data-grid="d" data-role="navbar" role="navigation">
<ul class="ui-grid-b">
<li class="ui-block-a">XXX</div>
<li class="ui-block-b">...</div>
<li class="ui-block-c">...</div>
<li class="ui-block-a">...</div>
<li class="ui-block-b">...</div>
</ul>
</div>
</div>
Content of each li as follows.
XXX ==>
<li class="ui-block-a">
<a id="home" class="ui-btn ui-btn-icon-top ui-btn-up-a" data-icon="custom" href="#" data-theme="a">
<span class="ui-btn-inner">
<span class="ui-icon ui-icon-custom"></span>
<span class="ui-btn-text">H</span>
</span>
</a>
</li>
My output shows as two rows and three colomns grid. Please can you find the reason.
Check this out: http://jquerymobile.com/test/docs/buttons/buttons-grouped.html
<div data-role="controlgroup" data-type="horizontal"> your items </div>
You have specify the classes on your li elements to tell how many columns you want
<ul class="ui-grid-b">
<li class="ui-block-a">XXX</div>
<li class="ui-block-b">...</div>
<li class="ui-block-c">...</div>
<li class="ui-block-D">...</div> <--D here, column 4
<li class="ui-block-E">...</div> <--E here, column 5
</ul>
Default number of columns is three I guess, which is why the last two were pushed to the next row.

Resources