Angular lazy-load Module and Document Status after loading - javascript

I am building application and I am using lazy-load modules, using ngx-datatable I am listening to the right click event on ROWs and Header to show context Menu
The event capturing the mouse position correctly related to document, however it works only in the first load with refresh then the context menu is changing the position after navigation between the components.
After long debugging I found that with the first load, document coordinates zero position is start from top left corner of the document and after the module already loaded and I will navigate between the components the zero position is start from top left corner to the main component of the lazy-loaded module so the menu is not showing in the correct place
any solution or advice ... !?
Menu HTML
<ngx-datatable
[rows]="users"
class="bootstrap"
columnMode="force"
[footerHeight]="50"
[rowHeight]="50"
[limit]="10"
[selected]="selected"
[selectionType]="SelectionType"
(activate)="activated($event)"
(tableContextmenu)="onTableContextMenu($event)"
>
......
</ngx-datatable>
<ul #tableBody class="dropdown-menu">
<li><a class="dropdown-item"><i class="mdi mdi-pencil mrg-right-10"></i> <span i18n>Edit</span></a> </li>
<li class="dropdown-divider"></li>
<li><a class="dropdown-item"><i class="mdi mdi-account-lock-open mrg-right-10"></i> <span i18n>Activate</span></a> </li>
<li><a class="dropdown-item"><i class="mdi mdi-account-lock mrg-right-10"></i> <span i18n>Deactivate</span></a> </li>
</ul>
Component Logic
#ViewChild('tableBody') menuBody: ElementRef<HTMLUListElement>;
.....
onTableContextMenu(e: any) {
if (e.type == 'body') {
this.menuBody.nativeElement.style.position = 'fixed';
this.menuBody.nativeElement.style.top = e.event.y + 'px';
this.menuBody.nativeElement.style.left = e.event.x + 'px';
this.menuBody.nativeElement.className += ' show';
e.event.preventDefault();
e.event.stopPropagation();
}
}

Related

jQuery div show on hover with some elements

