Reputation: 3247
In my home page(.xhtml),I'm having 4 h:inputText box and one serach button(h:commandButton)in JSF page
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt'>
<h:inputText id="pmtID" value="#{searchSettlementTransRequest.pmtTransId}" name='pmt'>
<h:inputText id="AgentID" value="#{searchSettlementTransRequest.AgentId}" name='agnt'>
<h:inputText id="AgencyID" value="#{searchSettlementTransRequest.AgencyId}" name='agncy'>
<h:commandButton id="tranSearchBtn" styleClass="valign first button-search sSearch" action="stlmtSubmit"/>
My requirement is:
Upvotes: 2
Views: 7433
Reputation: 3863
If you want to do this only in jsf just have to add some AJAX calls. Some suggestions below:
Add to all your <h:inputText
attribute disabled
with value of #{searchSettlementTransRequest.getDisabled('this_component_id')"
. So the whole thing will look like this:
<h:inputText id="someId1" value="#{searchSettlementTransRequest.someValue}" name="stlmt" disabled="#{searchSettlementTransRequest.getDisabled('someId1')}"/>
Next in your bean processing this request change settter for `stlmTransId, pmtTransId, AgentId, AgencyId' that their will mark that this value is being set:
public void setXXX(XXX xxx) {
// your actual code comes here and at the end set that this component was changed
actuallyChanged = id_of_input_text_component_corresponding_to_this_value_as_string;
}
Of course you have to add field String actuallyChanged
to your bean.
Method getDisabled(String compId)
will know looks:
public String getDisabled(String compId) {
if (actuallyChanged.equals(compId)) {
return "";
else {
return "disabled";
}
}
For all your components you have also add AJAX call like this:
<f:ajax event="change" execute="@this" render="stlID pmtID AgentID AgencyID"/>
So know when value of one component will change all other will be disabled. But there is immposible to make them enabled after call is make because without cliend side scripting you cannot easly make them available on select or focus gained or anything.
If you like to disable components temporary, for example when user type in one component other all disabled, but when he select some of them then this one selected is enabled and all other, included this in which he firstly write text, will be disable. In that case better aproach is to use client side scripting for this, JavaScript for example.
Update to exactly match your problem in JavaScript (jQuery)
add to all components an event like this:
onkeyup="$('#thisComponentId').attr('disabled', false); $('#otherComponentId').attr('disabled', true); $('#otherComponentId').attr('disabled', true); "
After your comment you can change it to:
onkeyup="if ($('#thisComponentId').val() && $('#thisComponentId').val() == '') { // here set enable for all components } else { // here set disable for all other components }
This isn't very sophisticated way but it should work. Know when you start typing in one component other will be disabled but when you send request all will be enabled again.
Upvotes: 1
Reputation: 7920
If you want the inputs to be enabled after each page load you can have a flag representing the page is loaded and set that flag to false after each ajax request through an listener. And to ensure that the flag is set to true after complete page loads you can use preRenderView
event. You just need a method to be executed for preRenderView
event which set the flag to true if the page is loaded through complete request rather than an ajax request. If the page is loaded with ajax request, faces-request
parameter will be set to "partial/ajax".
public static final String INITIAL_VALUE = ""; // I assume your fields are integer and they are initialized to INITIAL_VALUE in the first place
public Boolean pageIsLoadedWithFullRequest = true;
public void preRenderView()
{
//check whether the request is an ajax request or not
Map<String, String> requestHeaderMap = FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
if(!"partial/ajax".equals(requestHeaderMap.get("faces-request")))
{
pageIsLoadedWithFullRequest = true;
}
And if you want to disable other inputs whenever the user writes into one of the fields, you can make an ajax call after a blur event to change the state of other input fields and set the pageIsLoadedWithFullRequest
flag to false in a listener.
public void madeAjaxRequest()
{
pageIsLoadedWithFullRequest = false;
}
public Boolean getStlIDEnabled()
{
return pageIsLoadedWithFullRequest || !stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getPmtTransIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && !pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getAgentIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && !AgentId.equals(INITIAL_VALUE) && AgencyId.equals(INITIAL_VALUE);
}
public Boolean getAgencyIdEnabled()
{
return pageIsLoadedWithFullRequest || stlmtTransId.equals(INITIAL_VALUE) && pmtTransId.equals(INITIAL_VALUE) && AgentId.equals(INITIAL_VALUE) && !AgencyId.equals(INITIAL_VALUE);
}
<f:event type="preRenderView" listener="#{searchSettlementTransRequest.preRenderView()}"/> <!--This will ensure that preRenderView method will be called right before rendering of the view ends -->
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt' disabled="#{not searchSettlementTransRequest.stlIDEnabled}"/>
<h:inputText id="pmtID" value="#{searchSettlementTransRequest.pmtTransId}" name='pmt' disabled="#{not searchSettlementTransRequest.pmtTransIdEnabled}"/>
<h:inputText id="AgentID" value="#{searchSettlementTransRequest.AgentId}" name='agnt' disabled="#{not searchSettlementTransRequest.AgentIdEnabled}"/>
<h:inputText id="AgencyID" value="#{searchSettlementTransRequest.AgencyId}" name='agncy' disabled="#{not searchSettlementTransRequest.AgencyIdEnabled}"/>
If you want to disable them through ajax you should add the f:ajax command and render all four of these inputTexts. Example:
<h:inputText id="stlID" value="#{searchSettlementTransRequest.stlmtTransId}" name='stlmt' disabled="#{not searchSettlementTransRequest.stlIDEnabled}">
<f:ajax event="blur"
listener=#{searchSettlementTransRequest.madeAjaxRequest()}
execute="stlID pmtID AgentID AgencyID"
execute="stlID pmtID AgentID AgencyID"/>
</h:inputText>
Unrelated It is not a good practice to capitalize the first letters of variables such as AgentId, AgencyID, it should be better if you change them to agentId and agencyID.
Cheers
Upvotes: 1