JSF onclick event on combobox - jsf

I don't know how to implement onclick event on a combobox, my boss want me to do is once the user click a value in the combobox it automatically search and display all the value of the selected/click item. First question is it possible to have an onclick event on a JSF page without using any javascript/jquery? Right now I'm using ADF for designing the interface. Second question how can I implements this onclick event on my combobox?

There are a couple of ways to achieve this:
Use a valueChangeListener and execute your query when it fires.
Set autoSubmit="true" and when the bound value changes, execute your query.

Only selecting a value in a dropdown won't submit your form. This is not about JSF but HTML .. so without any JS i think it's not possible.
I do not know anything about ADF in special but in plain JSF you just have to add an ajax-event to your dropdown (e.g. in primefaces)
<h:form id="id1">
<p:selectOneMenu id="id2" value="#{myBean.value}"
immediate="true" editable="true" >
<f:ajax execute="#this" listener="#{myBean.doSomeAction}" />
<f:converter converterId="myConverter" />
<f:selectItems value="#{myBean.availableOptions}" />
</p:selectOneMenu>
</h:form>

Related

I can't update my components when I change the state of selectOneButton component

I'm using primefaces to implement my web site and I'm facing an issue.
I've used selectOneButton component and depending on which button is selected I want to show a specific datatable. So when I click the button1 I want to show table1, and table2 when I click the button2.
This is the code I am using:
<p:selectOneButton
value="#{myBean.dataTableType}"
valueChangeListener="#{myBean.dataTableTypeChange}">
<f:selectItems value="#{myBean.dataTableTypes}"
var="type"
itemLabel="#{msg['datatable.type.'.concat(type)]}"
itemValue="#{type}" />
<p:ajax update="table1 table2"/>
</p:selectOneButton>
With this code, I'm unable to reach what I want :(
I think you can very well look at the following example and keep a render flag for your tables in the listener invoked in the bean.
https://stackoverflow.com/a/8409360/3403415
Hope it helps!!
You should declare an attribute process for ajax with value #this. This attribute say to selectOneButton to set value into bean when will happen some event for selectOneButtton. And you will have an actual value for datatable type.
Now you don't have it. And if you have a condition for example:
<ui:fragment rendered="#{myBean.dataTableType eq FirstTable}">
<p:datatable id="first_table">
...
</p:datatable>
</ui:framgent>
Condition return false..

Can we create textbox right next to selectonemenu component when we fire selectoneMenu valueChangeListener event

want to create textbox on the fly is it possible?
Select Report to run:
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<f:ajax listener="#{reportBean.getReqID}" render="reqID"> </f:ajax>
</h:selectOneMenu>
Seems like you want to show/hide the <h:inputText> based on the selected value on your <h:selectOneMenu>. Yes, this can be easily achieved with plain JSF.
Note that if you use set the rendered attribute as false the component won't appear in the component tree, so there will be no way it can't be referenced for any call (not even ajax calls). In order to update it, you should wrap the component inside another component like <h:panelGroup> and render the wrapper. Basic example:
<h:form id="frmRep">
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<!--
assuming your reportBean.getReqID method will change the value of
reportBean.showReqID attribute to render/not render it and works well
-->
<f:ajax listener="#{reportBean.getReqID}" render="pnlRepName" />
</h:selectOneMenu>
<h:panelGroup id="pnlRepName">
<h:inputText id="reqID" rendered="#{reportBean.showReqID}"
value="#{reportBean.reportName}" />
<h:panelGroup>
</h:form>
For this specific requirement instead, I won't recommend using an ajax call since it has to go to the server to only check if the component should or should not be showed to the user. I would opt for a JavaScript solution to handle this just on client side.

p:dialog closes when valueChangeListener is invoked