I have a navigation with two div's and some UL inside it. I want to have the second column hidden and make it to appear only on hover. Moreover it should display only UL which attribute "data-category-id" is the same as "data-parent-category-id". For some reason that is beyond my power I need to make this using jQuery. Some smooth animation would be nice as well.
Here is a code I already created, but it obviously has some issues. For some reason When I mouseenter element that should make the second column appear it keeps showing and hiding.
const itemLevelOne = $('.cs-navigation__item--level_1');
const itemLevelTwo = $('.cs-navigation__item--level_2');
const menuLevelThree = $('.cs-navigation__column___third');
itemLevelTwo.hide();
menuLevelThree.hide();
itemLevelOne.mouseenter(function () {
var attr = $(this).attr('data-category-id');
if (typeof attr !== 'undefined' && attr !== false) {
itemLevelTwo.each(function () {
if ($(this).attr('data-parent-category-id') === attr) {
$(this).show('200');
menuLevelThree.show('200');
} else {
$(this).hide('200');
menuLevelThree.hide('200');
}
});
}
});
I also created a codepen with some HTML code for so it is quite similar to what i have on my website. The second column should appear only when you HOVER on "El Hover" and "El Hover 2". In any other scenario it should be hidden.
https://codepen.io/bordini/pen/GRXgNEo
Hope there is some good soul that will be able to help me resolve this issue. Thank you very much!
Your problem is you have the <UL> of level 2 encapsulated in a <DIV> with class cs-navigation__column___third (HTML line 24) so it's part of your menuLevelThree. The menuLevelThree you keep show() and hide() - ing in the event handler for each item of level two which is why the entire level two menu is flickering.
Maybe you misplaced the level 3 DIV?
I commented out your menuLevelThree manipulation in the event handler and changed the first call to .show() to make it visible initially and now level 2 menu shows. Now you need to also implement an mouseleave event handler to hide the level 2 menu.
Oh, and if you are open to using jQuery-UI you may want to consider the https://jqueryui.com/menu/ widget - then you don't need to manually handle the showing and hiding of menu items. However I think you'll need to construct your menu structure hierarchically (level 2 is child of top level and level 3 is child of one particular level 2).
const itemLevelOne = $('.cs-navigation__item--level_1');
const itemLevelTwo = $('.cs-navigation__item--level_2');
const menuLevelThree = $('.cs-navigation__column___third');
itemLevelTwo.hide();
menuLevelThree.show(); // change to show()
itemLevelOne.mouseenter(function () {
var attr = $(this).attr('data-category-id');
if (typeof attr !== 'undefined' && attr !== false) {
itemLevelTwo.each(function () {
if ($(this).attr('data-parent-category-id') === attr) {
$(this).show('200');
// menuLevelThree.show('200');
} else {
$(this).hide('200');
//menuLevelThree.hide('200');
}
});
}
});
nav {
display: flex;
}
.cs-navigation__column___second{
background: red;
}
.cs-navigation__column___third{
background: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<div class="cs-navigation__column cs-navigation__column___second cs-navigation__extras" style="width: 291.16px;">
<ul class="cs-navigation__list cs-navigation__list--level_1" data-parent-item-id="7" style="column-count: 1; width: 150px;">
<li class="cs-navigation__item cs-navigation__item--level_1">
El 1
</li>
<li class="cs-navigation__item cs-navigation__item--level_1">
El 2
</li>
<li class="cs-navigation__item cs-navigation__item--level_1" data-category-id="57">
<a href="#" class="cs-navigation__link cs-navigation__link--level_1">
El Hover</a>
</li>
<li class="cs-navigation__item cs-navigation__item--level_1" data-category-id="60">
<a href="#" class="cs-navigation__link cs-navigation__link--level_1">
El Hover 2</a>
</li>
<li class="cs-navigation__item cs-navigation__item--level_1">
El 3
</li>
</ul>
</div>
<div class="cs-navigation__column cs-navigation__column___third cs-navigation__extras" style="width: 150px;">
<ul class="cs-navigation__list cs-navigation__list--level_2" data-parent-item-id="57">
<li class="cs-navigation__item cs-navigation__item--level_2" data-category-id="32" data-parent-category-id="57">
1
</li>
<li class="cs-navigation__item cs-navigation__item--level_2" data-category-id="32" data-parent-category-id="57">
2
</li>
<li class="cs-navigation__item cs-navigation__item--level_2" data-category-id="32" data-parent-category-id="57">
3
</li>
</ul>
<ul class="cs-navigation__list cs-navigation__list--level_2" data-parent-item-id="60">
<li class="cs-navigation__item cs-navigation__item--level_2" data-category-id="34" data-parent-category-id="60">
1
</li>
<li class="cs-navigation__item cs-navigation__item--level_2" data-category-id="34" data-parent-category-id="60">
2
</li>
</ul>
</div>
</nav>

Creating sub menu below toggle menu item for mobile versions

I use the following code to create a toggle menu for mobile versions and It works fine but I want to generate a sub menu below a menu item. For example I want to have to create two sub tabs for SERVICES item like New and Used to be appeared only when the user clicks on SERVICES. Anybody can help me doing this?
HTML
<nav id="navigation">
<a class="menu_button" href="#footer_nav" onclick="toggleNav(); return false;">☰ MENU</a>
<ul id="navigation_list" role="navigation">
<li><a href=#>HOME</a></li>
<li><a href=#>SERVICES</a></li>
<li><a href=#>WORK</a></li>
<li><a href=#>CONTACT</a></li>
</ul>
</nav>
Javascript
var originalNavClasses;
function toggleNav() {
var elem = document.getElementById('navigation_list');
var classes = elem.className;
if (originalNavClasses === undefined) {
originalNavClasses = classes;
}
elem.className = /expanded/.test(classes) ? originalNavClasses : originalNavClasses + ' expanded';
}
From http://blog.g-design.net/post/42617934013/create-an-accessible-toggle-menu-for-mobile
Thanks
You simply just create another list inside of the SERVICES list item. You can initially hide the list, and when you want to see it, via clicking, you just display it.
<nav id="navigation">
<a class="menu_button" href="#footer_nav" onclick="toggleNav(); return false;">☰ MENU</a>
<ul id="navigation_list" role="navigation">
<li><a href=#>HOME</a></li>
<li id="services-item">SERVICES
<ul id="sub_list" style="display: none;">
<li>NEW</li>
<li>USED</li>
</ul>
</li>
<li><a href=#>WORK</a></li>
<li><a href=#>CONTACT</a></li>
</ul>
</nav>
If you want to see the list when you click SERVICES, you need to add javascript, or a JS library, to do so:
//jQuery
$('#services-item').on('click', function() {
$('#sub-list').toggle();
)};
This method does not allow SERVICES to direct the user to a page. If you need it to direct a user to a page, then just add an icon beside the SERVICES text that toggles the sub-list when clicked.

Removing and adding Classes on Dropdown Menus on Hover

I have a Navigation built that have drop down menus,
HTML STRUCTURE LIKE SO
<li class="c-header__subnav-item c-header__subnav-item-is-hidden c-header__subnav-item-is-visible-md">
<a class="c-header__subnav-links u-caps js-c-header__subnav-trigger" href="#">
Action Review Review
<i class="fa fa-angle-down fa-lg c-btn__icon-right-sm"></i>
</a>
<ul class="c-header__subnav-dd">
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Overview
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Review Form
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Performance Card
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Recent Recordings
</a>
</li>
</ul>
</li>
When You Hover On the a.js-c-header__subnav-trigger
It addes a class to its self as well as its sibling ul ( the dropdown menu)
This is perfect but since the hover is triggered on the 'a' element If I toggle the class when and I go to hover on the drop down menu it gets removed before I can because of hovering off the 'a' element.
If I just add the classes and do not use toggle how would I remove both classes once I hover off the A element or Dropdown menu.
What needs to be achieved is
1.) If main nav link is hovered add an active class to itself and drop down is triggered and can be seen. If you hover out WITHOUT engaging the dropdown both active and dropdown class are removed
2.) If main nav link is hovered add an active class to itself and if dropdown IS engaged by user keep both classes until dropdown is hovered out of or 'A' Element.
CURRENT JQUERY CODE
;(function($, window, document, undefined) {
var $win = $(window);
var $doc = $(document);
var $classes = {
SubNavTrigger : 'js-c-header__subnav-trigger',
SubNavItemActive : 'c-header__subnav-item-is-active',
SubNavDropDown : 'c-header__subnav-dd',
SubNavDropDownActive : 'c-header__subnav-dd-is-active'
};
var _isMobile = false;
_isMobile = ($win.width() <= 1024) ? true : false;
// Check if user is on touch on page load
// if isMobile use click events
// if not mobile use hover events
if(_isMobile) {
$("." + $classes.SubNavTrigger).on('click', function(){
if ( $(this).hasClass( $classes.SubNavItemActive ) ){
// If Item has active class removeClass
$(this).removeClass( $classes.SubNavItemActive )
} else {
// If Item does not have active class addClass
$(this).addClass($classes.SubNavItemActive);
} //End if
// Add Active Class To Subnav.
$(this).siblings().toggleClass($classes.SubNavDropDownActive);
});
} else {
$("." + $classes.SubNavTrigger).on('hover', function(){
$(this).addClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
// If set to toggle impossible to hover on this menu.
$(this).siblings().addClass($classes.SubNavDropDownActive);
});
}
})(jQuery, window, document);
Thanks In Advance for any help.
Live Site Link to see
http://100dc.vincebrown.me/integrity-pledge
So I would make a few changes, I would move the s-c-header__subnav-triggerclass to the parent li. I would then change the jquery to use the hover(in,out). The in function would look something like
function () {
$(this).addClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
$(this).children().addClass($classes.SubNavDropDownActive);
}
and the out
function () {
$(this).removeClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
$(this).children().removeClass($classes.SubNavDropDownActive);
}
Here is a jsfiddle

