A way to easily check if an element was rendered in jsf2 - jsf

I have a button that is supposed to close a modal panel and render several elements.
Is there an easy way to check if an element was rendered after the button was pressed?
example button:
<a4j:commandButton onclick="#{rich:component('modal')}.hide();"
style="background-repeat:no-repeat;width:18px;height:18px;"
image="includes/images/close.gif"
render=":id1 :id2">
<f:setPropertyActionListener target="#{Controller.attribute}" value="false" />
</a4j:commandButton>

I have another button that does not "work" on the un-rendered div.
The conditon of the rendered attribute of all of the button's parent components must be preserved when you're submitting the form. So it should not only evaluate true during the request of presenting the form with the button, but it should also evaluate true during the request of processing the form submit. Easiest is to put the backing bean in the view scope by #ViewScoped.
Also, if you're re-rendering a component which in turn contains a <h:form>, you need to explicitly add the client ID of that <h:form> to the render attribute. E.g. when component with client ID id1 has in turn a <h:form id="formOfId1">.
render=":id1 :id2 :formOfId1"
You can debug this all by just exploring the HTTP traffic in the webbrowser's developer toolset (press F12 in Chrome/IE9/Firebug and check the "Network" section).
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - Points 5 and 7.

I have hit the same problem. My solution was to display the current time inside the element that i want to be rendered.
If, for instance, you want to render a panel, just paste inside that panel the following snippet:
<h:outputText value="#{session.lastAccessedTime}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS" type="date" />
</h:outputText>
If the time is updated after button click, then obviously the component was rendered. But is the opposite also true? If the time is not updated, does this mean the component was not rendered? What if the component got rendered properly, but the time displayed is frozen to the moment the page was first accessed? I had small doubts about that, so i refreshed the page, and the time changed. So the time displayed is not frozen to the initial moment.
Also note that there are multiple ways to get the time; if you don't like to use session time, you could set a property in the backing bean, and initialize it to new Date()

Related

Bean value is getting set on click of a cancel button in JSF, How to avoid this? [duplicate]

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

logout-method called every time user changes view [duplicate]

This question already has an answer here:
How to call JSF backing bean method only when onclick/oncomplete/on... event occurs and not on page load
(1 answer)
Closed 5 years ago.
<h:outputLink value="/4JVA-157292-war/supinfo/auth/mycar.xhtml">Car</h:outputLink>
<h:outputLink value="Log Out" onclick="${loginController.logout()}" />
As you see, If i click the Car link. I will excute the ${loginController.logout()}, but if i delete the Log out. I will go into the car page.
<h:ouputLink> component is used to render plain a anchor element with its href attribute evaluated as value attribute of <h:outputLink> with the query parameters attached in case the component has <f:param> tags as its children.
<h:ouputLink> is not used to execute server-side actions as you wrongly seemed to expect. You may have confused it with a <h:commandLink> component that is used to trigger a server-side action via a JavaScript call.
If you want to call the action method you must switch to a command comnponent (or its derivative) like <h:commandLink>. Its action attribute should point to the desired action method, like so:
<h:commandLink value="Log out" action="#{loginController.logout}" />
In this way you will be able to execute the bean action method.
Also it is worth noting that since JSF 2.0 there has been an <h:link> component that is useful for handling application-wide navigation. It takes a navigation case outcome in its outcome attribute thus leaving <h:outputLink> component useful for links to external resources.
For more information on the subject read the following answer: When should I use h:outputLink instead of h:commandLink?.
As to the cause of the problem you faced, onclick attribute is rendered as onclick event handler of the generated a element that responds to a click event on the HTML element it is attached to. In case the event is fired a client-side JavaScript code is called (by function call onclick points to or by executing inline code that is contained therein). Do note that onclick runs on the client (in JavaScript context within web browser) while action runs on the server (executes Java code depending on the submit button pressed within web server).
Usage of onclick may be fruitful at least in the following circumstances:
in case it is used in conjunction with a command component it may stop form submission to the server if some client-side requirements are not met (i.e. confirm dialog was shown and cancel button was pressed, or client-side validation failed) as soon as the event will be fired before any consecutive events associated with the element (like form submission):
<h:commandLink value="Delete item" action="#{bean.delete(item)}" onclick="return confirm("Are you sure you want to delete this item?");" ... />
or
<h:commandLink value="Submit data" action="#{bean.action}" onclick="return inputValid();" ... />
with
<script type="text/javascript">
function inputValid() {
var isInputValid = ...;
//decide what's valid or not and set variable to true/false accordingly
return isInputValid;
}
</script>
it may be used to trigger some GUI changes, especially when used in conjunction with non-command components, like in:
<h:button value="Show dialog" onclick="showDialog(); return false;" ... />

