nebular icon indicating copy to clipboard operation
nebular copied to clipboard

Nb Menu with query params are highlighting the first one always even if you have more menu items and selected different one

Open Gobikannan opened this issue 5 years ago • 12 comments

Nb Menu with query params are highlighting the first one always even if you have more menu items and different one selected.

https://github.com/akveo/nebular/blob/978a45c33bba40bb01c6f4b4c3b977990d2c291d/src/framework/theme/components/menu/menu.service.ts#L378

I looked at the code and I see the fragment was checked but not query params.

Is this a known issue?

Gobikannan avatar Oct 22 '19 09:10 Gobikannan

Here is the example:

https://nebular-menu-query-params-active.stackblitz.io/about?code=2

https://stackblitz.com/edit/nebular-menu-query-params-active

PFA

image

Gobikannan avatar Oct 22 '19 12:10 Gobikannan

@yggg @nnixaa - any workaround or suggestions on this?

Gobikannan avatar Oct 24 '19 11:10 Gobikannan

Try to use the url propery instead

https://stackblitz.com/edit/nebular-menu-query-params-active-nzzoq5?file=src/app/app.component.ts

AvshT avatar Feb 16 '20 15:02 AvshT

any workaround with this? i can't navigate using url

naonvl avatar Oct 01 '20 03:10 naonvl

@yggg @nnixaa - any workaround or suggestions on this?

AakashShah14 avatar Nov 01 '20 07:11 AakashShah14

@yggg the same issue

Broderick890 avatar Feb 22 '21 08:02 Broderick890

You can always add another path to your routing.module linked to the same component, then you add it to the menu with the query parameter

emicanonica avatar May 23 '21 16:05 emicanonica

any workaround or suggestions on this??

fdiogoc avatar Jul 27 '21 19:07 fdiogoc

Had the same problem:

You can use the fragment attribute of the NbMenuItem.

As you can see in https://github.com/akveo/nebular/blob/master/src/framework/theme/components/menu/menu.service.ts#L396 its used as a unique identifer for every nbmenuitem in the selection

BuddyFloyd avatar Feb 17 '22 15:02 BuddyFloyd

@BuddyFloyd : Do you have an example for this? I have no clue, what to enter as fragment, so that the menu item is selected within the sidebar when using queryParameters.

{
  title: "All tasks",
  link: "/pages/tasks/list"
}, {
  title: "Do immediately",
  link: "/pages/tasks/list",
  queryParams: {
    filter: "filterTasksAllA"
  }
}, {
  title: "Schedule",
  link: "/pages/tasks/list",
  queryParams: {
    filter: "filterTasksAllB"
  }
}

EFritzsche90 avatar Apr 02 '22 23:04 EFritzsche90

Using the fragment property did not work properly for me. When calling a page with queries that was not called from the nebular menu, it still selected the first item.

So i just found a working workaround manipulating the behaviour with one event listener and a little bit of code:

      this.router.events.subscribe((val) => {
        this.selectPageWithQueryParam();
      })

Indirectly, my goal with this trigger is to be able to react to a click in the nebular menu. There's also a onItemClick() event provided by menuService, but in this moment it gets triggered, the link has not changed yet. And it's the already changed link i use in my method. So i think it's the best alternative.

So first i implemented a "hasSameQueryParams"-Method which is checking if a page-item has the same queryParams as the current url.

  private hasSameQueryParams(page: NbMenuItem): boolean {
    let params = this.route.snapshot.queryParams;

    if (Object.entries(params).length == 0 || Object.entries(page.queryParams).length == 0) {
      return false;
    }

    for (const [param, value] of Object.entries(params)) {
      let pageParam = page.queryParams[param];
      if (pageParam != value) {
        return false;
      }
    }

    return true;
  }

If the params are matching i manipulate the menu selection using my second method:

private selectPageWithQueryParam() {
    for (const page of this.pageMenuItems) {
      let sameParams = this.hasSameQueryParams(page);

      if (sameParams) {
        // unselect all unrelevant pages
        this.pageMenuItems.forEach(item => {
          item.selected = false;
        });

        // select page with query
        page.selected = true;
        return;
      }
    }
  }

First i go trough all existing menu pages using a for loop. Next step is comparing the query params with the current url using my first method. If the params are matching i first unselect all pages to ensure that only one page will be selected. And finally i select the right page. Thats it :D

JereSten avatar May 04 '22 16:05 JereSten

@Jere2000 Looks good to me. Only thing is, that my menu item is still not selected, because it is still {selected: false} after set it true. Did you face the same problem?

EFritzsche90 avatar Aug 06 '22 22:08 EFritzsche90