0

I have a large <apex:form>, and in one section of the form, I am displaying a checkbox list based on the values on a custom object picklist ("Case Reasons"). The user can choose multiple items. If one of the items she chooses is "Other", an inputTextArea called "Details" should show. If "Other" is not checked (or checked and then unchecked again), "Details" should not show/hide again.

I have gotten everything to work EXCEPT I cannot show/hide the input field based on "Other" being checked specifically. With the code below, I can show/hide the "Details" input based on the checking and unchecking of ANY box in the list ... I just can't seem to iterate all of the items and look for which ones are selected before showing/hiding the input.

Variable "selectedReasons" should have the selected values I believe, but when toggleDetails() is called, this list is empty/no items.

Thank you in advance for any help!

UPDATE: When using a <apex:commandButton> to call toggleDetails(), the <apex:selectCheckboxes> is not null and has selected items. However, we do not want to implement this as a button click. The "Details" input needs to show hide based on a single selected item in a checkbox list.

CONTROLLER

public with sharing class CreateClaimVF {
    public List<SelectOption> reasonsForClaim {get;set;}
    public List<String> selectedReasons {get;set;}
    public Boolean showDetails {get;set;}

//***
//when page loads, among other things, calls the getReasonsForClaim() method
//and ensures the Details field is hidden by default
//***
Public CreateClaimVF(ApexPages.StandardController controller) {
    //other code ...

    //Get Case Reasons
    reasonsForClaim = getReasonsForClaim();
    showDetails = false;        
}

//***
//gets the "Case Reasons" picklist values and stores as reasonsForClaim
//***
Public List<SelectOption> getReasonsForClaim() { 
        List<SelectOption> reasons = new List<SelectOption>();
        Schema.DescribeFieldResult fieldResult = Case.Reason_for_Claim__c.getDescribe();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        for(Schema.PicklistEntry p : ple) {
            reasons.add(new SelectOption(p.getValue(), p.getValue()));
        }       
        return reasons;
}

//***
//when any of the checkboxes are clicked, this method is called each time
//***
public PageReference toggleDetails() {
        //this just toggles back and forth regardless of checkbox selection
        //needs to instead set showDetails to true if "Other" is checked, 
        //otherwise leave showDetails as false if "Other" not checked

        if(showDetails == true) { 
            showDetails = false; 
        } 
        else { 
            showDetails = true; 
        }    
        return null;
}

}

VF PAGE

<apex:outputPanel id="reason_block" rendered="true">
   <apex:actionRegion>
      <apex:selectCheckboxes id="reason_boxes" layout="pageDirection" value="{!selectedReasons}">
         <apex:selectOptions value="{!reasonsForClaim}" /> 
            <apex:actionSupport action="{!toggleDetails}" rerender="out" event="onclick" immediate="true" status="status" />
         </apex:selectCheckboxes>
   </apex:actionRegion>

   <apex:outputPanel id="out">
      <apex:inputTextarea id="details_input" html-placeholder="Details" rows="5" cols="50" rendered="{!showDetails}" />                                                                                
   </apex:outputPanel>

</apex:outputPanel>
0

Since the selected options are being stored in selectedReasons, you can just use selectedReasons.contains( 'Other' ) as the conditions like such:

public PageReference toggleDetails() {
    if ( selectedReasons != null && selectedReasons.contains( 'Other' ) ) {
        showDetails = true; 
    } else { 
        showDetails = false; 
    }
    return null;
}

If you'd prefer, you can also write the code for toggleDetails like this to take up less space (though the code will require a little bit more effort to read)

public PageReference toggleDetails() {
    showDetails = ( selectedReasons != null && selectedReasons.contains( 'Other' ) );
    return null;
}

I think that should work. I didn't test it myself, so let me know if there are any syntax errors or logical issues with the code. Good luck!

| improve this answer | |
  • toggleDetails sb a void method – cropredy Nov 2 '19 at 17:58
  • Thanks for the reply, @Roti. This solution doesn't work because selectedReasons is empty/no items in toggleDetails(). – SJ2363 Nov 5 '19 at 14:29
0

I have a solution, and I'm posting this for anyone else who needs this answer in the future!

Instead of <apex:actionSupport> on the <apex:selectCheckboxes>, use <apex:actionFunction> to invoke AJAX using JavaScript. This is the key to why a <apex:commandButton> worked, but a click event on the checkbox list itself did not. Here's an article that led me to this answer: https://developer.salesforce.com/forums/?id=906F0000000BQw5IAG

Also, be sure to instantiate selectedReasons on page load so that it is not null to begin with. You'll notice that change in my code below as well.

VF PAGE:

<apex:outputPanel id="reason_block" rendered="true">
   <apex:actionFunction action="{!toggleDetails}" name="toggleDetails" rerender="out" />
   <apex:actionRegion>
      <apex:selectCheckboxes id="reason_boxes" layout="pageDirection" value="{!selectedReasons}" onclick="toggleDetails()">
         <apex:selectOptions value="{!reasonsForClaim}" /> 
      </apex:selectCheckboxes>
   </apex:actionRegion>
   <apex:outputPanel id="out">
      <apex:inputTextarea id="details_input" html-placeholder="Details" rows="5" cols="50" rendered="{!showDetails}" />                                                                                
   </apex:outputPanel>
</apex:outputPanel>

CONTROLLER:

public with sharing class CreateClaimVF {
    public List<SelectOption> reasonsForClaim {get;set;}
    public List<String> selectedReasons {get;set;}
    public Boolean showDetails {get;set;}

//***
//when page loads, among other things, calls the getReasonsForClaim() method
//and ensures the Details field is hidden by default
//***
Public CreateClaimVF(ApexPages.StandardController controller) {
    //other code ...

    //Get Case Reasons
    reasonsForClaim = getReasonsForClaim();
    selectedReasons = new List<String>(); //add this to instantiate
    showDetails = false;        
}

//***
//gets the "Case Reasons" picklist values and stores as reasonsForClaim
//***
Public List<SelectOption> getReasonsForClaim() { 
        List<SelectOption> reasons = new List<SelectOption>();
        Schema.DescribeFieldResult fieldResult = Case.Reason_for_Claim__c.getDescribe();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        for(Schema.PicklistEntry p : ple) {
            reasons.add(new SelectOption(p.getValue(), p.getValue()));
        }       
        return reasons;
}

//***
//when any of the checkboxes are clicked, this method is called each time
//***
public PageReference toggleDetails() {
   //Sets showDetails to true if "Other" is checked, otherwise leave showDetails as false
   if(selectedReasons != null && selectedReasons.contains('OTHER')) {
     showDetails = true;
   } else {
     showDetails = false;
   }
   return null;        
}

}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.