How to hide elements in JSF? - jsf

Is it possible to hide a div etc based on a condition (like you do in rendered attribute with EL) without having to wrap it in a <h:panelGrid ...> etc with a rendered attribute? It ruins my layout. I just need it for the logic, not the layout.

first of all you should not wrap your elements with h:gridPanel which results in html table
instead you should wrap with h:panelGroup which results in span in html code , you can also add layout="block" to h:panelGroup to make it rendered as div
second you dont not use jstl when hiding div instead do something like this
<div style="display:#{(myBean.hideSomeDiv)?'none':'block'}">My Div Content</div>
or
<h:panelGroup styleClass="#{(myBean.hideSomeDiv)?'hide':''">My Span Content</h:panelGroup>
where in css file add this :
.hide {
display: none;
}
INMO you always better hide in JSF with rendered="#{myBean.renderCondition}"
Take a look at BalusC over here Conditionally displaying JSF components

You could just do this:
<div style="display:#{yourBean.property}"></div>
Where yourBean.property would return 'none' to hide the div

Related

panelGroup without style or styleClass is not rendered unless ID is given

According to the tag library for http://xmlns.jcp.org/jsf/html, a h:panelGroup is
Intended for use in situations when only one
UIComponent child can be nested, such as in the case of facets.
If the "style" or "styleClass" attributes are present, and the
"layout"
attribute is present with a value of "block", render a "div"
element,
outputting the value of the "style" attribute as the value of the
"style" attribute and the value of the "styleClass" attribute as the
value of the "class" attribute. Otherwise, if the "layout" attribute
is not present, or the "layout" attribute contains a value other
than
"block", render a "span" element, outputting the value of the
"style" attribute as the value of the "style" attribute, and the
value
of the "styleClass" attribute as the value of the "class"
attribute.
In case of
<h:panelGroup id="id" layout="block">
<!-- ... --->
</h:panelGroup>
or
<h:panelGroup layout="block" style="margin-right: 10px;">
<!-- ... --->
</h:panelGroup>
a div is being rendered:
<div id="id">
</div>
respective
<div style="margin-right: 10px;">
</div>
but when omitting the id (if one don't want to update the panelGroup) or the style (if one don't want to style the panelGroup) no div is being rendered and the resulting HTML can mess up ones layout. Furthermore exploring the realm of JSF, a panelGroup can also be used to conditionally render child elements using its rendered flag but as mentioned before when omitting the two mentioned attributes the result is rendered conditionally but without a div, such as
<h:panelGroup layout="block" rendered="true">
<it>Without DIV.</it>
</h:panelGroup>
leads to
<it>Without DIV.</it>
After this inquiry I want to check with the Stackoverflow community that I understood it right that when not using a panelGroup as a naming container or to customary style its elements one is better off solving the conditional rendering part (if needed) using a ui:fragment and the layouting part with a hard-coded div. Is this so?
Note: we are talking about if h:panelgroup will render any HTML component, but unless render="false" the inner components are not blocked from rendering in any case.
The behaviour tree of h:panelgroup consists of two checks:
Is at least one of "id" or "style" or "styleClass" attributes set?
Yes:
a. Renders a <div> if layout="block", otherwise
b. Renders a <span> (layout="gibberish" or non-existant)
No:
Renders no html component. Still useful if you want to use "rendered" or when you can nest only one component (i.e. <f:facet>)
The test for the layout attribute only comes after 1., above. Since your third example goes into the no branch, it is ignored.

New page with primefaces

a newbie primefaces question:
When I create a simple primeface page, what should I put in order to have the text styled?
<h:body>
<!-- Ok, what I put here to have styled the following H1 and outputText? -->
<h1>Not styled h1</h1>
<h:outputText value="Not styled text." />
</h:body>
</html>
I am able to get styled text by placing it inside a <\p:panel>, but I find that a bit annoying to place everything in panels.
Use css to change it, it's the most elegant solution. You can create your own classes or override existing primefaces ones if you're sure you aren't going to use the original ones. Remember to add !important at the end of the attributes set.
.ui-panel
{
border: black solid 1px !important;
}
You can just follow this tutorial about how and where to add your css reference in order to make Primefaces styles overriden.

How to make a clickable row in a rich:datatable?

I have a JSF page with a rich:dataTable where, in each row, I put h:commandLinks to lead to pages with the details of the row selected.
I wanted to make the whole row clickable, calling the action method when the user clicks anywhere in the row.
Is that possible without JavaScript?
And if JavaScript is the only way out, what would be the best way do it? Search for a commandLink and "click" it?
Thanks in advance!
I got the whole rows clickable with a bit of styling. I made the links inside the cells occupy the whole cell with display: block; for the links and padding:0 for the cell.
So, here is what you need to do. In the JSF page, set up rowClasses and the links in each cell:
<rich:dataTable value="#{myMB.listaElems}" var="elem" rowClasses="clickable">
<rich:column>
<h:commandLink action="#{myMB.preUpdate(elem)}" value="#{elem.item1}" />
</rich:column>
<rich:column>
<h:commandLink action="#{myMB.preUpdate(elem)}" value="#{elem.item2}" />
</rich:column>
</rich:datatable>
And in the CSS sheet:
tr.clickable td {
padding: 0;
}
tr.clickable td a {
display: block;
padding: 4px;
}
And that's it!
The only downside is that you need to repeat the link in each cell, but the HTTP flow remains simple, you don't need to change any component, and it will work for h:links or good old <a> html links -- a pretty acceptable tradeoff, I'd say. :)
The basic problem is that JSF (core) is tied to the HTML table element for query-result rendering via the dataTable component. Since a JSF dataTable renders as an HTML table, the result is limited to what can be managed in columns (no out-of-the-box row control that I have seen). The HTML/CSS way to do this is quite elegant but in order to accomplish this in JSF, I believe the UIComponent renderer for dataTable would need to be overridden to output this:
<div class="table">
<a href="#" class="row">
<span class="cell">Column-1-Value</span>
<span class="cell">Column-2-Value</span>
</a>
...
</div>
With CSS styles table row and cell representing display:table, display:table-row and display:table-cell; respectively. This makes the row completely clickable but it behaves as a proper table. I have not embarked on re-writing the JSF renderers and solving the JSF commandLink and other component problems to accomplish the rendering as above but that is probably the ultimate answer. I am not a fan of JSF after fighting with it on a few projects now (as compared to lighter weight combinations of concepts from basic HTML/CSS, a sprinkling of JavaScript, clean Java/Servlets, etc).
in your datatable use this one:
<a4j:jsFunction name="selectRow" action="#{userBean.myListener" ...>
<a4j:param name="currentRow" assignTo="#{userBean.selectedRowId}"/>
</a4j:jsFunction>
its called when you select a row, and you can do whatever you want and pass the selected row with the <a4j:param ...as an option you should also be able to call yourLink.click() or something similar, but that wont be the problem to find out...
reference : Richfaces Forum
You may want to try rich:scrollableDataTable. it has attribute onRowClick which you can specify as an event attribute into a4j:support / a4j:ajax nested inside your table. This will make your row clickable.
-cheers :)
For the new RichFaces 4.x, you can use the a4j:commandLink this instead, and make the complete row selectable in CSS. Notice that the 'rowClasses="clickable"' refers to the CSS class to select the whole row:
<rich:column id="fileName" sortable="false" width="618px">
<a4j:commandLink action="#{controller.setSelectedFile(file)}"
oncomplete="window.open('#{menuBar.PrintPage}?outputType=pdf', '_blank');"
rendered="#{not controller.getButtonDisabled(file)}"
execute="#this" limitRender="true">
<h:outputText value="${file}"
style="text-align:left;width:100%;min-width:400px;"
title="${file.name} is viewable.">
<f:converter converterId="MVC.View.Converter_FilePath" />
</h:outputText>
</a4j:commandLink>
</rich:column>
Use this CSS class to select the whole row:
tr.clickable td {
padding: 0;
}
tr.clickable td a {
display: block;
padding: 4px;
}

Horizontal placement of components in JSF

Should be simple but I couldn't find the answer, I would like to place components horizontally instead of vertically.
What I'm trying to achieve is a rich:toolbar with 2 or more rows. I've been trying to do that with a toolbar that has a panelgrid and two panelgroups like this:
<rich:toolbar...>
<f:panelgrid columns="1"...>
<f:panelgroup id="row1" .../> <-- Should be horizontal placement
<f:panelgroup id="row2" .../> <-- Should be horizontal placement
<f:panelgrid/>
<rich:toolbar/>
So how do I make the panelgroup layout horizontal (Or should I use something else?)
Thanks!
You probably already know that JSF in webserver ends up as HTML in webbrowser. In HTML, there are several ways to place elements horizontally (eventually with help of CSS):
Group them in inline elements (like <span> or any element with display: inline;).
Group them in block elements (like <div> or any element with display: block;) and give them all a float: left;.
The JSF <h:panelGrid> renders a HTML <table> element wherein each child component is taken as a <td>. The columns attribute represents the max amount of <td> elements in a single <tr> (so that the <h:panelGrid> knows when to put a </tr><tr> in). The JSF <h:panelGroup> renders a <span> element.
To achieve way 1 with JSF, you just need to group them in separate <h:panelGroup> components.
<rich:toolbar ...>
<h:panelgroup id="row1" ... />
<h:panelgroup id="row2" ... />
</rich:toolbar>
Way 2 can be done the same way, but then with <h:panelGroup layout="block"> instead and a float: left; in their CSS.

What jsf component can render a div tag?

Eg: h:inputText will render a "input type='text'".
What jsf tag can render a "div" tag?
You can create a DIV component using the <h:panelGroup/>.
By default, the <h:panelGroup/> will generate a SPAN in the HTML code.
However, if you specify layout="block", then the component will be a DIV in the generated HTML code.
<h:panelGroup layout="block"/>
In JSF 2.2 it's possible to use passthrough elements:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsf="http://xmlns.jcp.org/jsf">
...
<div jsf:id="id1" />
...
</html>
The requirement is to have at least one attribute in the element using jsf namespace.
Apart from the <h:panelGroup> component (which comes as a bit of a surprise to me), you could use a <f:verbatim> tag with the escape parameter set to false to generate any mark-up you want. For example:
<f:verbatim escape="true">
<div id="blah"></div>
</f:verbatim>
Bear in mind it's a little less elegant than the panelGroup solution, as you have to generate this for both the start and end tags if you want to wrap any of your JSF code with the div tag.
Alternatively, all the major UI Frameworks have a div component tag, or you could write your own.
you can use myfaces tomahawk component
http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_div.html
I think we can you use verbatim tag, as in this tag we use any of the HTML tags

Resources