Ajax request and attributes - ajax

I am trying this tutorial which describes how to set attributes into server call and how to analyse the attributes on backing bean;
<h:commandButton id="submit"
actionListener="#{userData.attributeListener}" action="result">
<f:attribute name="value" value="Show Message" />
<f:attribute name="username" value="JSF 2.0 User" />
</h:commandButton>
I googled a lot but most examples show how to set attrs for synch-ed calls not the asynch-ed ones :S So my question is ... how to send attributes on server if that would be the ajax call and how to get them on backing bean (see suggestion A code snippet)?
suggestion A :
<h:commandButton id="submit"
actionListener="#{userData.attributeListener}" action="result">
<f:ajax>
<f:attribute/>? how to
</f:ajax>
</h:commandButton>
and if there is a good tutorial concerning to this question please do share the link :)
Thanks

OK I just wrote a test which sets attributes out the ajax block as :
<h:commandButton id="submit"
actionListener="#{userData.callWithAttributes}" action="result">
<f:attribute name="a" value="#{testa}"/>
<f:attribute name="b" value="#{testb}"/>
<f:ajax .../>
</h:commandButton>
...and on the backing bean
...
public void callWithAttributes(ActionEvent e){
String a=(String) e.getComponent().getAttributes().get("a");
...
}
...
Seems like it's working fine :) So attributes should be placed into event-making component block - the h:commandButton in this particular case...

To set two properties in backing bean you can use f:setPropertyActionListener
<h:commandButton action="#{bean.method}">
<f:setPropertyActionListener value="#{testA}" target="#{bean.valueA}/>
<f:setPropertyActionListener value="#{testB}" target="#{bean.valueB}/>
</h:commandButton>
or with EL method argument support:
<h:commandButton action="#{bean.method(testA, testB)}"/>

Related

Passing <p:inputText> values to Bean using ajax

I am having the h:inputText which having a text and by ajax request how can i send it's values to bean class and the values will be validated in further action begin at bean class ..
view page code is
<h:form>
<p:panel id="panel" header="Login Panel" style="margin:0 auto;width:350px;margin-top:15%;">
<p:panelGrid columns="3" id="pgrid1" styleClass="theme" >
<p:outputLabel value="User Name:" />
<p:inputText id="name" value="#{loginBean.name}" required="true" requiredMessage="Name is required">
<f:ajax event="blur" render="label" listener="loginBean.validateName" ></f:ajax>
<!--Here the ajax event working properly but how can i get the inputText value when ajax event is invoked-->
</p:inputText>
<p:message for="name" style="color: red;" />
</p:panelGrid>
<p:commandButton type="Submit" value="Submit" action="#{loginBean.validate}" update="pgrid1" />
</p:panel>
My Bean class Code is :
public void validateName(AjaxBehaviorEvent e)
{
//Here i need inputText value..how can i handle this task..!!
}
JSF has already set the #{loginBean.name} value at that moment. Just access it directly.
public void validateName(AjaxBehaviorEvent e)
{
System.out.println(name); // Look, JSF has already set it.
// ...
}
You've by the way an EL syntax error in <f:ajax listener> which causes the listener method never to be invoked, but I'll bet it to be just carelessness during preparing the question as you mentioned that it is "working properly". In the future questions, please edit code in the real development environment and copypaste real working code instead of blindly editing the code in the question editor.

Disable/Enable h:commandButton on validation fails/ is ok

I got a TextBox with a validator and a commandbutton. When the validation of the textbox fails I want to disable the commandbutton otherwise it should be enabled. I don't want to use any codebehind so it should be working without any helper properties in the bean.
So how can I tell the commandbutton to be disabled/enabled depending on the validator state?
<h:outputLabel for="category" value="#{msg['category.create']}"/>
<h:inputText id="category" required="true" label="#{msg['category.create']}" value="#{CreateCategoryBean.newCategory.name}" >
<f:validator validatorId="Get.Validator.CategoryValidator" />
<f:ajax event="keyup" render="categorymessage" />
</h:inputText>
<h:messages for="category" id="categorymessage"/>
<h:commandButton id="submit" value="#{msg['default.create']}" action="#{CreateCategoryBean.CreateCategory()}"
As you've already a <f:ajax event="keyup">, just let it update the <h:commandButton> as well wherein you in turn in its disabled attribtue check if UIComponent#isValid() of <h:inputText> doesn't return false.
<h:inputText binding="#{category}" ...>
<f:ajax ... render="categoryMessage submit" />
</h:inputText>
<h:commandButton id="submit" ... disabled="#{not category.valid}" />
No additional bean properties necessary. The above code is complete as-is.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?

JSF passing object to template

