How to get sub-menus to stay on the right side of a base menu? - html

I have a dynamically generated (in Angular) menu and sub menu items with a nested call to the same component. <div> elements create the container and also each menu item. I have some variables with 'V' and 'H' values that allow me to position the menu items Horizontally or Vertically by dynamically creating classes ending by H or V character - these are the css classes:
.menuContainer-V {
display: table;
}
.menuContainer-H {
display: inline-table;
}
.menuItemsContainer-H {
display: flex;
float: left;
flex-wrap: wrap;
}
That is all. (There is no class: "menuItemsContainer-V" because <div> items align naturally).
Here is what I would like to the layout to be:
"Menu A" will have class of: "menuContainer-V".
"Menu B" and all other menus will have class of: "menuContainer-H"
and the containers of their items - class: "menuItemsContainer-H".
At this time this works OK with the classes I specified above - EXCEPT - when the horizontal menu (e.g. "Menu C" has more items to reach the right edge of the view, it will jump to the left edge of the view - below "Menu A". Also, if more menus are produced, when they reach the bottom of "Menu A", they jump below "Menu A".
How can I get all other menus (Menus B, C, D, etc ...) stay on the right side from "Menu A" and never go under it?
Please remember that the component is called recursively (from itself) for each menu, so the container and its content (each menu and items) are re-generated dynamically, so that is the tricky part here from the CSS prospective.
Here is the template (HTML) code:
<!--
This is the first/base/root or the next selected switchboard menu.
If it has .subMenuItems[] - ynBaseItemHasSubMenus,
its sub-menu-items are the items/buttons of the menu
-->
<div [class]="swbPosClass"
[style.margin-top]="swbMarginTop"
[style.margin-left]="swbMarginLeft">
<!-- container of one given menu - including title -->
<div *ngIf="baseMenuItem"
[class]="menuContainerClass">
<!-- This is the header/title of the menu - comes from:
baseMenuItem.displayName -->
<div *ngIf="showMenuTitle && baseMenuItem.displayName"
[class]="headerClass"
(click)="clearChild()">
<!-- <span>{{baseMenuItem.displayName}} - L: {{level}}, {{menuPos}}</span> -->
<span>{{baseMenuItem.displayName}}</span>
<!-- This is a link/small icon to menu options -->
<span class="menu-icon" (click)="openSwbOptionsDialog()">⧎</span>
</div>
<!-- Base container for menu items - they come from .subMenuItems[]
This div serves as container for the Tree menu items
and for the NON-tree menus this div allows this css:
.menuContainer-V { display: table; }
display table properly - items are NOT stretched accross the screen,
instead, all items are sized equally to the width of the item
with longest content.
-->
<div *ngIf="ynBaseItemHasSubMenus">
<!-- Menu items container (for items without title)
arrange the menu items per the specified layout - H, V -->
<div [class]="menuItemsContainerClass">
<!-- menu items temp use: class="tmp4" -->
<div *ngFor="let item of baseMenuItem.subMenuItems; index as itemIx"
[class]="menuItemClasses"
(click)="onItemSelected(item)">
<mat-icon *ngIf="item.iconName"> {{item.iconName}} </mat-icon>
{{item.displayName}}
</div>
</div>
</div>
<!-- doc:
routedOutletPos: Position options for the menu (item's) target pages
1 - pages are displayed below or right from the last sub-menu,
according to the values of: menuPositioning.
The switchboard menus are remain shown / visible.
-->
<div *ngIf="isRoutedItem && routedOutletPos === 1">
<router-outlet></router-outlet>
</div>
</div>
</div>
<!-- doc:
For H or V (horizontal/vertical menus)
while we have sub-menu items we create sub-menus;
nested / recursive sub-menus based on users selection in prev. level item.
DANGER !!! DO NOT REMOVE: *ngIf="ynRecurse"
IT WOULD CAUSE ENDLESS LOOP - RESOURCES DEPLETED DANGER / BROWSER/SYSTEM CRASH
-->
<!-- <div *ngIf="ynRecurse" [class]="swbPosClass"> -->
<libtw-switchboard-a01 *ngIf="ynRecurse"
[baseMenuItem]="selectedItem"
[ynRecurse]="false"
[level]="level">
</libtw-switchboard-a01>
<!-- </div> -->
<!-- doc:
routedOutletPos: Position options for the menu (item's) target pages
2 - pages are displayed below the entire menu structure
- below all sub-menus.
The switchboard menus remain shown / visible.
-->
<div *ngIf="isRoutedItem && routedOutletPos === 2">
<router-outlet></router-outlet>
</div>

Related

Adding elements in scrollable area changes viewport

I have scrollable area.
One button adds elements to start of array, other adds elements to end of array.
Array is rendered inside scrollable area.
Adding elements to end of the array does not change viewport position (desired).
Adding elements to start of the array does change viewport position (not desired).
<template>
<div class="h-[300px] w-[200px] overflow-y-scroll">
<p v-for="(stuff, index) in content" :key="index" >{{stuff}}</p>
</div>
<button #click="this.content.unshift(this.dec--)">Add Content On Start</button>
<button #click="this.content.push(this.inc++)">Add Content On End</button>
</template>
<script>
export default{
data(){
return {
content: [1,2,3,4],
inc: 5,
dec: 0
}
},
}
</script>
Desired outcome is to have viewport fixed when content is added (or removed).
Why is this happening? How can I fix it?

Remove list item from unordered list with chrome extension

I'm really new to this. I'm making an extension for chrome to remove elements from a list depending on a condition. Each item in list has a div tag and div tag has either following class or not_following class. example
<div title="UnFollow" class="following" ... </div>
or
<div title="Follow" class="not_following" ... </div>
I want to remove the item if it has following class. here the code I have so far it works for first item.
var element = document.querySelector("list > li:nth-child(1)");
if(document.querySelector("list > li:nth-child(1) > div.following")){
element.remove();
}
how do I make a loop so it works for every item in the list.

How can I display the current section name in a top dropdown nav using scrollspy?

I want to display the section's name on the dropdown tab using bootstrap scrollspy. When I scroll now, I only see section (which I would exclude) and I would like to see the current section in the dropdown bar as in when its not opened. So when I touch section 2 while scrolling I would like to see section 2 in the dropdown bar on top. At first, of course, I would like the bar to display section 1.
This is my code: https://codepen.io/alyssaalex/pen/rNNGrLy
I would appreciate it if someone could provide some help in this regard. Thanks!
You need to trigger an event on section change. And then get the section name and put on the dropdown title.
add this code in your JS
$(".navbar").on("activate.bs.scrollspy", function(){
$("#section_ddl").html('');
var sections = new Array("Section 1", "Section 2");
var x = $(".nav li.active > a").text();
if(sections.indexOf(x) != -1){
$("#section_ddl").html(x + '<span class="caret"></span>');
}
else {
$("#section_ddl").html('Section <span class="caret"></span>');
}
});
If you add/remove sections, you only need to put section names in the sections array.
Note: section_ddl is the id of the dropdown.
You can see the working example here

How to scroll to an internal anchor link accounting for a sticky top bar?

I'm using Foundation, and would like a sticky top bar with sub links to internal parts of the page. The problem is, if I do it naïvely, i.e.:
<div class="sticky">
<nav class="top-bar" data-topbar role="navigation">
<section class="top-bar-section">
<ul class="left">
<li>Intro</li>
<li>Basic</li>
</ul>
</section>
</nav>
</div>
... not much stuff ...
<a name="/intro"></a>
<h2>Intro</h2>
... much stuff ...
<a name="/basic"></a>
<h2>Basic</h2>
... much stuff ...
... then the top of the page scrolls to the top of the header, which is then obscured by the sticky top bar. See the jsfiddle and click on the top links to see what I mean.
How can I keep a sticky top bar, yet have clicks on the top bar scroll the page such that the header is right below the top bar, instead of obscured?
Solution #1
Add an <h2> style rule to the CSS, something like:
h2 {
margin-top: 30px;
}
Solution #2
If you want to minimise the extra white-space added to the document, you might try something like the following, instead:
a[name]:target {
padding-top: 30px;
}
This will only add white-space to the <a> element which is currently targeted.
I ended up writing a function to do this.
It changes the window location, so acts as if the user clicked an <a href='#internal-ref></a> link.
It scrolls to the link anyway using scrollIntoView() (thanks to this answer for making me aware of its existence).
It then scrolls back by $("nav.top-bar").height() pixels using window.scrollTo().
The code:
function scrollToAnchor(name) {
// change location
window.location = '#' + name;
// scroll to element anyway
var element = $("a[name='" + name + "']")[0];
if (!element) {
console.error("No such anchor with name", name);
return;
}
element.scrollIntoView();
// scroll back to leave room for sticky nav
var stickyNavHeight = $("nav.top-bar").height();
console.log(stickyNavHeight);
window.scrollTo(window.scrollX, window.scrollY - stickyNavHeight);
}
Live demo.

Updating appbar button using flyout menu

I have a question that is probably easy but I'm just overlooking.
So I've created an app bar with a single button on it that creates a flyout menu when pressed. The button is created so that it can hold an image.
<button class="app-button" style="-ms-high-contrast-adjust:none" data-win-control="WinJS.UI.AppBarCommand"
data-win-options="{id:'appButton',icon:'url(images/logo.png)',section:'global', type: 'flyout', flyout:select('#appFlyout')}">
</button>
On my flyout menu, I'm going to populate it with a list of items, but at the moment I've just hard coded a list of images, using CSS to supply an image to each button.
<div id="appFlyout" data-win-control="WinJS.UI.Flyout" aria-label="App Menu" style="visibility: visible;">
<ul class="appList" list-style-type: none style="width: 127.5px;">
<li id="app1List"><button id="app1" class="appButton"></button></li>
<li id="app2List"><button id="app2" class="appButton"></button></li>
<li id="app3List"><button id="app3" class="appButton"></button></li>
<li id="app4List"><button id="app4" class="appButton"></button></li>
<li id="app5List"><button id="app5" class="appButton"></button></li>
<li id="app6List"><button id="app6" class="appButton"></button></li>
</ul>
</div>
For the short term, I just need a way through my JavaScript to update the button on my appbar with the image of the button clicked in the flyout menu. I'm using the blank Windows Store App, so everything is located in default.(css/html/javascript).
I attempted to create a function that would update the button and then add that function to an event listener for app1 so that clicking it would update the appbar image but it wouldn't work. Looking past the poorly constructed list (as I said, it's just a stop gap for the moment), is there a better way to do those or do I need to do it how I thought and add an event listener to each button in the flyout menu?
Consider using WinJS.UI.ListView control for the list in the flyout. Refer a quickstart sample in case you have not used listview earlier.
It can be bound to an list with each item representing a button img. use iteminvoked event handler to set the selected button image, for the appbarcommand in the appbar.
below is not complete code. but part of the code, to give an idea.
var buttonFilePaths = [
{ iconFilePath: '/images/button1.png' },
{ iconFilePath: '/images/button2.png'},
{ iconFilePath: '/images/button3.png'}];
var list = new WinJS.Binding.List(buttonFilePaths);
// bind this list data source to the listview control.
listview.winControl.itemDataSource = list.dataSource;
// register for iteminvoked event when the item is tapped;
listView.addEventListern('iteminvoked', function (event)
{
var selectedIndex = event.detail.itemIndex;
var item = list.getAt(selectedIndex);
appButton.winControl.icon = item.iconFilePath;
});
html:
<div id='listview' data-win-control="WinJS.UI.ListView'
data-win-options="{ tapBehavior: 'invokeOnly', selectionMode: 'none', swipeBehavior: 'none'
, itemTemplate: select('#itemTemplate')}" >
</div>
<div id='itemTemplate' data-win-control='WinJS.Binding.Template'>
<div class='list-item'>
<img data-win-bind='src: iconFilePath' />
</div>
</div>