How to use h:outputLink without destroying the bean - jsf

Im using a especial protocol (SIP) to open a softphone trough my xhtml page using something like this
<h:outputLink value="sip:123456" />
But is destroying my bean, leaving the page useless, is there a workaround for this? any ideas would be apreciated
pd:i also trying with primefaces.
UPDATE
What scope is your bean?
Is a viewscope, and i dont have to pass any parameters, this is a special protocol sip: , what it does is that it opens a program called softphone
How would you do this is normal html?
I corrected the title thanks, in normal html would be something like this <a href="sip:3378984" > call </a>
When will your bean be destroyed? When the page is shown or if you
click the link? But, you can't click the link because there is no
content to render. How do you check the destroyed bean? Which bean?
when i hit the link it goes to my #Predestroy method, and it opens the softphone program (there is no page to show), after i hit the link the page becomes unusuable, like the links, buttons etc, wont work
i also used primefaces commandlink
<p:commandLink value="prime link" action="#{testBean.redirect()}"/>
public void redirect() throws IOException {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.redirect("sip:123456");
}

So after some reasearch and some comments from previous users i created a script to open the new window and close it after some milliseconds
function clicktocallwindowf(number) {
var wnd = window.open("sip:" + number);
setTimeout(function () {
wnd.close();
}, 10);
return false;
}
<p:commandLink onclick="clicktocallwindowf(#{phonebean.number})" styleClass="Fs16 icon-phone-1"/>
Hope this helps somebody, thank you guys for the comments it gave me more direction!

Related

Bean initialization JSF (Primefaces)

