Primefaces blockUI and composition - jsf

I'm using JSF 2.2, PF 5.3 and GlassFish 4.1.1.
I'm trying to centralize the blockUI content in my web application.
here the code of the my custom blockUI
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<cc:interface>
<cc:attribute name="block" type="java.lang.String"/>
<cc:attribute name="trigger" type="java.lang.String"/>
</cc:interface>
<cc:implementation>
<p:blockUI block="#{cc.attrs.block}" trigger="#{cc.attrs.trigger}">
LOADING<br />
<p:graphicImage library="images" name="ajax-loader.gif"/>
</p:blockUI>
</cc:implementation>
and here the code in which I'm trying to apply this one
<h:form>
...
...
<p:dataTable id="myTable">
<p:column headerText="actions">
<p:commandButton class="triggerableFromBlockUI" action="#{action1}"/>
<p:commandButton class="triggerableFromBlockUI" action="#{action2}"/>
</p:column>
</p:dataTable>
...
...
<myTag:blockUI block="myTable" trigger="#(.triggerableFromBlockUI)"/>
</h:form>
but I see the following error
Cannot find component for expression "myTable".
If I use directly the p:blockUI all is working. Can you help me?

Here the solution found in the Prime Faces Forum
<myTag:blockUI block="#form:myTable" trigger="#(.triggerableFromBlockUI)"/>

Related

Create customizable components

I am new to JSF. We are building a web application using JSF with primefaces. We have lot of places where we need to display table. The table should have paging, column resizeable, in some places we need context menu on right click, etc.
I am able to implement this with dataTable component provided by primefaces. But I would like to create it as more customizable component. Some thing like reusable javascript/jquery (Jqgrid) plugin where we just set few property values which should be should be enough.
I would also want to do the similar way instead of writing the whole code for all the functionality, if a component is created which can be reused in all places and set parameters (Eg: columnResizable='true', columnSortable='true') which saves development time.
I am not getting any picture of how to accomplish it. If some one can guide that will be great. I am not expecting entire code, any idea of implementing this using JSF will be really appreciated.
You should use a composite component, you can pass as many parameters as you want and customize it accordingly using #{cc.attrs.param1} syntax. Here's a sample XHTML.
Composite component
<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:u="http://java.sun.com/jsf/composite/ui" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:s="http://jboss.org/seam/faces" xmlns:p="http://primefaces.org/ui" xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="tableId" />
<cc:attribute name="param1" />
<cc:attribute name="param2" default="false" />
<cc:attribute name="param3" required="true" />
</cc:interface>
<cc:implementation>
<p:dataTable id="#{cc.attrs.tableId}" rendered="#{cc.attrs.param2}" value="#{cc.attrs.param1}" var="result" emptyMessage="#{messages['global.noItemsFound']}">
<ui:include src="#{cc.attrs.param3}" />
</p:dataTable>
</cc:implementation>
</ui:component>
Using <c:if test="#{not empty cc.attrs.param4}"> or rendered attributes you can further customize your component
View
Let's call your composite myList.xhtml, then you could call it:
<u:myList param1="#{backingbean.results}" param2="true" id="list1" param3="/items/columns.xhtml" />
and don't forget to put a header in your view:
xmlns:u="http://java.sun.com/jsf/composite/ui"
columns.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.org/seam/faces" xmlns:u="http://java.sun.com/jsf/composite/ui"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<p:column headerText="Name">
<h:outputText value="#{result.name}" />
</p:column>
<p:column headerText="Salary">
<h:outputText value="#{result.salary}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{result.age}" />
</p:column>
</ui:composition>
An alternative to including a separate view for columns would be using <p:columns> in composite component and passing another list containing columns data as a parameter. Dynamic Columns

Dynamic tab content in primefaces using ui:include not working

I'm unable to use ui:include in tabView. I'm trying to make dynamic tabs using included Facelet.
Here's my code:
<p:tabView id="panelGl" var="tabContent" value="#{mainPageBackingBean.tabs}" widgetVar="panelGlJs" style="height: 100%;" dynamic="true" >
<p:ajax event="tabClose" listener="#{mainPageController.onTabClose}" oncomplete="questionDialogWV.show()" update="#(this) :questionForm:questionFormPanel" />
<p:ajax event="tabChange" onstart="setActive()" update="#(this)" />
<p:tab title="#{tabContent.title}" titletip="#{tabContent.description}" closable="true">
<ui:include src="#{mainPageBackingBean.tabContents}" />
</p:tab>
</p:tabView>
And #{mainPageBackingBean.tabContents} runtime value is pointing at this Facelet:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.org/ui">
<p:panel>
<h:form>
<p:commandButton id="testEmail" value="" process="#this" actionListener="#{communicationChannelsController.testEmailChannel()}"/>
</h:form>
</p:panel>
</ui:composition>
When I use the above ui:include outside of p:tabView it works normally (I am able to invoke communicationChannelsController.testEmailChannel() without a problem). Also when I copy the contents of above file inside p:tab everything works fine also.
Problem is that, when combined p:tab and ui:include do not work, this bean method is not called.
What is the best approach at creating dynamic tabs using some navigation bean like mainPageBackingBean in my example?

Validation of ViewParam and a4j:commandButton

