How to close SideMenu on click outside

Hi,
How to close the Sidemenu when we click outside the Menu (like lost focus)… i.e., when clicked in any other part of the screen…

Hi,

Could you clarify which SideMenu do you use, responsive or not?

Hi, Yes, I’m using Main Screen with Responsive side menu, I want the menu to be close automatically when i click the screen portion… (Currently i must click the MobileMenuButton to open/close the menu)

It will be very handy if the menu closes by itself when i click the outside portion of the menu…

I have attached the image for better understanding…

Thanks…Screenshot%20from%202019-10-04%2011-31-57

Hi…
Sorry can anyone suggest me to close the menu bar automatically, when i click the mouse pointer outside the menu bar…?cuba-template.zip (118.3 KB)

I have also attached the Template Project for your consideration…

Hello @Narayanan

Sorry for waiting. I’ll prepare an example and describe solution soon.

Regards,
Daniil

1 Like

Since we have no ability to add event listeners on server-side code, we have to add web-toolkit module. You can do it via Studio (CUBA → Advanced → Manage modules → Create ‘web-toolkit’ module).

We’ll use Vaadin Extensions mechanism to create an extension that will track clicks and notify server if work area is clicked. Let’s begin with server-side extension class:

package com.company.cubatemplate.web.widgets;

import com.company.cubatemplate.web.widgets.client.workareaext.WorkAreaClickExtensionServerRpc;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.Extension;
import com.vaadin.ui.Component;

public class WorkAreaClickExtension extends AbstractExtension {

    protected Runnable clickHandler = null;

    public WorkAreaClickExtension(AbstractClientConnector target) {
        super(target);

        registerRpc((WorkAreaClickExtensionServerRpc) () -> {
            if (clickHandler != null) {
                clickHandler.run();
            }
        });
    }

    public static WorkAreaClickExtension get(Component component) {
        for (Extension e : component.getExtensions()) {
            if (e instanceof WorkAreaClickExtension) {
                return (WorkAreaClickExtension) e;
            }
        }
        return new WorkAreaClickExtension((AbstractClientConnector) component);
    }

    public void setClickHandler(Runnable clickHandler) {
        this.clickHandler = clickHandler;
    }
}

It enables us to add click handler that will be used to hide side menu.

WorkAreaClickExtensionServerRpc is an interface that represents server RPC to notify server side code that click performed:

package com.company.cubatemplate.web.widgets.client.workareaext;

import com.vaadin.shared.communication.ServerRpc;

public interface WorkAreaClickExtensionServerRpc extends ServerRpc {

    void workAreaClicked();
}

Let’s proceed to client extension class:

@Connect(WorkAreaClickExtension.class)
public class WorkAreaClickExtensionConnector extends AbstractExtensionConnector {

    @Override
    protected void extend(ServerConnector target) {
        subscribe();
    }

    private native void subscribe() /*-{
        var that = this;
        $wnd.addEventListener('click', function (evt) {
            var workAreaClicked = false;

            var el = evt.target;
            while (el != null) {
                if (el.classList.contains("c-app-workarea")) {
                    workAreaClicked = true;
                    break;
                } else {
                    el = el.parentElement;
                }
            }

            if (workAreaClicked) {            
                that.@com.company.cubatemplate.web.widgets.client.workareaext.WorkAreaClickExtensionConnector::clickPerformed()();
            }
        });
    }-*/;

    private void clickPerformed() {
        getRpcProxy(WorkAreaClickExtensionServerRpc.class).workAreaClicked();
    }
}

Client-side extension subscribes for click events and traverses upwards through DOM tree.

Now we can add our extension in ExtMainScreen:

@Subscribe
public void onExtAfterShow(AfterShowEvent event) {
    WorkAreaClickExtension workAreaClickExtension = WorkAreaClickExtension.get(AppUI.getCurrent());
    workAreaClickExtension.setClickHandler(() -> {
        Component sidePanel = sideMenu.getSidePanel();
        if (sidePanel.getStyleName().contains(HaloTheme.SIDEMENU_PANEL_OPEN)) {
            sidePanel.removeStyleName(HaloTheme.SIDEMENU_PANEL_OPEN);
        }
    });
}

Please check attached project for more details:

side-menu-close-by-click.zip (115.3 KB)

Regards,
Daniil

Это всё ещё рабочее решение? Я скопировал в своей проект - не работает. Что означает закомментированная область кода?
/-{

}-
/

Please use english language in this forum.