I have a <p:dialog> which contains a <h:selectOneMenu> with a valueChangeListener. Here's the relevant code:
<p:dialog>
<h:form>
<div>
<h:selectOneMenu value="#{itemController.itemId}" valueChangeListener="#{itemController.chkItemType}" onchange="submit()">
<f:selectItems value="#{itemController.itemsList}" />
</h:selectOneMenu>
</div>
</h:form>
</p:dialog>
When it is called, the dialog get closed. I would like to keep it open and only close it on cancel button. How can I achieve this?
That's expected behaviour. The onchange="submit()" which you've there submits the entire form synchronously, causing a complete page reload.
You should be using ajax instead to perform the submit. Replace the onchange attribute by just this tag
<f:ajax />
inside the <h:selectOneMenu>. This way the form will be submitted asynchronously, with by default no page reload at all.
Depending on the concrete functional requirement, which you didn't tell anything about, you do probably also not need a valueChangeListener at all, but rather a <f:ajax listener>.
<f:ajax listener="#{itemController.chkItemType}" />
If you'd like to update some parts of the page on successful execution of the ajax request, use its render attribute.
See also:
When to use valueChangeListener or f:ajax listener?

Restrict f:validator on a specific submit button alone

I'm having a JSF form in which I have a textarea and multiple buttons.
For the text area I'm doing validation using f:validator
<f:validator validatorId="myValidator" />
<a4j:support event="onsubmit" ajaxSingle="true" process="textarea1" />
The validator is working as expected. Now i have multiple submit buttons on the page i want the validation to happen on specific button only and validator should be ignored on the remaining buttons.
Is there anyway to restrict the validator on a specific submit button alone. Thanks.
You can use the disabled attribute.
<f:validator validatorId="myValidator" disabled="#{empty param['formId:buttonId']}" />
Where formId is the ID of your <h:form> and the buttonId is the ID of the button which is supposed to be the only button to trigger validation.
I assume that you want to submit the textarea value to the server when clicking on other buttons too (so no point of playing with the process attribute)
How about adding immediate="true" to the other buttons ?
That way they will skip validation, while the submit button without immediate="true" will do the validation as expected
Or
There seems another workaround in this article JSF 2 - Conditionally Skip Validation
Something like
<h:commandButton action="#{bean.someMethod"} value="Submit2">
<f:param name="skipValidation" value="true"/>
</h:commandButton>
and inside the validate method of the validator check for the skipValidation attirbute (look for further explanation in the article...)

Update form from value change of Primefaces spinner

I am trying to update my form on the basis of changes of the spinner
<p:spinner id="spin1" min="1" max="#{editPhoto.max}" size="1"
value="#{editPhoto.page}" validator="#{editPhoto.validator()}"
valueChangeListener="#{editPhoto.refreshForm()}" />
<p:commandButton value="Insert" action="#{editPhoto.insertImage()}" />
<p:commandButton value="Delete" action="#{editPhoto.deleteImage()}" />
I've put break points in the value, setPage as well as in the validator and valueChangeListener and it hits them only when I press the commandButton. I've tried immediate="true", but that adds nothing. What I really want is to know when the value has been changed, but without having to hit the commandButton.
In a previous question BalusC suggested the use of
<f:event type="preRenderView" listener="#{nextpageBacking.onPreRenderView}" />
I suspect that I need something similar here, but what sort of event should I be looking for? Maybe not, so what do I need to do to get changes in the spinner without having to press on the commandButton? Thanks, Ilan
My bean is view-scoped. Perhaps the answer is to use another request scoped-bean and have the request scoped-bean operate on the view-scoped bean? I will try this if this looks like the correct direction.
You should use f:ajax or p:ajax.
The valueChangeListener will only fire when the whole form or the spinner is submitted.
<p:spinner id="spin1" min="1" max="#{editPhoto.max}" size="1"
value="#{editPhoto.page}" validator="#{editPhoto.validator()}">
<p:ajax listener="#{editPhoto.refreshForm()}"
update="#form" process="#this" />
</p:spinner>
The valueChangeListener attribute of the spinner is not the best place to fire your method. You should better put it in the listener attribute of p:ajax. The valueChangeListener should be used if you are interested in the old and the new value.

Resources