I think i came across a bug of #ViewScoped with a4j:commandButton.
I have a very complex form where all actions use a4j, except those that need to upload data.
And depending on the order of the commands the validation of the viewParam breaks.
Here is the working code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j" >
<f:metadata>
<f:viewParam id="viewParam" name="viewParam" value="#{bean.viewParam}" required="true" />
</f:metadata>
<h:head>
<title>Test View Param</title>
</h:head>
<h:body>
<h:message for="viewParam" />
<hr/>
<h:form>
#{bean.viewParam}<br/>
<h:commandButton value="cmdButton" />
<a4j:commandButton value="a4jBtn" execute="#this" render="#form" />
</h:form>
</h:body>
</html>
just click on the a4jBtn and then on the cmdButton to see the problem.
you will see that the parameter is still there! but that the validation fails.
<t:saveState> does not help,
<rich:message> is also not better, but
<h:commandButton value="ajaxBtn" ><f:ajax execute="#this" render="#form" /></h:commandButton>
instead of
<a4j:commandButton value="a4jBtn" execute="#this" render="#form" />
does work correctly!
Using myFaces 2.0.15 and richFaces 4.2.3.Final on Tomcat 6.0.18 and jboss-el 2.0.0.GA.
i could workaround my problem by using f:ajax instead of a4j:commandButton, but maybe you have a better idea, or you could just explain to me what is going wrong?
You basically need to retain the view parameters on synchronous postbacks. As you're using OmniFaces, you could use <o:form> for that.
<o:form includeViewParams="true">
Or as you're already using a view scoped bean, trigger the validation only on non-postbacks.
<f:viewParam ... required="#{not facesContext.postback}" />
Or, as you're using OmniFaces, you could use <o:viewParam> instead which skips the validation/conversion/update on postbacks.
<o:viewParam ... />

Conditionally render element's attribute in a composite component

I have the following composite component:
<?xml version="1.0" encoding="UTF-8"?>
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute required="true" name="field" />
<composite:attribute required="true" name="value" />
<composite:attribute required="false" name="size"/>
</composite:interface>
<composite:implementation>
...
<div class="wrapper">
<h:inputText value="#{cc.attrs.value}"
id="#{field.id}"
rendered="#{field.rendered}"
size="#{cc.attrs.size}">
</h:inputText>
<h:messages for="#{field.id}" styleClass="errorMessage"/>
</div>
...
</composite:implementation>
</ui:component>
The problem is that when I'm using this component without setting its size attribute, it still gets rendered as size=0 in the html input element.
What I want is to render the nested h:inputText's attribute only if it has a valid value (eg. not empty). Alternatively, I'd like to expose all attributes of the nested element if they are not overridden explicitly.
How would it be possible?
You can use JSTL <c:if> to build the view conditionally and <f:attribute> to specify an attribute separately:
<h:inputText ...>
<c:if test="#{not empty cc.attrs.size}">
<f:attribute name="size" value="#{cc.attrs.size}" />
</c:if>
</h:inputText>
An alternative is to specify a default for the composite component attribute:
<cc:attribute name="size" required="false" default="10" />
Additional to BalusC's post:
You must use
type="int" in the cc:attribute-tag :
cc:attribute name="maxlength" type="int"
I believe there is an alternate method for accessing attributes. I've used this with JSF 2 when accessing an attribute named with a java reserved keyword.
{cc.attrs['size']}

What is the real conceptual difference between ui:decorate and ui:include?

It occurs ago me that ui:decorate is functionally the same as ui:include except that you can also pass ui:param and ui:define to the included file.
Am I crazy?
EDIT : Although in fact you can pass ui:param to a ui:include file too, it turns out I am already doing it. Maybe you can pass a ui:define as well, I will check and edit here.
The main difference between <ui:include> and <ui:decorate> is that the <ui:decorate> is intended to allow insertion of user-defined template components, while the <ui:include> is intended to include an existing and already-predefined template.
This indeed means that the <ui:decorate> supports <ui:define> for user-defined template components in its body and can insert it at the <ui:insert> place inside the template.
Here's a -somewhat clumsy- example to show where it can be used:
/WEB-INF/templates/field.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:outputLabel for="#{id}" value="#{label}" />
<ui:insert name="input" />
<h:message id="#{id}_message" for="#{id}" />
</ui:composition>
/page.xhtml
<h:panelGrid columns="3">
<ui:decorate template="/WEB-INF/templates/field.xhtml">
<ui:param name="label" value="Foo" />
<ui:param name="id" value="foo" />
<ui:define name="input">
<h:inputText id="foo" value="#{bean.foo}" required="true" />
</ui:define>
</ui:decorate>
<ui:decorate template="/WEB-INF/templates/field.xhtml">
<ui:param name="label" value="Bar" />
<ui:param name="id" value="bar" />
<ui:define name="input">
<h:selectBooleanCheckbox id="bar" value="#{bean.bar}" required="true" />
</ui:define>
</ui:decorate>
...
</h:panelGrid>
Note that it renders the components nicely in each cell of the panel grid. Again, this particular example is pretty clumsy, I'd just have used a tag file instead. Only if it was a larger section, e.g. a whole form whose e.g. its header or footer should be customizable, then an <ui:decorate> would have been appropriate.
Another major advantage of <ui:decorate> is that it allows you to use a composite component with a template. See also Is it possible to use template with composite component in JSF 2?

Resources