Dynamic cc:insertChildren render - jsf-2

I got the problem when control to render cc:insertChildren dynamically.
<cc:implementation>
My text 1
<c:if test="#{testData}">
<cc:insertChildren /> <!-- My content will be loaded here-->
</c:if>
My text 2
<c:if test="#{!testData}">
<cc:insertChildren /> <!-- or other will be loaded here-->
</c:if>
</cc:implementation>
but the content rendered in both cc:insertChildren tags could not be rendered.
Do you have any ideas ?
Thank you.

Related

p:dialog doesn't work as expected (freezes view or doesn't show required message)

After carrying on a project of a colleague of mine I'm facing some problems with a little dialogue. I was asked to copy a component and give it a new name. But there started the problem: I was able to build the dialogue and sending the component to my backing bean (unfortunately a SessionScoped one), also the new name found its way and saving is working too BUT the save button of my dialogue shows some weird behaviour. And as the code will show I have tried a lot of variants for it (with different results, described in the comments above them).
At the end I simply want three little things: get the JSF lifecycle only called once, a working required for my inputText-field and a still usable view after successful saving.
If you need more code e.g of the composite components starting with bal or of the backing bean, just drop a note and I will take care of it.
I'm aware of the fact that fetching the data every time from the database is bad style in ui:repeat, but I haven't seen a different way with the SessionScoped-Bean I have to work with (ViewScoped would for sure be better here, but time changing it, is, like always, not there).
Here is my code, using Primefaces 5.3 and the current version of Bootsfaces:
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:b="http://bootsfaces.net/ui"
xmlns:bal="http://java.sun.com/jsf/composite/bal/components">
<ui:composition template="/template/main.xhtml">
<ui:define name="content">
<bal:pageHeading title="#{msg.menu_settings} ยป #{msg.menu_components}">
<h:form>
<div class="btn-group pull-right">
<b:commandButton look="link" styleClass="as-link" size="lg" action="#{componentController.createCategory()}" value="#{msg.create_category}" title="#{msg.create_category}" iconAwesome="plus-circle" />
</div>
</h:form>
</bal:pageHeading>
<bal:row id="panelRow">
<h:form id="masterForm">
<ui:repeat value="#{componentController.getComponentcategoryListByCompany(loginController.company)}" var="componentcategory">
<bal:panel title="#{componentcategory.name}" description="#{componentcategory.description}" expanded="false" id="categoryForm">
<f:facet name="tools">
<b:commandButton look="link" styleClass="as-link" action="#{componentController.createComponent(componentcategory)}" value="#{msg.create_component}" title="#{msg.create_component}" size="md" iconAwesome="plus-circle" immediate="true" />
</f:facet>
<ul class="list-unstyled">
<ui:repeat value="#{componentcategory.componentList}" var="componentItem">
<li class="list-group-item">
<div class="row">
<div class="col-sm-7 name-col">#{componentItem.name}</div>
<div class="col-sm-5 text-right">
<b:buttonGroup>
<p:commandButton styleClass="btn btn-link as-link" style="float: left;" value="#{msg.copy_component}" title="#{msg.copy_component}" icon="fa fa-files-o" >
<p:ajax listener="#{componentController.sendComponentToCopy(componentItem)}" oncomplete="PF('copyComponentDialog').show()" process="panelRow:masterForm" partialSubmit="true" />
</p:commandButton>
</b:buttonGroup>
</div>
</div>
</li>
</ui:repeat>
<ui:fragment rendered="#{empty componentcategory.componentList}">
<li class="list-group-item list-group-item-info">#{msg.no_components_available}</li>
</ui:fragment>
</ul>
</bal:panel>
</ui:repeat>
<ui:fragment rendered="#{empty componentController.getComponentcategoryListByCompany(loginController.company)}">
<ul class="list-unstyled">
<li class="list-group-item list-group-item-info">#{msg.no_categories_available}</li>
</ul>
</ui:fragment>
</h:form>
</bal:row>
<p:dialog id="dlg" widgetVar="copyComponentDialog" resizable="false" draggable="false" showEffect="fade" hideEffect="fade" modal="true">
<h:form id="dlgForm" prependId="false">
<bal:panel id="copy_component_view" title="#{msg.copy_component}" styleClass="form-panel" collapsible="false">
<b:message for="name" showSummary="false"/>
<b:inputText value="#{componentController.copiedComponentName}" id="name" label="#{msg.name}" fieldSize="sm" required="true" requiredMessage="#{msg.name_required}" />
<bal:panel id="buttons">
<bal:row id="row" colStyleClass="btn-group">
<ui:remove>
<!-- Required works - After saving panels are no longer toggleable - JSF-lifecycle called twice -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check">
<p:ajax listener="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
</p:commandButton>
<!-- Required doesn't work - After saving panels are toggleable, but view not updated - JSF-lifecycle called twice -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" ajax="false">
<p:ajax listener="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
</p:commandButton>
<!-- Required works - After saving panels are no longer toggleable - JSF-lifecycle called twice -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" actionListener="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
<!-- Required works - After saving panels are no longer toggleable - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" action="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
<!-- Required doesn't work - After saving panels are toggleable, view updated - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" ajax="false" action="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
<!-- Required works - After saving panels are no longer toggleable - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()">
<f:actionListener binding="#{componentController.copyComponent()}" />
</p:commandButton>
<!-- Required doesn't work - After saving panels are toggleable, view updated - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" ajax="false" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()">
<f:actionListener binding="#{componentController.copyComponent()}" />
</p:commandButton>
<!-- Required works - After saving panels are no longer toggleable - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()">
<f:actionListener binding="#{componentController.copyComponent()}" />
</p:commandButton>
</ui:remove>
<!-- Required doesn't work- After saving panels are toggleable, view updated - JSF-lifecycle called once -->
<p:commandButton value="#{msg.save}" styleClass="btn btn-primary" icon="fa fa-check" ajax="false" actionListener="#{componentController.copyComponent()}" partialSubmit="true" process="copy_component_view" update="copy_component_view :panelRow:masterForm" oncomplete="if(!args.validationFailed) PF('copyComponentDialog').hide()" />
<b:commandButton value="#{msg.cancel}" iconAwesome="close" look="default" immediate="true" onclick="PF('copyComponentDialog').hide()" />
</bal:row>
</bal:panel>
</bal:panel>
</h:form>
</p:dialog>
</ui:define>
</ui:composition>
</html>
Edit:
Just some additional information concerning bal:panel:
<?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:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="title" type="java.lang.String" />
<cc:attribute name="description" type="java.lang.String" />
<cc:attribute name="subtitle" type="java.lang.String" />
<cc:attribute name="subtitle" type="java.lang.String" />
<cc:attribute name="leftFooter" type="java.lang.String"/>
<cc:attribute name="rightFooter" type="java.lang.String" />
<cc:attribute name="closable" type="java.lang.Boolean" default="false" />
<cc:attribute name="collapsible" type="java.lang.Boolean" default="true" />
<cc:attribute name="expanded" type="java.lang.Boolean" default="true" />
<cc:attribute name="styleClass" type="java.lang.String" />
<cc:attribute name="style" type="java.lang.String" />
<cc:attribute name="titleStyle" type="java.lang.String" />
<cc:attribute name="labelValue" />
<cc:attribute name="labelLook" default="plain"/>
<cc:attribute name="labelStyleClass" />
<cc:attribute name="labelStyle" />
<cc:facet name="tools" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<div id="#{cc.clientId}" class="ibox float-e-margins #{!cc.attrs.expanded?'border-bottom':''} #{cc.attrs.styleClass}" style="#{cc.attrs.style?cc.attrs.style:''}">
<ui:fragment rendered="#{not empty cc.attrs.title}">
<div class="ibox-title" style="#{not empty cc.attrs.titleStyle?cc.attrs.titleStyle:''}">
<span class="name-col">
<span>
<h5>#{cc.attrs.title}
<ui:fragment rendered="#{not empty cc.attrs.subtitle}">
<small class="m-l-sm">#{cc.attrs.subtitle}</small>
</ui:fragment>
<ui:fragment rendered="#{not empty cc.attrs.description}">
<h:outputLink value="" styleClass="ui-commandlink ui-widget btn-md">
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="auto" data-original-title="#{cc.attrs.description}" />
</h:outputLink>
</ui:fragment>
</h5>
<ui:fragment rendered="#{not empty cc.attrs.labelValue}">
<span class="label label-#{cc.attrs.labelLook} #{cc.attrs.labelStyleClass}" style="#{cc.attrs.labelStyle}">#{cc.attrs.labelValue}</span>
</ui:fragment>
</span>
</span>
<div class="ibox-tools">
<cc:renderFacet name="tools" />
<ui:fragment rendered="#{cc.attrs.collapsible eq true}">
<a class="collapse-link">
<i class="#{!cc.attrs.expanded?'fa fa-chevron-down':'fa fa-chevron-up'}"></i>
</a>
</ui:fragment>
<ui:fragment rendered="#{cc.attrs.closable eq true}">
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</ui:fragment>
</div>
</div>
</ui:fragment>
<c:if test="#{cc.childCount gt 0}">
<div class="ibox-content" style="display: #{!cc.attrs.expanded and cc.attrs.collapsible?'none':'block'};">
<cc:insertChildren />
</div>
</c:if>
<ui:fragment rendered="#{not empty cc.attrs.leftFooter or not empty cc.attrs.rightFooter}">
<div class="ibox-footer">
<ui:fragment rendered="#{not empty cc.attrs.rightFooter}">
<span class="pull-right">
#{cc.attrs.rightFooter}
</span>
</ui:fragment>
<ui:fragment rendered="#{not empty cc.attrs.leftFooter}">
#{cc.attrs.leftFooter}
</ui:fragment>
</div>
</ui:fragment>
</div>
</cc:implementation>
</html>
and bal:row:
<?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:cc="http://xmlns.jcp.org/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="colStyleClass" type="java.lang.String" />
<cc:attribute name="rowStyleClass" type="java.lang.String" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<div id="#{cc.clientId}" class="row #{cc.attrs.rowStyleClass}" >
<div class="col-lg-12 #{cc.attrs.colStyleClass}">
<cc:insertChildren />
</div>
</div>
</cc:implementation>
</html>

