Change behavior of menu element

Currently the when you click the menu link to the page you’re already on, it does nothing.
Normal link doesn’t behave like this. I expect it to load the link no matter what page I’m on.
I want my site menu to behave like a normal link; to actually load the link I click, regardless of what page I’m on.

I’ve contact Wix support already and the answer is that this is how menu element in Wix behave. There’s nothing they can help and suggest I check out Corvid forum.

I am asking for any advice regarding this issue. I looked up API and the only thing relating to menu is ‘MenuContainer’ element which is a ‘mobile’ thing. Its properties/functions doesn’t seems to be able to help me circumvent this issue. I have tried using buttons and surprisingly they don’t load the link of the page I’m already on either. Strange. Going lightbox-menu workaround is another option but I want to stick with normal top menu.

Thank you in advance. Cheers!
Nik

I think the only thing you can do is to create a custom menu of your own, then you’ll be able to do whatever you want using code.

P.S.
I also use a custom menu, because it’s much more flexible, so I can design it as I like, show different pages to different users, pass query parameters to the target page, pop up a pre-loader etc… The built-in menu is just too limited…

Thanks for your suggestion. May I ask how do you create custom menu? Is it putting together text links, buttons, and other stuffs to make a site menu? Or to build it using Corvid 100%?

Because, menu element, buttons, and text links all behave the same when pointing to the page you’re already on, aka. location(this). When clicked, they does nothing. I just want them to load the link I point them to, regardless of location.

I’m a noob coder, learning as I go. So I’m incompetently unable to imagine creating site menu using Corvid solely. Could you please advise?

@thanikphoto if you create a lighbox, you can put there buttons, texts etc… then you can use Corvid to control the behavior. For example, you can use wixLocation.to(wixLocation.url) to refresh the current page.

@thanikphoto When you use a button that links to the current directory, it won’t reload it but instead go to the top of the page.

When you use a text’s html tag to link the page, even if it is to the current directory, it will always reload the page like you want.

@skmedia Oh yeah, I didn’t even notice that it go to the top of the page. Maybe the 2 pages I tested this were too short. But then can’t we already do this with “back to top” Wix app?
If it’s a link, I expect it to behave like a link though, that’s why I have a problem with it.

I tested text link like this: added a text from the menu, select a word, click ‘link’ in the text settings panel, choose to link to the current page I’m on. And test is on published version, not just preview. Does this method not creating syntax? If yes, why doesn’t it behave like one then?

@jonatandor35 Thanks for the refresh/reload function! I found this on my own right before you posted and tested it and it worked. Now I have to find a way to check if the link points to current page so the reload function would trigger only with that link.

@thanikphoto first get the current path:
let currentPath = wixLocation.path[0];
Then compare it to the link

@jonatandor35 Thanks for the idea guideline. I put 3 buttons into a box and put it in the header section as a menu. I put the following code in site-wide section. I seems to work without a hitch as far as I see.

export function checkPath(path) {
//function to compare current path and link path
    let currentPath = wixLocation.path[0]; 
    //get the current path. expect string "path"
    console.log("Current path = " + currentPath);  //log for debugging
    console.log("Link path = "+ path);  //log for debugging
    if (path === currentPath) {
        console.log("same path");  //log for debugging
        wixLocation.to(wixLocation.url);  //return reload function
    }
    else {
        console.log("different path");  //log for debugging
        wixLocation.to("/" + path);  //return original path with "/" added in front
    }
}

export function button8_click(event) {
    //call checkPath function. button.link returns "/path" so need to remove "/" first
    checkPath($w('#button8').link.slice(1));
}

export function button7_click(event) {
    checkPath($w('#button7').link.slice(1));    
}

export function button9_click(event) {
    checkPath($w('#button9').link.slice(1));
}

How does it look? Any advice on improving the code is very welcomed.

@thanikphoto you forgot to declare the path variable.
To make it simpler, maybe try something like:

