Why jsf <h:inputHidden../> is taking space on the screen? - html

Among most primefaces component on my screen, I happen to have used an h:inputHidden on my xhtml page as I needed a hidden field to store/update a bean field value.
<h:inputHidden id="calendarValueHidden" value="#{myCdiBean.calValue}"/>
Even though it is not visible, but I don't know why it is taking space on the screen which has disturbed other components of the page. Even display:none !important is not working on the input hidden component.

The problem symptoms indicate a common starter's mistake: declaring it as an immediate child of a <h:panelGrid>. Like so:
<h:panelGrid columns="1">
<h:inputText ... />
<h:inputText ... />
<h:inputHidden ... />
<h:inputText ... />
</h:panelGrid>
The <h:panelGrid> generates a HTML <table> and, as documented, it will put every direct child in its own table cell <td>. The generated HTML output looks like this:
<table>
<tbody>
<tr><td><input type="text" /></td></tr>
<tr><td><input type="text" /></td></tr>
<tr><td><input type="hidden" /></td></tr>
<tr><td><input type="text" /></td></tr>
</tbody>
</table>
A <td> has by default some margin and padding which totally explains your problem. You should have noticed it when inspecting the HTML output and CSS styles in browser's builtin developer toolset (press F12 or rightclick, Inspect Element).
You basically want to group the <h:inputHidden> along with the desired <h:inputText> inside the same table cell. You can use <h:panelGroup> for that.
<h:panelGrid columns="1">
<h:inputText ... />
<h:panelGroup>
<h:inputText ... />
<h:inputHidden ... />
</h:panelGroup>
<h:inputText ... />
</h:panelGrid>
This will end up in the generated HTML output as below, exactly as you intented:
<table>
<tbody>
<tr><td><input type="text" /></td></tr>
<tr><td><input type="text" /><input type="hidden" /></td></tr>
<tr><td><input type="text" /></td></tr>
</tbody>
</table>
Unrelated to the concrete problem, using tables for layout and positioning is bad. Use divs and CSS.

The problem is, I placed the hidden field inside the panel grid, just after the component, the value of which it holds. I took it out of the panel grid and placed it in the end just before the end of the form tag. Problem solved.
Looks like a panel grid does not take a hidden field for actually a literally non-present component. It is still counted by a panel grid because it is still in dom. For an element to be an uncountable element in panel grid, it has to be unrendered (rendered="false"). But then it also becomes totally inaccessible and its value wont be available as it is no more in dom.

Related

JSF onclick radio button hide/show textbox

I want to implement functionality like, when I'm selecting one radio button it has to show one text box otherwise it should be in the hidden state. I wrote code like this
<tr>
<th><label for="selection">Register as ::</label></th>
<td> <h:selectOneRadio id="selection" value="#{LoginBean.role}" label="Action" required="true">
<f:selectItem itemValue="Customer" itemLabel="Customer" />
<f:selectItem itemValue="Manager" itemLabel="Manager" />
<p:ajax process="console" update="#form" />
</h:selectOneRadio>
</td>
</tr>
<tr>
<th><h:outputLabel value="Enter your Fee ::" rendered="#{LoginBean.role eq 'Manager'}"></h:outputLabel></th>
<td><h:inputText id="fee" value="#{LoginBean.fee}" rendered="#{LoginBean.role eq 'Manager'}" required="true" requiredMessage="Fee is required." class="form-control" a:placeholder="200.00" ></h:inputText></td>
</tr>
Here, If I select Manager radio button it should show the outputLabel and inputeText.
There are getter and setters in the Bean Class.
Is there anything wrong?
instead of the input row as in your code,
I would recommend you put it in another form with rendered="#{LoginBean.isManager }", take out both rendered in your h tag.
Duplicate this form without any child tag, this form comes with rendered="#{!LoginBean.isManager }"
In your Bean, declare new boolean isManager with getter setter.
As you process your radio choice form, Bean will set isManager to false or true based on your choice and render the form according to your isManager.
I used this way to quick add "Edit" form. It works without POSTBACK. I hope it works for you!
PS: You may only need to set rendered to tr tag instead of h tag.

Primefaces global tooltip with HTML content

In my JSF page I am using a datatable with tooltip on a row column like this:
<p:dataTable var="item" ...>
<p:column headerText="#{bundle['item.name']}">
<!--
<h:outputText value="#{item.name}" title="#{simpleTooltipGenerator.generate(item)}"/>
-->
<h:outputText id="name" value="#{item.name}"/>
<p:tooltip for="name" escape="false" value="#{simpleTooltipGenerator.generate(item)}"/>
</p:column>
</p:dataTable>
The simpleTooltipGenerator.generate() is a method which generates the following HTML tooltip:
<div class="ui-tooltip-text ui-shadow ui-corner-all">
<table>
<tbody>
<tr><td class="key">Lastname</td><td class="value">Doe</td></tr>
<tr><td class="key">Firstname</td><td class="value">John</td></tr>
</tbody>
</table>
<div class="adresse spacer"></div>
<div class="adresse title">Address</div>
<table>
<tbody>
<tr><td class="key">OFFICE</td><td class="value">...</td></tr>
<tr><td class="key">HOME</td><td class="value">...</td></tr>
</tbody>
</table>
</div>
This works as expected, but when I use a global tooltip <p:tooltip escape="false"/> together with <h:outputText value="#{item.name}" title="#{simpleTooltipGenerator.generate(item)}"/> only the generated HTML code is shown in the tooltip! Using a fixed text for the global tooltip works?!
Is this a bug, that global tooltip does not support HTML content, even if set escape="false", or is this not supported?!
My environment is Primefaces 6.0 on WildFly 10.0.0-Final
From PrimeFaces Documentation:
Global Tooltip
...
As global tooltips are more efficient
since only one instance of tooltip is used across all tooltip targets, it is suggested to be used instead
of explicit tooltips unless you have a custom case e.g. different options, custom content.
First I would say this is not supported. As i tried it worked nevertheless. So your problem seems to be missing globalSelector attribute which defaults to a,:input,:button
If you want to support <h:outputText /> (which renders as <span />) binding, just add a propper selector like:
<p:tooltip escaped="false" globalSelector="a,:input,:button,span" />

Specify width of a column of h:panelGrid

Previously is used <table> tags in JSF forms. I notice that it is better to use panelGrid tag instead of it, since it is easier to use and simpler.
Previously, I used an extra <td> for <h:message > tag and give it's width to 300 to prevent form moving to left when messages appears.
Now, I'm using width attribute of <h:panelGrid> tag , but it is not my desire perform.
When any error message appears, the whole form moves left and then messages appear in front of each input texts .
I used width attribute of message tag, but it not worked good.
Should I have to back to use <table> instead of <h:panedGrid> ?
<?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://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Facelet gg</title>
</h:head>
<h:body>
<center>
<h:form>
<h:panelGrid columns="3" width="400">
<h:outputLabel value="Username:"/>
<h:inputText id="username" value="#{loginBean.username}" required="true">
<f:validateLength maximum="30" minimum="3"/>
</h:inputText>
<h:message for="username" />
<h:commandButton value="submit" action="home"/>
</h:panelGrid>
</h:form>
</center>
</h:body>
</html>
It's normal behavior because the width attribute of the h:panelGrid is for the entire table and not for a particular column, you can check that in it's java docs.
However, you can specify a width for each column by defining CSS classes for columns using the attribute columnClasses:
Comma-delimited list of CSS style classes that will be applied to the
columns of this table. A space separated list of classes may also be
specified for any individual column. If the number of elements in this
list is less than the number of actual column children of the UIData,
no "class" attribute is output for each column greater than the number
of elements in the list. If the number of elements in the list is
greater than the number of actual column children of the UIData, the
elements at the posisiton in the list after the last column are
ignored.
So, in your example, assuming that you have a style.css file in your css library, you can add something like this to it:
.firstColumn {
width: 100px;
}
.secondColumn {
width: 100px;
}
.thirdColumn {
width: 300px;
}
After including your css file using:
<h:outputStylesheet library="css" name="styles.css"/>
you can use it in your h:panelGrid like following:
<h:panelGrid columns="3" columnClasses="firstColumn,secondColumn,thirdColumn ">
<h:outputLabel value="Username:"/>
<h:inputText id="username" value="#{loginBean.username}" required="true">
<f:validateLength maximum="30" minimum="3"/>
</h:inputText>
<h:message for="username" />
<h:commandButton value="submit" action="home"/>
</h:panelGrid>

How to arrange two buttons side by side in Struts2

I am developing a Web page on struts2 If I am correct theme in Struts2 is set such that all the tags will eventually be inside a table so all tags will be aligned one below other.
In My web page i have login page with Submit and Reset button I want both side by side (next each other) rather than in separate line.I Tried googling i got some answer like { display : inline; } in CSS and also { position : float} and theme="simple" in form. Nothing worked
<table><tr><td><s:submit method="CheckUser" value="Login" align="center" /></td><td><s:reset value="Clear" align="center" /></td></tr>
In case if i set i get the 2 buttons(submit+reset) as required
but though label="User Id" is given i get only text field without label
<tr><td><s:textfield name="userid" label="User Id" size="25" /></td></tr>
<tr><td><s:password name="password" label="Password" size="25" /></td></tr>
Please do suggest me where I am going wrong and how to get both label to text field and also submit_Reset button side by side
Just leave default Struts2 theme, which is xhtml by the way, as it is and change only your <s:submit> and <s:reset> tags adding to them theme attribute with value simple.
<s:form>
...
<tr>
<td colspan="2">
<s:submit value="Login" theme="simple"/>
<s:reset value="Clear" theme="simple"/>
</td>
</tr>
</s:form>
In struts.xml set the theme to simple
<struts>
...
<constant name="struts.ui.theme" value="simple" />
...
<struts>
Now things will work as you expect.
The theme can also be scoped in other ways if you don't want the simple to to be default (page and per tag are common) see here: http://struts.apache.org/2.3.8/docs/selecting-themes.html

Move elements to top of container using only css

I'm using happy.js for form validation. When an error occurs, a span with the class "unhappyMessage" will be placed directly before the form element that did not pass validation. The html ends up looking something like this:
<form id="myForm">
<label for="text1">Label 1</label><br />
<span id="text1_unhappy" class="unhappyMessage">Error message</span>
<input id="text1" type="text" />
<br />
<label for="text2">Label 2</label><br />
<span id="text2_unhappy" class="unhappyMessage">Error message</span>
<input id="text2" type="text" />
</form>
The <span>s don't show up until an error occurs. I would like to use css to somehow filter the error messages to the top of the parent, as if it were coded like this:
<form id="myForm">
<span id="text1_unhappy" class="unhappyMessage">Error message</span><br />
<span id="text2_unhappy" class="unhappyMessage">Error message</span><br />
<label for="text1">Label 1</label><br />
<input id="text1" type="text" />
<br />
<label for="text2">Label 2</label><br />
<input id="text2" type="text" />
</form>
Note that I would like to make each .unhappyMessage appear on its own line as well. Is there a css-only way to do this?
Note: for those of you who are wondering, I want to use css only because I would have to do some reverse engineering in order to get this working with javascript, since it seems the only event I'm provided through happy.js is not the only time that error messages are created.
Css wont provide a solution for you. Look for another form validator if you have no easy access into the event delegation. Or look into the code to see if you can figure out a work around.
Edit:
looking at the happy.js page it provides a callback function for you to specify if you wish.
unHappy (function): A callback that gets triggered when form
submission is attempted but any fields fail validation.
So pass a function that prepends all the error messages.