I am writing an app using JSF 2.0.
For one of the page, there is a section of the page that takes a long time to display.
To improve the user experience, I am thinking to load the page first and then automatically do an Ajax call back to the JSF manage bean object once the page is loaded successfully after 1st load.
I am thinking to use f:event with type postAddView.
<h:outputText id="dummyId">
<f:event type="postAddToView" listener="#{mngBean.doSomething}" />
</h:outputText>
However it seems like f:event postAddToView is still being processed before the page is displayed for the first time.
The other options that I have explore is to create a hidden button and get javascript to trigger it. It works however I am just wondering if there is a nice JSF component/event that can do this instead of using java script.
Thanks for your help.
<h:commandButton id="dmyButton"
value="#{mngBean.getSomething}"
actionListener="#{mngBean.doSomething}"
style="display: none"
type="submit">
Java Script
<script language="JavaScript">
$(document).ready(function() {
if (document.getElementById('form:dmyButton').value == 'true') {
document.getElementById('form:dmyButton').click();
}
});
</script>
Thanks for all your help in advance
I think the PreRenderViewEvent is what you want.
http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/event/PreRenderViewEvent.html
Though the docs don't show it, the preRenderViewEvent does work with f:event. I'll fix the docs presently.
PostAddToViewEvent is processed "During Restore View Phase, after a
component has been added to a view." (according to Java Server Faces 2.0 - The Complete Reference) which means it is really early in the lifecycle (Restore View is the first lifecycle phase).
I don't think that any PhaseListener will help you in this case, since they all run on the server side, not on the client side.
However, <f:ajax> can be applied to <h:body>, with event="load". I tried it, but it didn't really work, <f:ajax> wrapping <h:body> nothing happened, the other way around I got Unable to attach <f:ajax> to non-ClientBehaviorHolder parent error.
Related
I'm trying to scrape a .jsp webpage with Jsoup. The page I'm trying to scrape is basically a 6 steps form, filling each form takes me to another one but to do so I must click a button that calls a jsp function. I don't know how to do so with jsoup.
So here is a piece of the jsp page I'm trying to scrape.
<img id="nextButtonId" onkeypress="disableButtons(this);onIntroductionFormSubmit()" height="50"
alt="suivant" title="suivant" src="/eAppointment54-etrangers/element/images/buttons/next.gif"
**onclick="disableButtons(this);onIntroductionFormSubmit()"** onmouseover="downNextSrcPicture(this);"
onmouseout="upNextSrcPicture(this);" style="display: block;">
I want to call the onclick methods onclick="disableButtons(this);onIntroductionFormSubmit(). Maybe there is a way I can do this without having to simulate the actual clicking.
Thanks in advance !!!
Jsoup is not a browser engine, it is just an HTML parser/writer. To do such a thing you should do one of these, I recommend the first one:
Implement the method yourself (it's probably just an HTTP call)
Use an automation library like Selenium (no experience)
(Not recommended) Run a full browser environment such as JavaFX WebView and inject code to do the action.
I have a JSP file in which there are two textareas and a submit button all in a form ;
<form action="" method="post">
<textarea name="inConsole" id="in" cols="100" rows="10"> </textarea> <br/>
<input type="submit" name="Send Command"/> <br/>
<textarea name="outConsole" id="out" cols="100" rows="10"></textarea>
</form>
this page is supposed to work like any SQL program. so the user types a command in the first textarea and clicks submit, then the value of textarea will be extracted to a field and a method will take care of the command and return a log (1 row inserted, error:bad syntax etc) which will be displayed in the second textarea.
I know how for example make a login page and send data and redirect user to a new page(new jsp) file if user pass is correct.
what I can't find is how can I do all the things that I said above without going to a new page while using form action.
I have checked other questions that linked the action attribute to a servlet which was confusing for me( the way that a servlet was called). I'm looking forward to use a simple scriptlet for this purpose like the one I used for my login page:
<%
DatabaseLoginTest dbLogTest = new DatabaseLoginTest();
if (dbLogTest.DBLoginChecker(request.getParameter("user"), request.getParameter("pass")) == true){
%>
<p>Login Successful</p>
<% } else { %>
<p>Login Failed</p>
<% } %>
also I'm aware that adding java scripts(not Javascript scripts:) ) to html isn't a good practice(and the reasons for it) but I think this might be easier for a simple program that I'm working on.
p.s: I'm using tomcat and Intellij for developing this web application
and I have made a custom SQL so I only need the code that gives me the textarea value and the one that sets the other one's value
Update: now I know I should use javascript but I don't know how can I send the data extracted by javascript to a java method.
If you want to do this while remaining in the same page, you have to use Javascript. This is because if you want the server to be able to re-render the page, there has to be a page refresh.
You would need to write onClick handler for the submit button and make a Ajax call to your server to a specific URL with the user input. This URL would serve the data needed for the necessary UI changes.
You can use a scriptlet to generate the HTML that would be shown in the webpage but this would only suffice for a simple use-case and it would be a lot simpler if, say, your service returned just the data required to make the UI change and actual UI change is handled by the JS.
Also,I don't think it is a bad practice to embed JS in HTML. Sure, you can optimize this by including a JS source file but that's a separate optimization.
My application is managing software, and for user convenience, I want to allow them to open multiple tabs for changing parameters of more than one record at a time. But after finishing whatever they doing, the tabs stays open, and I got some complains about that. So basically my question is:
If there's any way to close browser tab that sends a request to method in my backing bean? for example:
JSF page:
<h:commandButton value="Public score"
action="#{assignmentBean.publicSelected()}">
</h:commandButton>
Bean method:
public void publicSelected() {
application.setAssignmentStatus(done);
dataAccess.mergeEntity(application);
}
is there any way to add something after merging command and close browser tab that activated method? Thanks for help
FULL CODE FOR SOLUTION I'm bad with mixing JS and JSF, so for any of you that are also bad at this I post full code solution using Tiago Vieira Dos Santos hint.
Now my button code looks like:
<h:commandButton value="Public score"
action="#{myBean.doThings}">
<f:ajax execute="#this" onevent="pop"/>
</h:commandButton>
plus on bottom of page I added code as follows:
<script type="text/javascript">
function pop(data){
if(data.status == "success"){
window.close();
}
}
</script>
now after method does what has to be done the window closes.
I think you can be use the javascript command Window.close() then you can put it on oncomplete tag or call in you managed bean using the FacesContext.
See more in this How to close current tab in a browser window?
Using an OutputLink and Javascript
<h:outputLink onclick="window.open('popup.faces', 'popupWindowName', 'dependent=yes, menubar=no, toolbar=no'); return false;" value="#">
<h:outputText value="open popup" />
</h:outputLink>
With this solution we got control over the appearance of the new browser window. And since there is no postback, there is no validation at all. This is the easiest way to open a new browser window when no model update is needed and no action has to be executed.
In order to implement a proper action handling we need to move the decision whether to open a new window to the action listener.
<h:commandLink actionListener="#{bean.openPopupClicked}" value="open popup" />
public void openPopupClicked(ActionEvent event) {
// code to open a new browser window goes here
}
I have Javscript in my XHTML file as
<script src="test1.js"></script>
Now I have couple of other javascripts as well. They are actually themes.
I want give users flexibility to change the them (javascript name) frmo drop-down box .
I tried this way
<script src="#{testBean.jsName}</script>
Since it is going to be an Ajax update so I have update the section and I updated with
<h:panelGrid id="jsName">
<script src="#{testBean.jsName}</script>
</h:panelGrid>
This is not inside the form .
when I try
<p:commandButton value="Generate"
actionListener="#{tBean.generateGraph}" update="jsName"></p:commandButton>
It doesn't work as it says that it couldn't find jsName.
I put that gride inside the form then it wont throw the error but the script name would still remain the same.
Does anyone have better idea or any other way to achieve it?
If you try to update it from a component inside the form you have to use the absolute id of the panelGrid otherwise primefaces will try to update something with id jsName inside the form. When you want to use the absolute id you have to preced a :. So try the following for the button:
<p:commandButton value="Generate" actionListener="#{tBean.generateGraph}" update=":jsName"/>
I'm working with a JSF application and I'm seeing the URL that appears in the browser's navigation bar is always for the page I just left, rather than the page I'm on.
It is because you are forwarded(not redirected) to another page from server, To redirect you need to set the following param with your return
?faces-redirect=true
That will happen if you're using POST for navigation by e.g. commandlinks/commandbuttons. If it's pure page-to-page navigation and you actually don't need to submit anything to the server, then you've a bigger problem. You will indeed get exactly this nasty "side effect" and your links will not be bookmarkable nor searchbot-crawlable. PRG (Post-Redirect-Get), as suggested by other answers, will indeed solve the bookmarkability ("one URL behind") problem, but it surely won't solve the inability of searchbots to crawl/index the pages.
Just don't use POST for plain page-to-page navigation in first place. Use GET for that. Use <h:link> instead of <h:commandLink> and so on. In code, replace all
<h:form>
<h:commandLink value="Next page" action="nextpage" />
</h:form>
by
<h:link value="Next page" outcome="nextpage" />
See also:
When should I use h:outputLink instead of h:commandLink?
What is the difference between redirect and navigation/forward and when to use what?
By default, JSF performs POST operations directed to the original page's URL. If you use a <navigation-rule>, you can specify <redirect/> to let the browser perform an additional request, so the target page's URL will appear in the navigation bar.