import wixLocation from 'wix-location';
let menuButtons = [
    {
       "_id": "button1",//use the property ID
       "link": "/categoires"//use your page path
    },
    {
       "_id": "button2",
       "link": "/about"
    },
    {
       "_id": "button3",
       "link": "/contact"
    }
    ]
$w.onReady(function () {
   let currentPageButton = menuButtons.find(e => e.link === "/" + wixLocation.path[0]);
    currentPageButton.link = wixLocation.url;//sets the full url for current page button
    let buttonSelector = menuButtons.reduce((e1, e2) => e1 + `#${e2._id},`,"");
    buttonSelector = buttonSelector.substring(0, buttonSelector.length -1);
    $w(buttonSelector).onClick((event) => {
    let clickedButton = menuButtons.find(e => e._id === event.target.id);
    wixLocation.to(clickedButton.link);
    })
});
  • be sure to remove the links from the button (on the editor)

@jonatandor35 Appreciate the sample code you provide. I took your code and use it without changing anything (except button ID and page path) and it works perfectly. However, since I’m pretty noob, I had a slightly difficult time understanding it. On the bright side, I learnt a lot of new things such as ‘Arrow Function’ and ‘String Literals’.

I’m still confused ‘how’ this line work:

let buttonSelector = menuButtons.reduce((e1, e2) => e1 + `#${e2._id},`,"");

I understand that it goes through menuButtons array (which has ‘_id’ and ‘link’) and gives out just ‘_id’ part of it, which will be used in $w selector after this. But ‘how’ does it work? The string literal part throws me off even more. What does #${e2._id} means when it works. I’ve read through the whole MDN page (Array.prototype.reduce() - JavaScript | MDN) but still don’t 100% grasp how it works, specifically in this(my) case.

@thanikphoto The purpose of this line is to loop through the buttons array and create a string of the button id’s like:
#button1, #button2, #button3
If you have only 3 buttons you can delete this line (and the successive substring() method), and instead to write:

let buttonSelector = "#button1, #button2, #button3";

The only reason I wrote it is to make my code general and let it work with any unlimited number of buttons (if you have for example 20 buttons, you won’t like to specify each of them explicitly)

@jonatandor35 I kinda get it now. I agree with how you wrote it to work with unlimited number of buttons. I wouldn’t have think like that and would’ve just list all 3 buttons in the selector instead.

Excuse me for asking a lot. So the breakdown of this line is like this?

let buttonSelector = menuButtons.reduce((e1, e2) => e1 + `#${e2._id},`,"");

e1 is accumulated value aka. the result of every loop
e2 is array index which will move by 1 position every loop
initialValue is empty string

So for every loop (ie. first loop):
e1 = empty string
e2 = {“button1”, “/path1”}
the reduce() function will return “e1” follow by what’s in the string literal part which is “#” follow by the first value of e2 object which is “button1”, therefore e1 = “#button1

Do I get this right?

@thanikphoto on the first round it’ll be an empty string + “#” + button1 Id + “,”
on round 2 it’ll be the result of round1 + “#” + button2 Id + “,”
etc…
Then after the looping, I removed the last comma from the string using substring() method (I’m not sure it’s necessary. It depends on what Corvid really does under the hood, but I didn’t have time to test it, so I’ve added it anyway).

@jonatandor35 It works perfectly the way you wrote it. But as you said, without thorough testing, Corvid might be smart enough to ignore the last comma and we don’t really need substring() at all.

Let me get this straight. Reduce() function spits out string of “#button1, #button2, #button3,”. Use substring() to take out the last comma, hence: “#button1, #button2, #button3”. Which eventually becomes an array?

@thanikphoto this particular reduce() string indeed the string you described as an output, and you use in the event handler: $w(stringOfElements).onClick().

[We can try guessing how exactly Corvid processes it under the hood, but it’ll be only a guess.]

hi @JD this is a great suggestion, I only have one issue and that is that you cant use the rest of the page whilst using a lightbox overlay since the background is transparent but still there. how would you fix this issue. thnx!

@matthias-dedeyn69559 Instead of a lightbox, you can use a regular box and make it global. And colapse-expand it when needed.