Is there a way to render a component based on the current value the user has selected from a selectOneMenu component? My selectOneMenu component is populated with an enum consisting of two values, smoker and non-smoker. If the user has smoker selected I want to render a checkbox below it which lets the user check how many they smoke a day 10, 20, 30+, etc. I also want the opposite to work if they user has selected non-smoker i.e. the check boxes don't render/disappear.
Just check the dropdown menu's value in the rendered attribute of the target components and update their common parent by a <f:ajax>. Here's a kickoff example:
<h:selectOneMenu value="#{bean.item}">
<f:selectItem itemValue="one" />
<f:selectItem itemValue="two" />
<f:selectItem itemValue="three" />
<f:ajax render="results" />
</h:selectOneMenu>
<h:panelGroup id="results">
<h:panelGroup rendered="#{bean.item eq 'one'}">
You have selected "one".
</h:panelGroup>
<h:panelGroup rendered="#{bean.item eq 'two'}">
You have selected "two".
</h:panelGroup>
<h:panelGroup rendered="#{bean.item eq 'three'}">
You have selected "three".
</h:panelGroup>
</h:panelGroup>
If you'd like to perform some business logic based on the selected value, use <f:ajax listener>.
<f:ajax listener="#{bean.changeItem}" render="results" />
public void changeItem() {
someResult = someService.getByItem(item);
}
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu
Conditionally displaying JSF components
Related
I am currently trying to setup an editable data table that uses ajax to maintain focus when a user edits a cell using either JavaScript or a backing bean, because when a cell edit occurs data in other parts of the table will need to be updated, thus the table should be redrawn, unfocusing the focused element. Currently I'm trying to do this using a p:focus, using a CellEditEvent listener to get the component id. Unfortunately, assigning to the variable for the focused component id is not changing which element is focused on the page.
Here is the relevant HTML:
<h:form id="addForm">
<p:focus id="focusID" for="#{beanView.focus}" />
<h:panelGroup id="entrypg">
<p:commandButton id="updateButton" widgetVar="updateButton" update="addForm:myDT" />
<p:dataTable id="myDT" widgetVar="myDT" var="iter" value="#{beanView.valList}"
editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{beanView.onCellEdit}" oncomplete="$('#addForm\\\:updateButton').click();"/>
<p:column headerText="X">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{iter.x}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{iter.x}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:panelGroup>
</h:form>
And the cell edit handler in the view:
public void onCellEdit(CellEditEvent edit) {
if(edit.getNewValue() != null) {
focus = edit.getColumn().getChildren().get(0).getClientId();
}
}
I am also open to better ways one could do this, as I'm unsureif p:focus is designed for this purpose.
Thanks!
Ok I've gotten it to work using widgets:
function forceFocus(index) {
var widget = PF('myDT');
widget.showCellEditor($('[role="gridcell"].ui-editable-column:eq(' + index + ')'));
}
The showCellEditor does pretty much exactly what I need, it highlights a cell and focuses it allowing immediate editing. It also seems to preserve focus between ajax calls.
More logic would be needed if you wanted to do this to a table with more than 1 editable column.
Edit: Ok it seems like its not storing the focus between table redraws, but it should be doable to grab the focus before the table is redrawn and restore it after its redrawn with the above function
i have a p:selectOneRadio
<p:selectOneRadio id="radioTpPunto" value="#{geoWebModel.radioPuntoBtnValue}" widgetVar="selectTipoRicerca">
<f:selectItem itemLabel="P. di Fermo" itemValue="1" />
<f:selectItem itemLabel="P. di Destinazione" itemValue="2" />
<p:ajax listener="#{geoRefCtr.doAction('radioPuntoChange')}" update=":geoForm:panelFiltroPosizione"/>
</p:selectOneRadio>
And everything is working fine when I click the 2 options : my method is called and my model is updated.
Now, I want to "emulate" this behaviour using Javascript and I've tried using something like:
selectTipoRicerca.jq.find('input:radio[value=2]').trigger('click.selectOneRadio');
My backing bean's method is called but the value of my model isn't updating.
Any clues ?
You can give that specific radio an ID and then use:
document.getElementById("myRadio").click();
this will trigger just as if a user clicked the radio button.
If you're using jQuery, you can shorten it to:
$("myRadio").click();
<h:dataTable id="merchantDataTable"
value="#{merchantManagementBean.merchants}" first="0"
rows="#{merchantManagementBean.rowsPerPage}" var="merchant"
styleClass="dataTable"
columnClasses="users-colMerchant, users-colMerchantDescr, nostyle"
rowClasses="oddRow, evenRow">
<h:column>
<f:facet name="header">
<h:panelGrid columns="1">
<h:selectBooleanCheckbox />
</h:panelGrid>
</f:facet>
<h:selectBooleanCheckbox value="#{merchant.selected}"/>
</h:column>
</h:datatable>
Yea so I have this code part and I need to make the main checkbox to make them all checked I can use Probably only Javascript based solution since communication with bean is going to server side.
Please have a look at the following posts:
How to create effective "select all" checkbox in JSF
how to create selectAll checkbox in JSF-2
Or you can approach this problem witj jQuery to select all checkboxes:
http://www.sanwebe.com/2014/01/how-to-select-all-deselect-checkboxes-jquery
How can i dynamically change the value of a h:dataTable? I have the following code (just a snippet):
<h:dataTable value="#{DataProvider.mapValues}" var="o" border="1">
<h:column>
<h:outputText value="#{o.key}"></h:outputText>
</h:column>
<h:column>
<h:outputText value="#{o.value}"></h:outputText>
</h:column>
</h:dataTable>
<h:selectOneMenu>
<f:selectItem itemLabel="Choose Language.."></f:selectItem>
<f:selectItem itemLabel="DE"></f:selectItem>
<f:selectItem itemLabel="CZ"></f:selectItem>
<f:selectItem itemLabel="EN"></f:selectItem>
<f:selectItem itemLabel="FR"></f:selectItem>
<f:selectItem itemLabel="ES"></f:selectItem>
<f:selectItem itemLabel="PT"></f:selectItem>
</h:selectOneMenu>
So, basically, when I choose a language from the SelectOneMenu, the dataTable should use different values (like "#{DataProvider.mapValues(en)"). To be clear: everytime I select a value from the Combobox, the dataTable should reload with an other value.
I guess this would work with JavaScript, but I don't know how exactly it has to be done.
Any help would be appreciated. Thanks!
EDIT: I have to use JSF1.2, so I can't use any built-in AJAX features.
Make DataProvider.getMapValues something like this:
private String selectedLanguage; // + getter and setter
private Map getMapForLanguage(String language)
{ ... }
public Map getMapValues(){
return getMapForLanguage(selectedLanguage);
}
bind the selectedLanguage to your h:selectOneMenu selected value and do an ajax update of h:dataTable upon selection like this:
<h:dataTable id="myTable" ... >
...
<h:selectOneMenu value="#{DataProvider.selectedLanguage}">
...
<f:ajax render="myTable"/>
</h:selectOneMenu>
How can I disable <p:selectBooleanCheckbox> component using JavaScript?
My goal is to prevent user from changing value of one selectBooleanCheckbox while another is changed during ajax request time (which change values in managed bean).
My simplified code :
<p:selectBooleanCheckbox id="..." value="..." widgetVar="abcde">
<p:ajax listener="..." update="..."/>
</p:selectBooleanCheckbox>
<p:selectBooleanCheckbox id="..." value="...">
<p:ajax listener="..." update="..." onstart="alert(document.getElementById('j_idt14:locationChoice2_input').disabled);document.getElementById('j_idt14:locationChoice2_input').disabled=true;alert(document.getElementById('j_idt14:locationChoice2_input').disabled)" />
</p:selectBooleanCheckbox>
j_idt14:locationChoice2_input id is the id of my first <p:selectBooleanCheckbox /> component.
alert() functions dsplay false and after true so my component is well disabled.
However, it stays with the same render event if it's disabled.
Is the only way to be changing manually CSS classes to match disabled state ? Can widgetVar help me ?
nb: I want to change immediately the aspect of the component so I don't use the JSF disabled attribute, I have to use JS.
I answer my own question.
I put inside simple panelGrid my 2 selectBooleanCheckbox and apply blockUI on this panelGrid :
<p:blockUI block="panelToBlock" widgetVar="block" />
<h:panelGrid id="panelToBlock">
<p:selectBooleanCheckbox id="..." value="..." widgetVar="abcde">
<p:ajax listener="..." update="..." onstart="block.show()" oncomplete="block.hide()" />
</p:selectBooleanCheckbox>
<p:selectBooleanCheckbox id="..." value="...">
<p:ajax listener="..." update="..." onstart="block.show()" oncomplete="block.hide()" />
</p:selectBooleanCheckbox>
</h:panelGrid>
blockUI has a default opacity value to 0.3 but I don't want to see it, I just want to disable my 2 selectBooleanCheckbox so I change the value of the generated id to 0 at runtime with JS :
$(window).load(function() {
$('#j_idt14\\:j_idt23_blocker').css('opacity', 0);
}
and that's all.
Now when ajax request is made, these 2 checkboxes values can not be changed.
Hope this helps