I have two jsf pages. layout.xhtml and page.xhtml. Layout looks like this:
<ui:composition>
<h:panelGroup id="menu" layout="block">
<h:outputText value="#{menuBean}" />
<h:form>
<ui:repeat var="menuItem" value="#{menuBean.menuItems}">
<button:menuItem label="#{msgs[menuItem.label]}" action="#{menuBean.selectItem(menuItem.label)}" update="#{update}" />
</ui:repeat>
</h:form>
</h:panelGroup>
<ui:repeat var="menuItem" value="#{menuBean.menuItems}">
<h:panelGroup layout="block" rendered="#{menuBean.selectedItemLabel eq menuItem.label}">
<ui:include src="#{menuItem.page}" />
</h:panelGroup>
</ui:repeat>
And page like this:
<h:panelGroup binding="#{page}" layout="block">
<ui:decorate template="../template.xhtml">
<ui:param name="menuBean" value="#{pageBean}" />
<ui:param name="update" value=":#{page.clientId}" />
</ui:decorate>
</h:panelGroup>
When I first time render page everything is ok (menuItems are rendered etc). After I click any button I get Target Unreachable, identifier 'menuBean' resolved to null.
Can anyone explain me what is happening why the menuBean isn't assigned again and if there exists another way to achieve this kind of thing (to have some generic layout page, pass some object there and generate page)? My beans are managed by Spring.
UPDATE:
I guess the problem is somehow connected to my composite button which looks like this:
<composite:interface name="menuItem">
<composite:attribute name="action" targets="button" />
<composite:attribute name="styleClass" />
<composite:attribute name="label" />
<composite:attribute name="update" />
<composite:attribute name="rendered" />
<composite:insertChildren />
</composite:interface>
<composite:implementation>
<h:commandButton id="button" value="#{cc.attrs.label}" style="width: 150px;" action="#{cc.attrs.action}"
rendered="#{empty cc.attrs.rendered ? true : cc.attrs.rendered}" styleClass="menu-item #{cc.attrs.styleClass}" type="button">
<f:ajax render="#{cc.attrs.update}" />
</h:commandButton>
</composite:implementation>
If I replace the tag by standard h:commandButton everything works perfectly. I am passing object into template and the template is passing the passed object into composite, but I am definitely missing something.
I think the problem is connected with the scope of the beans. As I understand your pageBean backing bean have request scope. Try to change scope on wider one (it should be view scope #ViewScoped). If you use CDI annotations instead of JSF then you can look at #ConversationalScope (or you can use MyFacesCODI library as Luiggi noted).
The problem I am facing to BalusC already described on his blogspot:
http://balusc.blogspot.cz/2011/09/communication-in-jsf-20.html#ViewScopedFailsInTagHandlers
Simply put at the moment of postback request (ajax refresh of button) bean passed into my composite button does not exist. As BalusC noted, solution can be creating of standard UIComponent instead of using composite shortcut.

Inputtext not syncing with backend bean when commandbutton is pushed

When I hit the commandButton it puts in the value that product.amount started as rather than what is currently typed in the input box.
<h:inputText value="#{product.amount}" />
<h:commandButton id="Button"
value="Buy"
tabindex="2" >
<f:ajax listener="#{shopBean.addToCart(product.product, product.amount)}"
execute="#this"
render="#all" />
</h:commandButton>
You need to include the input field in the execute attribute of the <f:ajax> so that it get processed as well, otherwise it will simply be ignored altogether.
<h:inputText id="amount" ... />
<h:commandButton ...>
<f:ajax execute="#this amount" ... />
</h:commandButton>
Or just put the whole in a single form and use execute="#form".
<h:form>
<h:inputText ... />
<h:commandButton ...>
<f:ajax execute="#form" ... />
</h:commandButton>
</h:form>
By the way, the render="#all" defeats one of the main advantages of using ajax. Try to render exactly only the component(s) which actually needs to be updated.

how to add a f:ajax tag to an h:link?

I have this:
<h:link value="Sign In" outcome="login.jsp" />
When the link is clicked it navigates to login.jsp. Works fine.
I'd also like a method in a bean to get called on the click, so I tried this:
<h:link value="Sign In" outcome="login.jsp" />
<f:ajax event="click" listener="#{loginHandler.dismissSignUpDialog}" />
</h:link>
But it never calls the method. The method looks like this:
public void dismissSignUpDialog(AjaxBehaviorEvent e) {
setSignUpDialogDismissed(true);
}
Any idea what I'm doing wrong? Thanks!
The <f:ajax> indeed doesn't work on <h:link> that way. Use <h:commandLink> instead.
<h:form>
<h:commandLink value="Sign In" action="login.jsp?faces-redirect=true" />
<f:ajax listener="#{loginHandler.dismissSignUpDialog}" />
</h:commandLink>
</h:form>
By the way, why are you still using JSP instead of Facelets?
I think you would be far better off using an <h:commandLink> whose action is set to your method, then alter the method to return String corresponding to your outcome. That is:
<h:commandLink value="Sign In" action="#{loginHandler.dismissSignUpdialog}" />
And the bean:
public String dismissSignUpDialog() {
setUpDialogDismissed(true);
return "login";
}

Resources