App menu root link clickable

Post Reply
Ramakrishna.Jetti
Posts: 4
Joined: 20 May 2022, 18:07

20 May 2022, 18:48

Hi Team,

We have issues with the new menu design in overlay menu style, other menu styles are working fine, In the earlier version-5.0.0 overlay menu style, is working fine without any issues.
After upgrading to the latest version 7.x.x overlay menu style is not working as earlier.
Issue :
  • The root element on click is not working
  • Root element icon disappears
  • Child links are displayed by default. (Expanded)
Menu Type : 3 level structure menu
Example:
  • Home
  • Contact us
  • Theme
    • dark
      • Blue
    • light
      • Blue
In Our case Home, Contact us, Theme links should be clickable, Icons should be visible for root elements, and dark and light menu links should be visible after clicking the Theme root element, but dark and light links are displayed by default and the home button is not clickable.

In the previous version of our below code is working fine
{label: "TODO, icon: PrimeIcons.CALENDAR_PLUS, to: "/todo", id: "menu_todo" }

Can you please check and confirm this stopper for our release.

Thanks
Jetti

mert.sincan
Posts: 5074
Joined: 29 Jun 2013, 12:38

25 May 2022, 11:09

Hi,

This is by design. We have made some changes regarding the menus. So, In order to create the menu structure you want above, you need to create a root object. Exp;

Code: Select all

const menu = [
      { 
          label: 'Root', 
          items: [
              // your old menu structure
          ]
      }
]
Full example;

Code: Select all

const menu = [
    {
        label: 'Root', items: [
            {
                label: 'Favorites', icon: 'pi pi-fw pi-home',
                items: [
                    { label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/' }
                ]
            },
            {
                label: 'UI Kit', icon: 'pi pi-fw pi-star-fill',
                items: [
                    { label: 'Form Layout', icon: 'pi pi-fw pi-id-card', to: '/formlayout' },
                    { label: 'Input', icon: 'pi pi-fw pi-check-square', to: '/input' },
                    { label: "Float Label", icon: "pi pi-fw pi-bookmark", to: "/floatlabel" },
                    { label: "Invalid State", icon: "pi pi-exclamation-circle", to: "/invalidstate" },
                    { label: 'Button', icon: 'pi pi-fw pi-mobile', to: '/button', class: 'rotated-icon' },
                    { label: 'Table', icon: 'pi pi-fw pi-table', to: '/table' },
                    { label: 'List', icon: 'pi pi-fw pi-list', to: '/list' },
                    { label: 'Tree', icon: 'pi pi-fw pi-share-alt', to: '/tree' },
                    { label: 'Panel', icon: 'pi pi-fw pi-tablet', to: '/panel' },
                    { label: 'Overlay', icon: 'pi pi-fw pi-clone', to: '/overlay' },
                    { label: "Media", icon: "pi pi-fw pi-image", to: "/media" },
                    { label: 'Menu', icon: 'pi pi-fw pi-bars', to: '/menu' },
                    { label: 'Message', icon: 'pi pi-fw pi-comment', to: '/messages' },
                    { label: 'File', icon: 'pi pi-fw pi-file', to: '/file' },
                    { label: 'Chart', icon: 'pi pi-fw pi-chart-bar', to: '/chart' },
                    { label: 'Misc', icon: 'pi pi-fw pi-circle-off', to: '/misc' },
                ]
            },
            {
                label: "PrimeBlocks", icon: "pi pi-prime",
                items: [
                    { label: "Free Blocks", icon: "pi pi-fw pi-eye", to: "/blocks", badge: "NEW", },
                    { label: "All Blocks", icon: "pi pi-fw pi-globe", url: "https://www.primefaces.org/primeblocks-react", target: "_blank" }
                ]
            },
            {
                label: 'Utilities', icon: 'pi pi-fw pi-compass',
                items: [
                    { label: 'Icons', icon: 'pi pi-fw pi-prime', to: '/icons' },
                    { label: "PrimeFlex", icon: "pi pi-fw pi-desktop", url: "https://www.primefaces.org/primeflex", target: "_blank" }
                ]
            },
            {
                label: 'Pages', icon: 'pi pi-fw pi-briefcase',
                items: [
                    { label: 'Crud', icon: 'pi pi-fw pi-pencil', to: '/crud' },
                    { label: 'Calendar', icon: 'pi pi-fw pi-calendar-plus', to: '/calendar' },
                    { label: 'Timeline', icon: 'pi pi-fw pi-calendar', to: '/timeline' },
                    { label: 'Landing', icon: 'pi pi-fw pi-globe', url: 'assets/pages/landing.html', target: '_blank' },
                    { label: 'Login', icon: 'pi pi-fw pi-sign-in', to: '/login' },
                    { label: 'Invoice', icon: 'pi pi-fw pi-dollar', to: '/invoice' },
                    { label: 'Help', icon: 'pi pi-fw pi-question-circle', to: '/help' },
                    { label: 'Error', icon: 'pi pi-fw pi-times-circle', to: '/error' },
                    { label: 'Not Found', icon: 'pi pi-fw pi-exclamation-circle', to: '/notfound' },
                    { label: 'Access Denied', icon: 'pi pi-fw pi-lock', to: '/access' },
                    { label: 'Empty', icon: 'pi pi-fw pi-circle-off', to: '/empty' }
                ]
            },
            {
                label: 'Hierarchy', icon: 'pi pi-fw pi-align-left',
                items: [
                    {
                        label: 'Submenu 1', icon: 'pi pi-fw pi-align-left',
                        items: [
                            {
                                label: 'Submenu 1.1', icon: 'pi pi-fw pi-align-left',
                                items: [
                                    { label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-align-left' },
                                ]
                            },
                            {
                                label: 'Submenu 1.2', icon: 'pi pi-fw pi-align-left',
                                items: [
                                    { label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 1.2.2', icon: 'pi pi-fw pi-align-left' }
                                ]
                            },
                        ]
                    },
                    {
                        label: 'Submenu 2', icon: 'pi pi-fw pi-align-left',
                        items: [
                            {
                                label: 'Submenu 2.1', icon: 'pi pi-fw pi-align-left',
                                items: [
                                    { label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 2.1.3', icon: 'pi pi-fw pi-align-left' },
                                ]
                            },
                            {
                                label: 'Submenu 2.2', icon: 'pi pi-fw pi-align-left',
                                items: [
                                    { label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-align-left' },
                                    { label: 'Submenu 2.2.2', icon: 'pi pi-fw pi-align-left' }
                                ]
                            },
                        ]
                    }
                ]
            },
            {
                label: 'Start', icon: 'pi pi-fw pi-download',
                items: [
                    {
                        label: 'Buy Now', icon: 'pi pi-fw pi-shopping-cart', url: ['https://www.primefaces.org/store']
                    },
                    {
                        label: 'Documentation', icon: 'pi pi-fw pi-info-circle', to: '/documentation'
                    }
                ]
            }
        ]
    }
];
Best Regards,

Ramakrishna.Jetti
Posts: 4
Joined: 20 May 2022, 18:07

25 May 2022, 12:29

Thank you for your reply.

If I create a root element like your example it will not work in the other 3 styles ( Horizontal, Static, Slim) Menu.

We are using all menu styles in our application.

Horizontal menu for large devices, other menu styles will change based on the device.

do you have any other solutions like the link is clickable or plain text configuration?


Thanks
Jetti

Ramakrishna.Jetti
Posts: 4
Joined: 20 May 2022, 18:07

03 Jun 2022, 17:53

Hi Team,

Any Update on this issue ?

mert.sincan
Posts: 5074
Joined: 29 Jun 2013, 12:38

06 Jun 2022, 15:07

Hi,

Can you try the updated AppMenu.js below with the menu data above?

Code: Select all

import React, { useState, useCallback, useEffect } from 'react';
import { NavLink } from 'react-router-dom'
import { classNames } from 'primereact/utils';
import { CSSTransition } from 'react-transition-group';
import { Ripple } from 'primereact/ripple';

const AppSubmenu = (props) => {

	const [activeIndex, setActiveIndex] = useState(null);

	const onMenuItemClick = (event, item, index) => {
		//avoid processing disabled items
		if (item.disabled) {
			event.preventDefault();
			return true;
		}

		if (props.innerRoot && props.onRootItemClick) {
			props.onRootItemClick({
				originalEvent: event,
				item: item
			});
		}

		//execute command
		if (item.command) {
			item.command({ originalEvent: event, item: item });
			event.preventDefault();
		}

		if (item.items) {
			setActiveIndex(activeIndex === index ? null : index);
		}

		if (props.onMenuItemClick) {
			props.onMenuItemClick({
				originalEvent: event,
				item: item
			});
		}
	}

	const onKeyDown = (event, item, index) => {
		if (event.key === 'Enter') {
			onMenuItemClick(event, item, index);
		}
	}

	const onMenuItemMouseEnter = (index) => {
		if (props.innerRoot && props.menuActive && isHorizontalOrSlim() && !isMobile()) {
			setActiveIndex(index)
		}
	}

	const isHorizontalOrSlim = useCallback(() => {
		return (props.layoutMode === 'horizontal' || props.layoutMode === 'slim');
	}, [props.layoutMode]);

	const isMobile = useCallback(() => {
		return window.innerWidth < 1025;
	}, []);

	const isHorizontal = () => {
		return props.layoutMode === 'horizontal';
	}
	const isSlim = () => {
		return props.layoutMode === 'slim';
	}

	useEffect(() => {
		if (!props.menuActive && isHorizontalOrSlim() && !isMobile()) {
			setActiveIndex(null);
		}
	}, [props, isHorizontalOrSlim, isMobile]);


	const renderLinkContent = (item) => {
		let submenuIcon = item.items && <i className="pi pi-fw pi-angle-down layout-menuitem-toggler"></i>;
		let badge = item.badge && <span className="menuitem-badge">{item.badge}</span>;

		return (
			<React.Fragment>
				<i className={classNames('layout-menuitem-icon', item.icon)}></i>
				<span>{item.label}</span>
				{submenuIcon}
				{badge}
			</React.Fragment>
		);
	}

	const renderLink = (item, i) => {
		let content = renderLinkContent(item);
		let linkStyle = classNames(item.class, 'p-ripple');

		if (item.to) {
			return (
				<NavLink activeClassName="router-link-active" to={item.to}
					onClick={(e) => onMenuItemClick(e, item, i)} exact role="menuitem"
					target={item.target} onMouseEnter={(e) => onMenuItemMouseEnter(i)}
					className={linkStyle}>{content}
					<Ripple />
				</NavLink>
			)
		} else {
			return (
				<a href={item.url} tabIndex={item.url ? '' : 0} role="menuitem" onClick={(e) => onMenuItemClick(e, item, i)} target={item.target}
					onMouseEnter={(e) => onMenuItemMouseEnter(i)} onKeyDown={(e) => onKeyDown(e, item, i)} className={linkStyle}>
					{content}
					<Ripple />
				</a>
			);

		}
	}
	const isMenuActive = (index) => {
		return activeIndex === index;
	}

	var items = props.items && props.items.map((item, i) => {
		const active = isMenuActive(i);
		let styleClass = classNames(item.badgeStyleClass, { 'active-menuitem': active }, { 'layout-root-menuitem': props.root });
		let tooltip = props.root && <div className="layout-menuitem-root-text" style={{ textTransform: 'uppercase' }}>
			{item.label}
		</div>;

		return <li className={styleClass} key={i} role="none">
			{item.items && props.root === true && <div className='arrow'></div>}
			{renderLink(item, i)}
			{tooltip}
				<CSSTransition classNames="layout-submenu-container" timeout={{ enter: 400, exit: 400 }} in={item.items && (props.root && !((isHorizontal() || isSlim()) && !isMobile() && (!isSlim() || (isSlim() && activeIndex !== null))) ? true : active)} unmountOnExit>
					<AppSubmenu items={item.items} onMenuItemClick={props.onMenuItemClick} layoutMode={props.layoutMode}
						menuActive={props.menuActive} parentMenuItemActive={active} />
				</CSSTransition>

		</li>
	});

	return items ? <ul role="menu" className={props.className}>{items}</ul> : null;

}

const AppMenu = (props) => {
	const items = props.model && props.model[0] ?  props.model[0].items || [] : [];
	return <AppSubmenu items={items} className="layout-menu layout-main-menu clearfix"
		menuActive={props.active} onRootItemClick={props.onRootMenuItemClick}
		onMenuItemClick={props.onMenuItemClick} root={false} layoutMode={props.layoutMode}
		parentMenuItemActive={true} innerRoot={true} />
}

export default AppMenu;


Ramakrishna.Jetti
Posts: 4
Joined: 20 May 2022, 18:07

09 Jun 2022, 13:28

Thank you for your response.

We are using apollo react 7 version source code with the below small change in the AppMenu js file. it is working fine.

AppMenu.js --> <AppSubmenu --> root={false}

mert.sincan
Posts: 5074
Joined: 29 Jun 2013, 12:38

18 Jun 2022, 01:11

Thanks a lot for the update!

Best Regards,

Post Reply

Return to “Apollo - PrimeReact”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest