0

I have problems with the Multi-Window Handling in my appliacation. I currently using Conversation Scope to enable multi window / tab handling but in case the user opens a link (button) in a new tab the conversation is shared between the old and new tab.

Apache Deltaspike has a solution for that (http://deltaspike.apache.org/documentation/#_module_overview) but I already using Seam 3 (and JSF 2.1) and don't want to migrate to Deltaspike.

So I'm searching for an alternative solution without Deltaspike or is it possible to use Deltaspike AND Seam 3?

user1127860
  • 150
  • 2
  • 14
  • If you can, upgrade to JSF-2.2: it handles multiple windows now – kolossus Dec 02 '14 at 16:33
  • After all I've read about this in JSF 2.2 is that not working if the user opens a link/button in a new tab because the window ID will be the same in both tabs. Anyway an update to JSF 2.2 is currently not possible. – user1127860 Dec 04 '14 at 11:57
  • JSF 2.2 just provides a ClientWindow, but it doesn't manage a scope for it. Use DeltaSpike instead of Seam3. DeltaSpike is the future on that road and just awesome! – Dar Whi Dec 05 '14 at 22:50

1 Answers1

0

I build a solution with p:remoteCommand and this answer: In javascript, how can I uniquely identify one browser window from another which are under the same cookiedbased sessionId

I added this JS to my template which creates a unique id for each browswer tab an stores it in the window.name. Then it calls a p:remoteCommand to check the guid:

$(window).load(function() {
    // ----------------------
    var GUID = function() {
        // ------------------
        var S4 = function() {
            return (Math.floor(Math.random() * 0x10000 /* 65536 */
            ).toString(16));
        };
        return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
    };

    if (!window.name.match(/^GUID-/)) {
        window.name = "GUID-" + GUID();
    }

    if ($('#guid_form\\:server_guid').text().length == 0 || 
            $('#guid_form\\:server_guid').text() != window.name) {
        checkGuid([{name:'guid', value:window.name}]);
    }
})

Added a Primefaces remoteCommand to my template which is called by the script above.

<h:form id="guid_form">
    <h:outputText value="#{checkTabAction.guid}" id="server_guid"/>
    <p:remoteCommand name="checkGuid" actionListener="#{checkTabAction.checkGuid}" process="@this" partialSubmit="true" />
</h:form>

And added a check action which validateds the current browser tab / window by comparing the guid's:

@ConversationScoped
@Named(value = "checkTabAction")
public class CheckTabAction implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private Logger log;

    private String guid = null;

    public void checkGuid() {
        Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        String guid = params.get("guid").toString();

        if (this.guid == null) {
            this.guid = guid;
        }

        if (!StringUtils.equals(this.guid, guid)) {
            log.info("New tab detected!");
            throw new NonexistentConversationException("New tab detected!");
        }
    }

    public String getGuid() {
        return guid;
    }

}
Community
  • 1
  • 1
user1127860
  • 150
  • 2
  • 14