when is a bean initialized? I used #RequestScoped managed bean annotation.
I have a page - products.xhtml and I am redirecting on the same page depending on the version a clicks.
For example, user clicks 2019.000, it redirects to the same page~
/products.xhtml?faces-redirect=true&ver=2019.000
My problem is I have a dialog that opens when a user clicks on a p:commandLink. The bean needed to populate the dialog's contents is DownloadView.java::getRoot().
Here's a snippet of my DownloadView.java.
#ManagedBean(name = "DownloadView")
#ViewScoped
public class DownloadView implements Serializable {
private TreeNode root;
private String path;
public TreeNode getRoot() {
DownloadBI downloadBI = new DownloadBI(modifyPath(this.path));
this.root = downloadBI.getFilesTreeNode();
if (root.getChildCount() != 0)
this.root.getChildren().get(0).setExpanded(true);
return this.root;
}
. . .
The default selection when page loads is 2020.000. The dialog works perfectly fine with the correct target links when loaded from the default selection 2020.000. But, when I redirect to 2019.000 and try to open a dialog, it seems that the bean retained the data from 2020.000.
Here is a snippet of my p:commmandLink calling the dialog from products.xhtml.
<p:commandLink value="#{startup.name}" title="#{startup.name}"
process="#form" update=":download-form:downloadPanel"
oncomplete="PF('downloadDialog').show()" >
<f:setPropertyActionListener target="#{DownloadView.path}" value="#{startup.url}"/>
</p:commandLink>
I was assuming that the value of startup.url should change every time the commandlink is clicked. It does but, its the same value from 2020.000. While testing its behavior, I noticed that the form id is the same from 2020.000 and 2019.000.
From chrome source:
j_idt161:0:j_idt163:1:download-view
is the same when selecting from 2019.000. They should be different since they have different urls.
I thought that this is scoping issue, but I tried all scopes. But, it is still not working.
I am thinking that I should create my DownloadView.java bean only when the commandLink is clicked, and when the dialog is closed, it should also be destroyed. But, I am not sure how to do this as well. :(
I have been debugging this for days now and I'm stuck. I hope someone could give some ideas how to resolve this. I am new to JSF/Primefaces, by the way. Please help!

How to open a blank page for an external url with JSF, if target url must be initialy retained from server?

Primefaces 3.5.14, Omnifaces 1.6
Is there a component in JSF/Prime that looks like a button, but that allows to open a new blank page with an external link ? So unlike a normal link, on click the new page URL must be initialy retained from server and just then new page must be opened. Like a commanButton with an action attribute, where a string result of an action method determine the new url.
Of course I can use p:button as in Styling one JSF external link to make it look like a button but in that case I must update link generated by p:button, depending on actions made on the page every time. This is not always desirable.
You need target="_blank" on the parent form in order to submit into a new window and you need to invoke ExternalContext#redirect() (or OmniFaces' Faces#redirect()) in the action method in order to let the target window send a new GET request on the given URL. Importantly, when you use <p:commandButton> instead of <h:commandButton>, you also need to set ajax="false" because it doesn't respect target="_blank".
Thus, so:
<h:form target="_blank">
<p:commandButton value="Submit" action="#{bean.submit}" ajax="false" />
</h:form>
with
public void submit() throws IOException {
String redirectURL = determineItSomehow();
Faces.redirect(redirectURL);
}

CommandButton open new tab with FlashScope parameters

How can I open new tab when user clicks p:commandButton? I also want to pass some parameters to new page using FlashScope. Here's the code:
<h:form>
<p:commandButton value="open new tab" action="#{myBean.newTab}"/>
</h:form>
public String newTab() {
Faces.setFlashAttribute("foo", bar);
return "otherView";
}
On the otherView page I use f:event type="preRenderView" to read Flash parameters.
Two notes:
I need to use FlashScope, not URL parameters.
If possible, I don't want to change newTab() and preRenderView() methods.
Thanks for help
Use target="_blank" on the form to tell the browser that the synchronous response of the form should be presented in a new (blank) tab/window. You only need to turn off ajax behaviour of the <p:commandButton> in order to make it a synchronous request.
<h:form target="_blank">
<p:commandButton value="open new tab" action="#{myBean.newTab}" ajax="false" />
</h:form>
No changes are necessary in the backing beans, it'll just work as you intented. I would only recommend to use POST-Redirect-GET pattern in the action method.
return "otherView?faces-redirect=true";
Otherwise the new tab would show the URL of the originating page and a F5 would re-invoke the POST. Also, this way the flash scope is also really used as it is been designed for (if you didn't redirect, just storing in request scope was been sufficient).
Update: as per the comments, the view scoped bean in the initial tab/window get killed this way. by returning a String navigation case outcome. That's right, if you'd like to keep the view scoped bean alive, replace the navigation case by a Faces#redirect() call (assuming that it's indeed OmniFaces which you're using there for Faces#setFlashAttribute()). You only need to set Flash#setRedirect() to true beforehand to instruct the flash scope that a redirect will occur.
public void newTab() throws IOException {
Faces.setFlashAttribute("foo", bar);
Faces.getFlash().setRedirect(true);
Faces.redirect("otherView.xhtml");
}

How to matching tabview component in server and client side with jsf?

I have two question as below;
I have a Menu and submenus in left side of my page and a Tabview on center of my page. when click to menuItem, I add tab to tabview with javascript dynamically
but I can't get tabs of tabview from backing bean. I can read only first tabs before I added with javascript.
so I want to match tabview at server side and client side synchronously.
how can i do this ?
and second;
When I closed to tab, I use TabCloseEvent in onTabClose method but event is always null. May be it will be solved with matching tabview with server and client side
i don't know.
codes are as below.
Please advise me.
thanks..
xhtml code :
<p:menuitem value="#{itemMenu.menuAck}"
action="#{MenuBean.OpenPage(itemMenu.pageName)}"
ajax="true"
oncomplete="handleTabViewEvent(args);" />
<script type="text/javascript">
function handleTabViewEvent(args) {
alert('Add tab here..');
}
</script>
bean code :
public void OpenPage(String pageName) {
String s = "Divert to handleTabViewEvent function";
}
public void onTabClose(TabCloseEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
TabView tw = (TabView)context.getViewRoot().findComponent("centerForm:tw");
String s = "I must delete tab here from tw which closed.
But event does not give me tab information. It is always null. And tw has old values";
}
I add tab to tabview with javascript dynamically
This was completely wrong approached in first place.
You need to add the tab using JSF instead of using JS. Right now JSF is completely unaware about the changed client side state and will never know about the new tab. Any workaround would only end up to be uglier and harder to maintain than when just doing it by JSF instead of JS.
See also:
How to add button for adding new tabs near last tab?
What is the need of JSF, when UI can be achieved from CSS, HTML, JavaScript, jQuery?

Redirecting to an external URL in a new tab and performing an action in backing bean at the same time

I'm working at a jsf application that at a certain time need to open an external page in a new tab, leaving the first page active. I need to find a way to make the application perform, in a single button click:
a redirect to an external URL in a new tab
an action which disables the button itself in the original page
I've tried using an <outputLink /> but it has no action attribute.
I've tried using a <commandLink />but it's unable to redirect outside.
I've also tried a <commandLink /> with target="_blank" and a redirection coded in the backing bean:
<h:commandLink onclick="submit();" target="_blank" action="#{myBean.execute}" disabled="#{myBean.linkDisabled}" value="external link" />
and, in the backing bean:
public String execute() {
linkDisabled = true;
try{
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.redirect(Constants.EXTERNAL_URL);
} catch(Exception e){
throw new FacesException("Redirection failed");
}
return THIS_PAGE;
}
A page is opened in a new tab but it's the current page instead of the that with URL Constants.EXTERNAL_URLand the button is still enabled. No error message is shown. Any suggestion?
Thanks in advance, Andrea
Your question is confusing. You're mixing "link" and "button". You basically need to disable the element in the client side by JavaScript because the response does not return to the current browser window/tab, but to a different browser window/tab. In JavaScript, it's easy to disable a button, but not a link. For simplicity, I'll assume that you mean and can use a <h:commandButton> and that this is the only button in the current form.
To solve your problem, you need to remove onclick="submit()" (because it's disturbing the default behaviour) and you need to remove the navigation outcome (it should not matter, but you never know in some JSF impls) and you need to disable the button by JS in the client side.
All with all your code should look just like this:
<h:form target="_blank">
<h:commandButton
value="external"
action="#{myBean.execute}"
onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);" />
</h:form>
And
public void execute() throws IOException {
FacesContext.getCurrentInstance().getExternalContext().redirect(Constants.EXTERNAL_URL);
}
The setTimeout() is necessary because the button is otherwise disabled before the form data is sent which would cause that the button's own name=value pair won't be sent as request parameter and so JSF won't invoke any action.
why don't you use action="someaction" and map it in faces-config.xml to go to another page?

Resources