Cancel button jsf not resetting entity

I'm trying to implement a cancel button to clear the fields from my entity.
Though, when I'm setting the entity to null my fields still keep their value.
Code:
The EntityBB's cancel method (note that the debugger can reach the cancel method):
public void cancelAddStandardLetter() {
setEntity(null);
standardLetterInit();
}
this method really sets all the values from the entity back to null and the standardLetterInit method sets some default values that are needed (tried the same method without the standardLetterInit -> same result).
The xhtml page (other inputfields are left out):
<o:form includeRequestParams="true" id="addStandardLetterForm">
<h:inputTextvalue="#{entityBB.entity.fileName}" styleClass="rInput"/>
<h:commandButton value="Cancel" immediate="true"
styleClass="floatRight"
action="#{entityBB.cancelAddStandardLetter()}" />
</o:form>
After pressing the "cancel" button, the values being typed in the "fileName" field are still there. How can that be?
Make sure that the bean is view scoped and use a plain GET button.
<h:button value="Cancel" />
This basically refreshes the page. It'll recreate the view scoped bean instance. No need to submit the whole form. If the input values still appear, then it's either the browser cache or autocomplete/autofill which you in turn can control with respectively a servlet filter and autocomplete="off".

PrimeFaces CommandButton that Doesn't Process Data

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

JSF: How to get the selected item from selectOneMenu if its rendering is dynamic?

At my view I have two menus that I want to make dependent, namely, if first menu holds values "render second menu" and "don't render second menu", I want second menu to be rendered only if user selects "render second menu" option in the first menu. After second menu renders at the same page as the first one, user has to select current item from it, fill another fields and submit the form to store values in database. Both the lists of options are static, they are obtained from the database once and stay the same. My problem is I always get null as a value of the selected item from second menu. How to get a proper value? The sample code of view that holds problematic elements is:
<h:selectOneMenu id="renderSecond" value="#{Bean.renderSecondValue}"
valueChangeListener="#{Bean.updateDependentMenus}"
immediate="true"
onchange="this.form.submit();" >
<f:selectItems value="#{Bean.typesOfRendering}" />
</h:selectOneMenu><br />
<h:selectOneMenu id="iWillReturnYouZeroAnyway" value="#{Bean.currentItem}"
rendered="#{Bean.rendered}" >
<f:selectItems value="#{Bean.items}" />
</h:selectOneMenu><br />
<h:commandButton action="#{Bean.store}" value="#Store" />
However, if I remove "rendered" attribute from the second menu, everything works properly, except for displaying the menu for all the time that I try to prevent, so I suggest the problem is in behavior of dynamic rendering. The initial value of isRendered is false because the default item in first menu is "don't render second menu". When I change value in first menu and update isRendered with valueChangeListener, the second menu displays but it doesn't initialize currentItem while submitting.
Some code from my backing bean is below:
public void updateDependentMenus(ValueChangeEvent value) {
String newValue = (String) value.getNewValue();
if ("render second menu" == newValue){
isRendered = true;
} else {
isRendered = false;
}
}
public String store(){
System.out.println(currentItem);
return "stored";
}
If you're using the rendered attribute on UIInput and UICommand components, then you have to make sure that the rendered condition evaluates exactly the same way in the subsequent request (during submitting the form) as it was during the initial request (during displaying the form). When it evaluates false, then the request values won't be applied/validated and the model values won't be updated and no action will be invoked for the component(s) in question.
An easy fix is to put the bean in the session scope, but this has caveats as well (poor user experience when opening same page in multiple browser tabs/windows). On JSF 2.0 you could use the view scope instead. On JSF 1.x you would use Tomahawk's t:saveState for this.
The problem arises only when we have "don't render" as a first option. I decided to change the values in the database and now I have "render second menu" as a first one. With such an approach, everything works fine.

Resources