jQuery adding active class to nav, now nav not working

So, I'd like my breadcrumb nav to show the user which page he/she is on by having the be a different color according to the page they are on. I.e. if on home, the home link is gray whilst the others remain black.
To do this I've added the following code to my app:
$(function(){
$('.breadcrumb li a').on('click', function(e){
e.preventDefault(); // prevent link click if necessary?
var $thisA = $(this);
var $li = $thisA.parent('a');
if (!$thisA.hasClass('active'))
{
$li.find('a.active').removeClass('active');
$thisA.addClass('active');
}
})
})
However, with the above code it never releases the active class when I also click events for example they end up both just being gray. Also, the page doesn't switch it stays on home page but with home and events grayed out.
The css:
.breadcrumb li a.active { color: #999999;}
The html
<ul class="breadcrumb">
<li>
<a class="active" href="/profiles"> Home</a>
</li>
<li>
<a class="active" href="/events"> Events</a>
</li>
<li>
Messages
</li>
<li>
My Profile
</li>
</ul>
Change
var $li = $thisA.parent('a');
to
var $li = $thisA.parents('ul');
because this line
$li.find('a.active').removeClass('active');
looks for a child a.active and your original $li would be null because your original line is trying to find a a that is a parent of the clicked a.
EDIT
Resources on highlighting the current page:
http://hicksdesign.co.uk/journal/highlighting-current-page-with-css
$("a[href*='" + location.pathname + "']").addClass("current"); from highlighting the current page in a list of links using css / html
http://www.eznetu.com/current-link.html#

dynamically update breadcrumb & highlight active color

I am sorry for the title. I don't no how to write the title for the below scenario .
The below question would be easier for an expert. Kindly bear with my English.
I am creating a single page portfolio. In the web site I have top menu,breadcrumb,content & footer.
If i click any menu or submenu the corresponding div is loading properly but I want to change my breadcrumb dynamically based on the menu
Here is the HTML code for top menu
<div id="eyMenuNav">
<ul id="navmenu">
<li class="on">
<a class='link1' href="#first">Article on Technology</a></li>
<li>
<a class="sub" href="#">Success Stories</a>
<ul>
<li>
<a class='link2' href="#second" onclick="onctext();">Customer Quotes</a>
</li>
<li>
<a class='link3' href="#third" onclick="onctext();">CSS, Appreciation - Metrics</a>
</li>
<li>
<a class='link4' href="#four" onclick="onctext();">Lesson Learnt</a>
</li>
</ul>
</li>
<li>
<a class='link5' href="#five">Hexaware Key Contributor</a>
</li>
</ul>
</div>
Here is the HTML code for breadcrumb
<div id="eyBreadCrumb">
<ul>
<li>
<a id="crumb" href="#"><!-- Here I need update my breadcrumb based on the link which i clicked -></a>
</li>
</ul>
<!-- Clearing Element -->
<div style="clear:both;"></div>
<!-- end breadcrumb --> </div>
Here Is the code for javascript which i tried it is working for one menu click but i want for all.
function onctext()
{
document.getElementById("crumb").innerHTML="Success Stories - Customer Quotes";
}
Kindly help me for the above scenario
Note : I am not using jquery only iam working with javascript.
Thanks
Mahadevan
Add this parameter to your onctext() call, so your menu items look like so:
<a class='link3' href="#third" onclick="onctext(this);">CSS, Appreciation - Metrics</a>
And then change your onctext function to retrieve the text from this:
function onctext(elm) {
var text = elm.innerHTML;
document.getElementById("crumb").innerHTML = text;
// set active class
var active = document.getElementsByClassName('active')[0];
if (active) {
active.className = active.className.replace(' active', '');
}
elm.className += ' active';
}

Categories

Resources