Manu
Manu

Reputation: 3247

how to disable multiple h:inputtext fields in JSF

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:

  1. on entered data in 1st input field the other input fields should be disabled(ie. 2,3,4).
  2. on entered data in 2nd input field the other input fields should be disabled(ie. 1,3,4). and so on.. Note: at the sametime if user entered data in 1st or 2nd or 3rd or 4th (user dynamic)field and delete the same before leaving out the input field in such case all field should be enabled. When i get response back(empty or non-empty data response) after clicking "search" button now all the input fields should be enabled for another search(now user may input data in any of the 4 fields)

Upvotes: 2

Views: 7433

Answers (2)

Michał Kupisiński
Michał Kupisiński

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

cubbuk
cubbuk

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

Related Questions