JSF 2.2 content not rendered until page refreshed

I am loading stuff via AJAX into my JSF page from the server. However, not all of the content is displayed immediately, two divs arent displayed until the page is refreshed.
Here's the form for loading the content:
<h:form>
<h:dataTable value="#{consoleController.list}" var="item">
<h:column>
<h:commandLink class="list-group-item"
action="#{consoleController.defineLink()}">#{item}
<f:setPropertyActionListener target="#{consoleController.content}"
value="#{item}" />
<f:ajax event="action" render="menuDiv contenDiv facetDiv"></f:ajax>
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
These are the elements I want to load the code into.
<div class="col-sm-12">
<div class="col-sm-4">
<h:panelGroup id="menuDiv">
<ui:include src="#{consoleController.loadMenu()}" />
</h:panelGroup>
</div>
<div class="col-sm-8">
<h:panelGroup id="contentDiv">
<ui:include src="#{consoleController.loadPage()}" />
</h:panelGroup>
</div>
</div>
<div class="col-sm-12">
<h:form>
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</h:form>
</div>
menuDiv is displayed fine, the other two aren't displayed until I refresh the page.
What's the problem here?
I read that you cannot upload elements that don't exist in the JSF tree, but that's not the case here.
Well, turns out it was as easy as removing the h:form tag around the last panel tag:
<div class="col-sm-12">
<h:form>
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</h:form>
</div>
becomes:
<div class="col-sm-12">
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</div>
and now it works.

