JSF onclick radio button hide/show textbox - html

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.

Related

Hide show components which are created dynamically using PrimeFaces

I have the following code which generates the radio button properly.
<c:forEach items="#{sampleController.modelVo.valuesList}" var="valueVo">
<p:selectOneRadio
id="pickedSdlp_#{valueVo.id}"
value="#{sampleController.selectedValue}"
layout="responsive"
columns="1"
converter="omnifaces.SelectItemsConverter" >
<f:selectItem
id="valueVo#{valueVo.id}"
itemLabel="#{valueVo.valueVoDesc}"
itemValue="#{valueVo}">
</f:selectItem>
</p:selectOneRadio>
<p:selectManyCheckbox
id="timeBlocks_#{valueVo.id}"
value="#{valueVo.timeId}"
layout="responsive"
columns="1">
<f:selectItems value="#{valueVo.subValueList}" var="valueVoTime" itemLabel="#{valueVoTime.from} #{valueVoTime.to}" itemValue="#{valueVoTime.id}" />
</p:selectManyCheckbox>
</c:forEach>
Is it possible to hide/show p:selectManyCheckbox based on the value selected? the value is actually based on voList.canShow == 'Y', if Y then show else hide it.
Radio buttons are dynamically created so not sure how to achieve this.
I am able to generate the following and highlighted the radio selected under each radio button check boxes are generated but how to hide/show them based on the radio value(ON/OFF):

p:autocomplete stops working after updating parent via ajax

I have a list of autocompletes that is rendered using a p:dataList. Something like shown below:
<h:panelGroup layout="block" id="outerPanel">
<p:dataList rendered="#{bean.myModel.listOfItems.size()>0}"
var="additionalMP"
value="#{bean.myModel.listOfItems}"
rowIndexVar="index" emptyMessage="">
<div class="wrapper ui-g">
<div>
<p:autoComplete
cache="true"
value="#{bean.myModel.listOfItems[index]}"
completeMethod ="#{handler.getAutoCompleteData}"
rendered ="true"
required="false"
scrollHeight="200"
styleClass="custom"
forceSelection="true">
<p:ajax event="query" global="false"/>
<f:attribute name="filter" value="filterName" />
<f:attribute name="mode" value="edit" />
</p:autoComplete>
</div>
<div>
<p:commandLink value="+ Add" actionListener="#{bean.addAutoComplete()}"
update=":formName:outerPanel"></p:commandLink>
</div>
</div>
</p:dataList>
</h:panelGroup>
So, the Add button inserts a new item in the list and I update the container panel so that the newly added item can be rendered on the UI.
As expected the panel is updated and I see another autocomplete on the UI. But the problem is, all the auto completes now don't work. i.e. they stop firing the query event and don't give any suggestions.
Edited: The partial response that updates the section of form with autocomplete fields, contains some script tags, which probably execute on page ready/load event. So I know that basically the newly added prime faces widgets are not being initialized.
Any idea how I can initialize the newly added autocompletes in the DOM?
The reason for all this trouble was an error in javascript that was caused by trying to scrollTo a particular element on the page from the bean. This crappy line of code in the bean was the source of all the trouble. There was no element on the page with the id messages. A glaring example of why UI should not be coupled in such a way.
RequestContext.getCurrentInstance().scrollTo("formId:messages");

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

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.

method not getting called on onclick event

I am createing page using JSF 2.0:
<h:selectBooleanCheckbox id="checkbox1" title="Published"
onclick="#{StageGate.setMyCheckboxValue()}" />
I was expecting setMyCheckboxValue() to be called whenever checkbox is clicked. However, setMyCheckboxValue() is called once when page is loaded.
If I write
<h:selectBooleanCheckbox id="checkbox1" title="Published"
onclick="#{StageGate.setMyCheckboxValue()}; alert(document.getElementById('checkbox1').checked);" />
I get alert for each click.
My Question is: When I am getting alert, why setMyCheckboxValue() is not getting called on each onclick event?
Note: I also tried AJAX, but the checkbox remains constant.
The onclick attribute is for client side (javascript) methods and will not change anything on the server side.
If you want to change a server side value you need the value attribute:
<h:selectBooleanCheckbox value="#{StageGate.myCheckboxValue}" .../>
Note that I changed your setMyCheckboxValue() to myCheckboxValue because the setter method is automatically detected by jsf (if you correctly define your variable foo with the getter getFoo() and the setter setFoo(...))
onclick is used for client side javascript calls.
I think you want to call a function on server side, when a checkbox is clicked.
Here is the code:
<h:selectBooleanCheckbox id="checkbox1" title="Published"
value="#{StageGate.myCheckBox}" >
<f:ajax event="change" execute="#this"
action="#{StageGate.setMyCheckboxValue()}" />
</h:selectBooleanCheckbox>
I hope this will work for you.

JSF2, Ajax partial update and ui repeat - submit and update dynamically added text boxes

I have a JSF2 application and a page with the following code:
<h:inputText id="someInput" required="true" />
<p:outputPanel id="itemsPanel">
<ui:repeat var="i" value="#{myBean.itemIndices}" id="items">
<h:inputText
id="itemInput"
value="#{myBean.dataItems[i]}"
/>
<h:panelGroup
layout="block"
styleClass="clear"
rendered="#{((i+1) % 10 == 0)}"
/>
</ui:repeat>
</p:outputPanel>
<br/>
<p:commandButton
classStyle="btn"
value="Add Row"
actionListener="#{myBean.increaseItemsCount}"
update="itemsPanel"
immediate="false"
ajax="true"
/>
The ui:repeat is dynamically rendering a number if text boxes depending on the itemIndices and dataItems properties. The "Add Row" button calls a method that will dynamically increase the number of itemIndices and dataItems, therefore additional text inputs appear.
The current code will not work if there is no value in the text box someInput, because the AJAX request also validates the form and validation fails. Pressing the button in this case has no visual effect, not even feedback for the user that validation did not pass (because I update itemsPanel only).
If I change the button to have immediate="true", then the validation issue is no more. Unfortunately, I want to be able to restore the values of the dynamic input fields that the user might have changed prior adding the new row. The immediate="true" attribute causes the form not to be submitted to the server, therefore the user-entered data will not be persisted.
A possible solution to this could be to add process="all dynamic input ids csv" attribute to the command button and set the immediate attribute back to true. This will cause the server to validate only the inputs specified in the process attribute and they will be persisted. The problem here is that these input ids are dynamically generated by JSF and I cannot come up with a proper way to get them as a CSV. I would also not prefer a solution for dynamically generating ids in myBean relying on assumptions of how JSF would output them.
All suggestions will be greatly appreciated.
You could use process="itemsPanel".
<p:commandButton
classStyle="btn"
value="Add Row"
actionListener="#{myBean.increaseItemsCount}"
process="itemsPanel"
update="itemsPanel"
ajax="true"
/>
You should only move the command button into <h:outputPanel id="itemsPanel">.