Vertical Radio-Buttons with table/ui:repeat - jsf

I need to achieve radio-buttons in multiple HTML-Table-Columns.
The number of Columns and Rows is dynamic (data-driven).
Example:
Input 1
Input 2
Input n
O (group 1)
O (group 2)
O (group n)
O (group 1)
O (group 2)
O (group n)
O (group 1)
O (group 2)
O (group n)
My code creates the table like this:
<table>
<ui:repeat value="rows" var="row">
<tr>
<ui:repeat value="cols" var="col">
<td>
O (group col.id)
</td>
</ui:repeat>
</tr>
</ui:repeat>
</table>
Now the question is: How can i create the needed radio-buttons the JSF-way?
All available components don't work this way:
p:selectOneRadio with custom layout doesn't play nice with ui:repeat, because i need one per column (not one per column and row)
h:selectBooleanCheckbox won't render as radio-buttons, so no MUTEX per group and wrong HTML

You can do this without ui:repeat by applying some CSS. For example:
<div style="display: flex">
<p:selectOneRadio id="group1" layout="responsive" columns="1">
<f:selectItem itemLabel="Group1 Option1" itemValue="Option1"/>
<f:selectItem itemLabel="Group1 Option2" itemValue="Option2"/>
<f:selectItem itemLabel="Group1 Option3" itemValue="Option3"/>
</p:selectOneRadio>
<p:selectOneRadio id="group2" layout="responsive" columns="1">
<f:selectItem itemLabel="Group2 Option1" itemValue="Option1"/>
<f:selectItem itemLabel="Group2 Option2" itemValue="Option2"/>
<f:selectItem itemLabel="Group2 Option3" itemValue="Option3"/>
</p:selectOneRadio>
<p:selectOneRadio id="group3" layout="responsive" columns="1">
<f:selectItem itemLabel="Group3 Option1" itemValue="Option1"/>
<f:selectItem itemLabel="Group3 Option2" itemValue="Option2"/>
<f:selectItem itemLabel="Group3 Option3" itemValue="Option3"/>
</p:selectOneRadio>
</div>

Related

rich:dataList vertically ordered between 2 columns

I have a dataGrid with 2 columns and a panelGrid inside it that shows the data correctly, but it fills both columns before changing row. I need it to fill first column, with half of list content and only then go to second column and fill it with rest. It is a static list with an even number right now, but it would be best if it could be done with a dynamic sized list with possible odd total number of values. There is an answer here in SO that shows that asp has a repeatcolumn tag that (if i understood correctly) does what i need. Is there a way to do that using richfaces in jsf?
<fieldset>
<legend>Select topics:</legend>
<rich:dataGrid value="#{registerForm.topics}"
var="topic"
columns="2">
<h:panelGrid columns="2" width="430px"
columnClasses="checkTopic,labelTopic" border="0">
<h:selectBooleanCheckbox id="checkTopic"
align="left"
value="#{registerForm.SelectedTopic}"
disabled="#{not registerForm.ActiveRegister}"/>
<h:outputLabel value="#{topic.description}"
for="checkTopic" />
</h:panelGrid>
</rich:dataGrid>
<h:panelGroup rendered="#{empty registerForm.topics}"
style="color: red;">
No topics registered.
</h:panelGroup>
</fieldset
I think I should use ui:repeat, but cant figure out how. I tried using dataList and dividing the list in 2 parts and each shown in a separed row, but didnt look good, also the code feels overcomplicated than it should be.
Also this question is the same as mine, but the answer doesnt correspond exctly to what is needed and i cant comment because 50 reputation.
I need:
Value1 Value3
Value2 Value4
With the code I have(and the answer) the result is:
Value1 Value2
Value3 Value4
Well you can't change the direction of the items, but you can reorder the list so instead of [1,2,3,4,5] you'll have [1,4,2,5,3].
Alternatively you could use the rendering index (rowKeyVar) and have your bean do the math figuring out what item should be displayed (essentially ignoring the list you're passing to the component).
Solved the issue using two DataTables and the "first" attribute. Had to create "getLines" class in backend, that returns listsize/2 (roundup), because I couddnt figure out how to do it in front end (but plan on doing).
<fieldset>
<legend>Select topic:</legend>
<h:panelGrid id="topicspanel" columnClasses="topicscol,topicscol" columns="2" border="0">
<rich:dataTable value="#{registerForm.topics}"
var="topic" columns="1" rows="#{registerForm.lines}"
border="0" id="table1">
<rich:column>
<h:panelGrid columns="2" width="430px"
columnClasses="checkTopic,labelTopic" border="0">
<h:selectBooleanCheckbox id="checkTopicCol1" align="left"
value="#{registerForm.selectedTopic}"
disabled="#{not registerForm.activeRegisters}" />
<h:outputLabel value="#{topic.name}"
for="checkTopicCol1" />
</h:panelGrid>
</rich:column>
</rich:dataTable>
<rich:dataTable value="#{registerForm.topics}"
var="topic" columns="1" rows="#{registerForm.lines}"
border="0" id="table2" first="#{registerForm.lines}"
align="right">
<rich:column>
<h:panelGrid columns="2" width="430px"
columnClasses="checkTopic,labelTopic" border="0">
<h:selectBooleanCheckbox id="checkTopicCol2" align="left"
value="#{registerForm.selectedTopic}"
disabled="#{not registerForm.activeRegisters}" />
<h:outputLabel value="#{topic.name}" for="checkTopicCol2" />
</h:panelGrid>
</rich:column>
</rich:dataTable>
</h:panelGrid>

Get string behind binding object

I have the following JSF construct:
<c:set var="myVar" value="#{myBean.getMyMap()}" scope="request" />
<h:form>
<p>
<h:outputText value="Output1: " />
<h:selectOneMenu value="#{myMappingsBean.data.attribute1}" binding="#{input1}" required="true">
<f:selectItems var="entry" value="#{myVar}"/>
<p:ajax update="myDropdown"/>
</h:selectOneMenu>
</p>
<p>
<h:outputText value="Output2: " />
<h:selectOneMenu id="myDropdown" value="#{myMappingsBean.data.attribute2}" binding="#{input2}" required="true" converter="javax.faces.Double">
<f:selectItems var="entry" value="#{myVar.get(input1.value)}"/>
</h:selectOneMenu>
</p>
</h:form>
Behind myVar is a map defined like that: Map<String, Collection<Double>>
The first dropdown menu shows a list of all the keys of that map (like desired), but the value behind that is the collection of values.
Here the HTML output of one option of that dropdown:
<option value="[1.0, 2.0]">SomeString</option>
My second dropdown should list the collection of double values stored in the map behind the key, that is selected by the first menu.
The problem now is, when I use value="#{myVar.get(input1.value)}" the value I get from .value is the collection and not the string/key of the map. So I never get the desired result.
How can I get the string/key behind the binded object input1? Is there something like input1.name or .toString? Is somewhere a documentary for this?
Ok, I solved it by applying the solution from here.
The first drop down has to be edited to the following:
<p>
<h:outputText value="Output1: " />
<h:selectOneMenu value="#{myMappingsBean.data.attribute1}" binding="#{input1}" required="true">
<f:selectItems var="entry" value="#{myVar.entrySet()}" itemValue="#{entry.key}" itemLabel="#{entry.key}"/>
</h:selectOneMenu>
</p>
As you can see, the entry set is created from the map and from that you use the key as value and label.
And with that the value behind input1.value now is not the collection of doubles but the key of the map.

Is it possible to change EL base on the selected value from dropdown list?

<th>
<h:outputText value="Pending Actions" style="font-weight:bold" />
<td colspan="4">
<p:selectOneMenu value="#{selectedValue}" required="true">
<f:selectItem itemValue="#{null}" itemLabel="--Select One--" />
<f:selectItem itemValue="organization1" itemLabel="ORGANIZAION1" />
<f:selectItem itemValue="organization2" itemLabel="ORGANIZAION2" />
<f:selectItem itemValue="organization3" itemLabel="ORGANIZAION3" />
<f:selectItem itemValue="organization4" itemLabel="ORGANIZAION4" />
</p:selectOneMenu>
<h:inputTextarea value="#{casesBean.organization1PendingActionDetails}"/>
</td>
</th>
As shown above, there is a dropdown list to let users select which organization they want to assign task.
In my database, there are columns
organization1PendingActionDetails,
organization2PendingActionDetails, etc.
So my question is:
Is it possible to change the inputTextarea value
based on the selected value from the dropdown list?
For example:
If the user selected organization2 then the inputTextarea will become value="#{casesBean.organization2PendingActionDetails}"
You will probably need to have more than one inputTextarea. Each area should have different value, and rendered set based on selected value. After selection set proper rendered value on inputTextarea and update it via ajax.
<p:ajax event="change" listener=#{casesBean.decideRenderedInputTextArea} update="InputTextAreasWrapper" />
Better solution:
It is way more elegant to have one inputTextArea. As you said you want to store the values from it into the database. So decide where to store data based on selected value inside been before performing action which will store data into database (after submit form).

How to visualize the elements in one line in Primefaces

I have the following form:
<h:form>
<h:selectOneMenu value="#{userRequestBean.selectedAgencyId}">
<f:selectItem itemLabel="Select" noSeletionOption="true" />
<f:selectItems
value="#{userRequestBean.requestAgencies[userActiveRequest]}"
var="agency" itemLabel="#{agency[0]}" itemValue="#{agency[1]}" />
</h:selectOneMenu>
<p:commandButton value="Hire"
action="#{userRequestBean.hireAgency}">
<f:setPropertyActionListener target="#{userRequestBean.request}"
value="${userActiveRequest}" />
</p:commandButton>
</h:form>
and i would like the SelectOneMenu and Button to be on one line. I tried with panelGrid but the select one menu becomes invisible, the same happens when i tried to use the standard HTML table. Can you give me an advice how to put then on one line? Thanks in advance!
use panelGrid and play with columns option. If you have N components and you want to put them in one line set columns value to N like:
<h:form>
<p:panelGrid columns="2" id="oneLineStyle">
<h:selectOneMenu value="#{userRequestBean.selectedAgencyId}">
<f:selectItem itemLabel="Select" noSeletionOption="true"/>
<f:selectItems
value="#{userRequestBean.requestAgencies[userActiveRequest]}"
var="agency" itemLabel="#{agency[0]}" itemValue="#{agency[1]}"/>
</h:selectOneMenu>
<p:commandButton value="Hire"
action="#{userRequestBean.hireAgency}">
<f:setPropertyActionListener target="#{userRequestBean.request}"
value="${userActiveRequest}"/>
</p:commandButton>
</p:panelGrid>
</h:form>

Adding space between two radio buttons of h:selectOneRadio

In JSF 2.0 I have below
<h:selectOneRadio value="#{StageGate.sketchesSG002006Decision}" onclick="validateMyRadioButton()" id="radio26">
<f:selectItem itemValue="Accepted" itemLabel="Accepted" id="accepted"/>
<f:selectItem itemValue="Rejected" itemLabel="Rejected" id="rejected"/>
</h:selectOneRadio>
I get output as
O Accepted O Rejected
^^
What I want is add space between two radio button so that output would be
O Accepted O Rejected
^^^^^^^^^^^
I tried adding between two radio button however it is not working. I am getting radio button on next line.
<h:selectOneRadio value="#{StageGate.sketchesSG002006Decision}" onclick="validateMyRadioButton()" id="radio26">
<f:selectItem itemValue="Accepted" itemLabel="Accepted" id="accepted"/>
<f:selectItem itemValue="Rejected" itemLabel="Rejected" id="rejected"/>
</h:selectOneRadio>
Any idea how this can be done?
HTML generated without is
<table id="radio26">
<tr>
<td>
<input type="radio" checked="checked" name="radio26" id="radio26:0" value="Accepted" onclick="validateMyRadioButton()" /><label for="radio26:0"> Accepted</label></td>
<td>
<input type="radio" name="radio26" id="radio26:1" value="Rejected" onclick="validateMyRadioButton()" /><label for="radio26:1"> Rejected</label></td>
</tr>
</table>
When I add &nbsp one space is generated before <table id="radio26"> statement.
Disclaimer, I don't know anything about JSF, so the following is based on my experience of ASP.NET and adding spaces in there. If this is wildly incorrect, please let me know, and I will remove immediately...
Try adding the space to the item label, updating...
<f:selectItem itemValue="Accepted" itemLabel="Accepted" id="accepted"/>
To...
<f:selectItem itemValue="Accepted" itemLabel="Accepted " id="accepted"/>
It might need to be escaped itself into...
<f:selectItem itemValue="Accepted" itemLabel="Accepted &nbsp; &nbsp;" id="accepted"/>
UPDATE
As the OP says in the comments, this will extend the link.
Looks like you should be able to set a CSS class to the parent object with something like...
<h:selectOneRadio styleClass="myRadioCtrl" ... >
And then in your style / CSS have something like...
.myRadioCtrl span { padding-right: 10px; }
Just thought id share my answer... after inspecing the page with firebug i ended up with the following
JSF:
<h:panelGroup id="search-options" layout="block" styleClass="radioButtonSpace">
<h:selectOneRadio value="#{searchEngineController.reportSearch}">
<f:selectItem itemValue="#{false}" itemLabel="CEPIS Search" />
<f:selectItem itemValue="#{true}" itemLabel="Report Search" />
</h:selectOneRadio>
</h:panelGroup>
CSS:
.radioButtonSpace table tbody td {padding-right:50px;}
I was having difficulties with this. Applying Style did not work for me when I did it on h:selectOneRadio, however it worked when applied in panelgroup wrapping around it.
Nothing of these answers worked for me, but like this works perfectly:
.ui-selectoneradio label{ padding-right: 10px !important; }
This is in case using primefaces

Resources