How to define default content for facet in a composite component?

I am trying to write a composite component in JSF 2.2.
This is it.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:facet name="content"/>
<cc:facet name="menubar"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
Content header
<cc:renderFacet name="content">
This is the default content.
</cc:renderFacet>
Spacer
<cc:renderFacet name="menubar">
This is the default menubar.
</cc:renderFacet>
</cc:implementation>
</html>
This is how it is used.
<dd:dummy>Hello hello</dd:dummy>
This is what is rendered to the client.
Why is the default content and default menubar not rendered?
This should work
<cc:implementation>
<c:if test="#{empty component.facets.content}" >
This is the default content.
</c:if>
<c:if test="#{not empty component.facets.content}">
<cc:renderFacet name="content"/>
</c:if>
<c:if test="#{empty component.facets.menubar}" >
This is the default menubar.
</c:if>
<c:if test="#{not empty component.facets.menubar}">
<cc:renderFacet name="menubar"/>
</c:if>
</cc:implementation>

<h:commandButton> not working inside <ui:define>

I created a facelet template called loginRegisterTemplate.xhtml. When I use it in a template client and I place a in it, the method in the managed bean is not invoked. Without the template the button is working fine. Why is this happening?
<ui:composition template="resources/css/faceletsTemplates/loginRegisterTemplate.xhtml">
<ui:define name="top">
Login Page
</ui:define>
<ui:define name="content">
<div align="center">
<h:panelGrid columns="3" columnClasses="rightalign,leftalign,leftalign">
<h:outputLabel value="Username:" for="userName"/>
<h:inputText id="userName" label="Username" required="true" value="#{loginBean.userName}" />
<h:message for="userName" />
<h:outputLabel value="Password:" for="password"/>
<h:inputText id="password" label="Password" required="true" value="#{loginBean.password}" />
<h:message for="password" />
</h:panelGrid><br/>
<h:button value="Back to Home" outcome="home"/>
<h:commandButton id="login" value="Login" action="#{loginBean.doLogin}"/>
</div>
</ui:define>
</ui:composition>
</h:body>
The simple <h:button> next to it, on the other side, is working fine.
Here is the body of my template file:
<h:body>
<div id="top">
<ui:insert name="top">Top</ui:insert>
</div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
</h:body>
I have looked here: h:commandLink / h:commandButton is not being invoked but I couldn't find which problem causes that.
Thanks!
Why is the h:commandButton not working?
Your problem is number 1 in the answer you have checked.
UICommand and UIInput components must be placed inside an UIForm
component, e.g. <h:form>.
Why is the h:button working then ?
from the h:button docs:
Render an HTML "input" element of type "button". The value of the
component is rendered as the button text and the outcome of the
component is used to determine the target URL which is activated by
onclick.
So ...
JSF will put your h:button outcome value in a javascript function that will be executed at an onclick event. But it will execute the action of the h:commandButton on the form submit with the POST method, so there should be a form to submit.

JSF2 ignores empty alt attribute

I have a jsf snippet:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets">
<!-- Yandex.Metrika -->
<img src="//mc.yandex.ru/watch/xxx" alt=""/>
<!-- /Yandex.Metrika -->
</ui:composition>
But when I use it, web-client get HTML page whithout empty alt attribute in img element:
<!-- Yandex.Metrika -->
<img src="//mc.yandex.ru/watch/xxx" />
<!-- /Yandex.Metrika -->
As result my document has validation error (
How can I solve this problem?
You could use the JSF graphicImage component, which does render the empty alt attribute.
For Example:
<h:graphicImage value="#{resource['images:image1.png']}" alt="" />
or
<h:graphicImage value="http://somedomain.com/somecontext/xxx/image1.png" alt="" />
Not sure if that is a bug in JSF2 (JSF1.2 preserves empty attributes).
To 'workaround' that in JSF2, wrap code by f:verbatim, like this:
<f:verbatim>
<img src="//mc.yandex.ru/watch/xxx" alt=""/>
</f:verbatim>

Resources