0

I'm using PrimeFaces 6.2

Hi everyone. As mentionned in the title, I need to open a new tab when a user clicks on a link (which is dynamically generated). I tried 2 solutions for now, and none of them works entirely :

1st solution : attributes url and target in PrimeFaces component

Facelet :

<p:contextMenu id="menuMesure" for="treeVArboParents" nodeType="3">
    <p:menuitem value="OPL" url="#{arboParObjView.sessionService.lienUrl()}" target="_blank"/>
</p:contextMenu>

View :

@Named(value="arboParObjView")
@ViewScoped
public class ArboParObjView implements Serializable
{
    @Inject
    SessionService sessionService;

    private TreeNode selectedNode //changes everytime a node is selected - both right and left clicks work

    ...some code here...

    public void genererLienBirt() //called everytime the selectedNode value is changed
    {
        String libelle="";
        if (selectedNode != null)
        {
            //code to find the id of the associated to the selected node.
            //I need the id because I want to pass it as a parameter of the link
            //And this part of code works well

            sessionService.setIdMesure(idMesure);
        }
    }       
}

Session Service :

@Named(value="sessionService")
@SessionScoped
public class SessionService implements Serializable
{
    private LienURL lienUrl = new LienURL();

    public String lienUrl()
    {
        String lien = "";
        if (idMesure != null)
        {
            lien = lienUrl.getUrl();
            lien += idMesure.toString();
            return lien;
        }
        return "";
    }
}

Bean :

public class LienURL
{
    private String url;

    public LienURL()
    {
        this.url = "myLink&BirtParameter="; //The base link with a Birt parameter waiting for the idMesure to be passed.
    }
}

This solution doesn't work. When the user click on the menu item of the context menu component, it's opening a new tab but the opened page is the same as the one the user just leaved. I think that's because the PF's attribute url loads the url once (and the first time, my url is null because the idMesure isn't filled yet), and it just ignores the good link I try to pass after idMesure is filled.

2nd solution : use the redirect of the FacesContext

Facelet :

<p:contextMenu id="menuMesure" for="treeVArboParents" nodeType="3">
    <p:menuitem value="OPL" actionListener="#{arboParObjView.sessionService.lienUrl()}" />
</p:contextMenu>

Service :

@Named(value="sessionService")
@SessionScoped
public class SessionService implements Serializable
{
    private LienURL lienUrl = new LienURL();

    public void lienUrl() throws IOException
    {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        String url = lienUrl.getUrl()+idMesure.toString();
        ec.redirect(url);
    }
}

The bean and the view don't change. It's the same as in the 1st solution. The second solution works better than the first one. It is opening the good page with the good url, but in the same tab as the page where the user was. Is there a way to use the FacesContext redirect, but in another tab, as the target="_blank" do (the target only works with the url attribute) ? Or is there a way to make the url attribute read other urls than the first passed (which is null) ?

Thanks, and excuse my english.

Galabrok
  • 21
  • 7
  • Your second solution is using the redirect of the ServletContext (that is what the external context is). So you don't do JSF redirect here. See https://stackoverflow.com/questions/15521451/how-to-navigate-in-jsf-how-to-make-url-reflect-current-page-and-not-previous-o – Kukeltje Oct 31 '18 at 07:47

2 Answers2

0

Please use target="_blank" in p:menuitem only in second solution and it should work.

Below is updated code

<p:contextMenu id="menuMesure" for="treeVArboParents" nodeType="3">
    <p:menuitem value="OPL" actionListener="#{arboParObjView.sessionService.lienUrl()}" target="_blank" />
</p:contextMenu>

and

public void lienUrl() throws IOException
    {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        String url = lienUrl.getUrl()+idMesure.toString();
        ec.redirect(url);
    }
Avanish
  • 1
  • 1
  • It doesn't work because the **target** attribute does nothing without the **url** attribute. Thanks for your help anyway – Galabrok Nov 05 '18 at 08:46
0

Thanks to all the contributors for their help. Solution below :

View :

@Named(value="arboParObjView")
@ViewScoped
public class ArboParObjView implements Serializable
{
    @Inject
    private TreePodeService treePodeService;

    private TreeNode selectedNode;
    private Integer idMesure;
    private String lienOplBirt;

    ...

    //redirect to the generated link (called by the UI)
    public void redirectOpl()
    {
        try {
            FacesContext.getCurrentInstance().getExternalContext.redirect(lienOplBirt);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //generate the Birt Link
    public void genererLienBirt()
    {
        String libelle = "";
        if (selectedNode != null)
        {
            libelle = selectedNode.getData().toString();
            VArboParObjectifsParents mesureSelected = treePodeService.getPodeArboObjParentDao().findByLibelle(libelle);
            idMesure = mesureSelected.getIdRoot();
        }

        lienOplBirt = "https://theLinkToPass"+"&RP_idMesure="+this.idMesure;
    }

    ...

    //Execute the genererLienBirt() method everytime selectedNode's value changes
    public void setSelectedTreeNode(TreeNode selectedNode) {
        if (selectedNode !=  this.selectedNode)
        {
            this.selectedNode = selectedNode;
            genererLienBirt();
        }
        this.selectedNode = selectedNode;
    }
}

Facelet (UI)

<p:menuitem value="OPL" includeViewParams="true" action="#{arboParObjView.redirectOpl()}" ajax="false" />
Galabrok
  • 21
  • 7