I’m trying to use LiveViewJS to show/hide hamburger menu options (inspired to do the same as in this video from Tailwind CSS founder where he was using VueJS):
on mobile screen I’ d like to display a hamburger menu
when clicking on a hamburger menu icon a list of menu options/links should be displayed and the icon should change from ‘hamburger’ to the ‘close’
on larger screens, I’d like to display menu options in line.
Kind of a classic layout, right?
I know that I need to check a boolean value in some way to show either the ‘hamburger’ or ‘close’ icon and took a try like that in the root.html.heex template:
def toggle_navbar_menu(js \\ %JS{}, selector) do
js
|> JS.toggle(to: selector) #=> will not do the trick!
end
The above function will not do the trick because:
JS.toggle/1 function will just toggle the element visibility by toggling its display: block attribute
the variable @show_menu is never set/changed
The question I have is how to achieve this behavior.
Which function in JS module to use?
How to set a boolean variable to be able to reuse in the template?
Go for show and hide. You don’t need or want server side state for this sort of thing. The opened/closed state is the visibility of the open/close controls.
Imagine the initial state is closed, there is an icon to click which hides itself, shows the menu, an overlay and a close button. Clicking the close button or overlay shows the open button and hides the menu, overlay and close button.
Sure, I don’t want to manage this state on the server side, that’s why I’d like to use LiveView.JS functions.
So here is what I managed to do at this moment:
I declared a custom fucntion in layouts.ex (no more in core_components because the related HTML code is located in the root.html.heex lauout template):
def toggle_navbar_menu(js \\ %JS{}) do
js
|> JS.toggle(to: "#menu", in: "fade-in-scale", out: "fade-out-scale")
end
Then called this function in the root.html.heex layout:
It works on a mobile screen, - the button does open/hide the menu links, but once I resized the screen to a larger one, the links are no more displayed until I refresh the page. I only happens in case of I trigger the hamburger button. If I just resize the screen larger-mobile/mobile-larger without triggering the button, the menu links are correctly displayed. I can see that the style of the div containing the links was set tp display:none in case of actioning the hamburger button and stayed the same after the resizing to a larger screen.
Here is the full content of the root.html.heex layout: