Limiting the number of open tabs

There are several links on the web page.

In the right click there is an option "open link in new tab" (browser option).

I want to restrict the user not to open more than two tabs? How can i do this?

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<ul>
<li><a href="http://localhost:8080/struts_tab/abcForm1.action" oncontextmenu="return false;"><span>First Click[Right Click disabled]</span></a></li>
<li><a href="http://localhost:8080/struts_tab/defForm2.action"><span>Second clieck[Not more than 2 tabs]</span></a></li>
</ul>
</body>
</html>

      

+3


source to share


1 answer


You cannot prevent a user from opening a new tab.
(This reminds me of old popups with no buttons, no address bar, but still responds to backspace and other events)

However, you can make your application recognize the attempt to open a third tab and load a different result, such as an error message like:

The maximum allowed limit for open tabs has been reached. Use no more than two tabs at a time.close this tab

You can use HTML5 sessionStorage for this .
Note. Web storage ( sessionStorage

and localStorage

) is now supported in every browser .sub>

sessionStorage

It is a global object ( sessionStorage

) that keeps the storage area available throughout the page session . The page session lasts as long as the browser is open and survives on the page reloads and restores. Opening the page in a new tab or window will result in a new session to be initiated .



Then you can

  • if not in sessionStorage, generate a unique token in JSP and put it in sessionStorage,

    $(function(){
        // Read the ID. If it null, this is a new tab: 
        // generate the ID and store it for later.
        var tabId = sessionStorage.getItem("tabId");
        if (tabId == null){
            tabId = Math.random();
            sessionStorage.putItem("tabId",tabId);
        }
    
          

  • send it back to action

        // Add the ID to the form (as hidden field), 
        // so it will be posted back in next submission.
        $('<input>').attr('type'  , 'hidden')
                    .attr('name'  , 'tabId')
                    .attr('value' , tabId)
        .appendTo('form');
    });
    
          

    maybe for a setter in BaseAction, expand with other actions and read prepare()

    or much better in Interceptor ;

  • put it in the collection, making sure it doesn't already contain two elements, otherwise return the error result, which should be displayed globally:

    public String intercept(ActionInvocation actionInvocation) throws Exception {
        Action action = (Action) actionInvocation.getAction();
        if(action instanceof LimitedTabsAware){ //interface to identify special actions
            ActionContext context = actionInvocation.getInvocationContext();
            Map<String, String[]> request = ((HttpServletRequest) 
                                context.get(StrutsStatics.HTTP_REQUEST)).getParameterMap();
    
            if (request.containsKey("tabId")){              
                String tabId = (String) request.get("tabId")[0];
                List<String> openTabs = context.getSession().get("OPEN_TABS_KEY");
    
                if (openTabs.contains(tabId)){
                    return actionInvocation.invoke();                   
                } else if (openTabs.size()>=2){
                    return "tabLimitExceeded"; // global result
                } else {
                    openTabs.add(tabId);
                    context.getSession().put("OPEN_TABS_KEY", openTabs);
                    return actionInvocation.invoke();
                }
    
            } else {
                throw new IllegalArgumentException("There is no tabId in this request.");
            }
        } else {
            return actionInvocation.invoke();
        }
    }
    
          

Then you must find a way to recognize when the tab is closed (to free up one slot), either:

  • determining the expiration time of the items in your collection (if you don't use the tab for some time, the session will expire and therefore a token in the collection must be executed)
  • otherwise a javascript AJAX timer on your page (for example every 30 seconds) that sends a signal keep-alive

    to an action to update the element's expiration date. If the tab is closed, the signal is no longer sent.
+3


source







All Articles