Hi,
Earlier we have talked about how to use dynamic binding with or without field set and dynamic binding when object is also dynamic. Now its time to go one level ahead.
My first question : Why we use dynamic binding ?
Ans : So that VFP Design can be configured on production org without any code change.
Mostly when we use field set or dynamic binding we can change our UI at any time but how to handle onclick event of any field if we have such requirement. We have only one inputField control in Repeat then how to call a javascript or actionFunction. We can not have dynamic UI at the cost of any business logic. So lets try to do it now
Requirement : We have a custom picklist field in the Field Set fields that we are displaying, "Is Active" having value "Yes" , "No" , “None” , if user select s yes then “No Of Employee” fields should become mandatory and if he changes it to other then “Yes” then it should be non mandatory. And also set No Of Employe = 5 whenever "Is Active" fields changes its value.
Step 1: First I Created a Field Set On Account , With Five Fields in the Field Set
Step 2: Create the Controller Class like this
//Controller class public class actionFunction_FieldSet { public Account account {get;set;} public boolean noOfEmpReq {get;set;} public String IsActive {get;set;} public actionFunction_FieldSet() { noOfEmpReq = false; account = new Account(); } //action function to be called public void actionFunctionM() { if(IsActive == 'Yes') noOfEmpReq = true; else noOfEmpReq = false; } }
Step 3: Create a VFP like this
<apex:page controller="actionFunction_FieldSet" title="Field Set Use"> <apex:form > <!-- Action function to determine required status for No of employee field --> <apex:actionFunction name="jsSetNoOfEmpReq" oncomplete="alert('action completed');" action="{!actionFunctionM}" immediate="true" reRender="pbsFS"> <apex:param assignTo="{!IsActive}" value="IsActive" id="IsActive" name="noEmpR"/> </apex:actionFunction> <script> var numberofemployeesID; function setNoOfEmpReq(ctrlIsActive) { //Assign value to the no of employee field if(document.getElementById(numberofemployeesID) != null) document.getElementById(numberofemployeesID).value = 5; //action function call jsSetNoOfEmpReq(ctrlIsActive.value); } </script> <apex:pageBlock title="Field Set Use"> <apex:pageBlockSection title="Field Set Use" id="pbsFS"> <apex:repeat value="{!$ObjectType.Account.FieldSets.DemoFieldSet}" id="ctrlRepeat" var="fieldAPIName"> <!-- 1. We have cretaed there input fields one will only if active__c field comes trough field set 2. second when numberofemployees comes 3. For other field Using such design we can have the dynamic design as well we can use onclick or onchange events on fields --> <apex:inputField value="{!account[fieldAPIName]}" onchange="setNoOfEmpReq(this);" rendered="{!IF(CONTAINS(LOWER(fieldAPIName), 'active__c') , true , false)}"/> <apex:inputField value="{!account[fieldAPIName]}" required="{!noOfEmpReq}" rendered="{!IF(CONTAINS(LOWER(fieldAPIName), 'numberofemployees') , true , false)}" id="NoOfEmp" /> <apex:inputField value="{!account[fieldAPIName]}" rendered="{!IF(OR(CONTAINS(LOWER(fieldAPIName), 'active__c') , CONTAINS(LOWER(fieldAPIName), 'numberofemployees')) , false , true)}" /> <script> /* Set the id for numberofemployeesID field can be used in java script */ if({!CONTAINS(LOWER(fieldAPIName), 'numberofemployees')}) { numberofemployeesID = '{!$Component.ctrlRepeat}:NoOfEmp'; } </script> </apex:repeat> </apex:pageBlockSection> </apex:pageBlock> </apex:form>> </apex:page>
So that was a very basic requirement when we need to use action function on any event of field from field set. Using similar approach we can solve big problems as well. We can also achieved it using only a single inputField and using onclick and passing field api name and performing actions only to valid fields otherwise return false.
<apex:page controller="actionFunction_FieldSet" title="Field Set Use"> <apex:form > <!-- Action function to determine required status for No of employee field --> <apex:actionFunction name="jsSetNoOfEmpReq" oncomplete="alert('action completed');" action="{!actionFunctionM}" immediate="true" reRender="pbsFS"> <apex:param assignTo="{!IsActive}" value="IsActive" id="IsActive" name="noEmpR"/> </apex:actionFunction> <script> var numberofemployeesID; function setNoOfEmpReq(ctrl , isctrlIsActive) { if(isctrlIsActive) { //Assign value to the no of employee field if(document.getElementById(numberofemployeesID) != null) document.getElementById(numberofemployeesID).value = 5; //action function call jsSetNoOfEmpReq(ctrl.value); } else return false; } </script> <apex:pageBlock title="Field Set Use"> <apex:pageBlockSection title="Field Set Use" id="pbsFS"> <apex:repeat value="{!$ObjectType.Account.FieldSets.DemoFieldSet}" id="ctrlRepeat" var="fieldAPIName"> <!-- 1. Used only one input field --> <apex:inputField value="{!account[fieldAPIName]}" onchange="setNoOfEmpReq(this , {!CONTAINS(LOWER(fieldAPIName), 'active__c')});" required="{!IF(CONTAINS(LOWER(fieldAPIName), 'numberofemployees') , noOfEmpReq , false)}" id="fieldId" /> <script> /* Set the id for numberofemployeesID field can be used in java script */ if({!CONTAINS(LOWER(fieldAPIName), 'numberofemployees')}) { numberofemployeesID = '{!$Component.ctrlRepeat}:fieldId'; } </script> </apex:repeat> </apex:pageBlockSection> </apex:pageBlock> </apex:form>> </apex:page>
Other Related Posts : Dynamic Binding : When Object Name is Dynamic Also
Regards
Shashikant Sharma