0

I have a requirement wherein if checkbox is true, picklist field must be enabled. If checkbox is false, picklist field must be disabled. But in default, picklist field must be disabled.

Enabling/disabling of picklist field is controlled by a javascript function also embedded in my visualforce page. However, each time I click the checkbox field, picklist field remained disabled.

How can I make this work with regards to the html tags inside the visualforce page?

Vf page portion:

<apex:column headerValue="Checkbox Field">
    <center>
        <table>
            <tr>      
                <td><apex:inputcheckbox id="cb" value="{!acc.Checkbox_Field__c}" onclick="check(this)"/></td>    
            </tr>
        </table>
    </center>                                
</apex:column> 

<apex:column headerValue="Picklist Field">   
    <center>
        <table>
            <tr>                      
                <apex:selectList id="pf" value="{!acc.Picklist_Field__c}" disabled="true" size="1">  
                    <!--PickListFields came from a method in apex class....-->
                    <apex:selectOptions value="{!PickListFields}"/> 
                </apex:selectList>  
            </tr>
        </table>
    </center>    
</apex:column>   

Javascript:

<script>

    function check(obj)
    {

        if((obj.checked == true)){

            document.getElementById('{!$component.pf}').disabled=false;
        }
        else{
            document.getElementById('{!$component.pf}').disabled=true;

        }
    }

</script> 

2 Answers 2

1

I'd avoid doing it with raw javascript & html, unless the element you're trying to interact with it also plain html. Salesforce puts a lot of extra information into other input elements that it manages under the surface. Trying to interact with a element may not work as expected unless you're using apex functionality. A great example of this is lookups, try inspecting one using your browser. You'll notice a additional set of input tags used to manage the old & new information, for a single field.


I usually manage behavior like this by making the attribute conditional, then re-rendering the element anytime the field is changed.

Something like:

<apex:selectList id="pf" value="{!acc.Picklist_Field__c}" disabled="{!NOT(acc.Checkbox_Field__c)}" size="1">  

You'll want to make sure that your Checkbox_Field__c is set to false when your component loads in order to start with the picklist disabled.

Then, instead of a javascript function, use a apex:ActionFunction. Same idea, but this allows talking directly to our controller, as well as rerender targets.

<apex:actionFunction name="UpdatePicklist" rerender="pf">
    <apex:param value="" name="CheckBox" assignTo="{!acc.Checkbox_Field__c}" />
</apex:actionFunction>

Make sure your checkbox has a event handler for this function:

<apex:inputcheckbox id="cb" value="{!acc.Checkbox_Field__c}" onchange="UpdatePicklist(this.value);" />

Now, when you modify the checkbox, a javascript function runs, which updates the value stored in the checkbox field, then rerenders the section with a conditional disabled attribute, which will either enable it or disable it, depending on the value.

Seems like you have the right idea, just need to execute it differently.


Disclosure: I'm writing this on my lunch break without actually testing the code. Some stuff might not be right, like not having an action attribute on the actionFunction or using the param to update a variables field.

Also, if you have existing javascript, ie, you need this function for more than just updating a fields disabled attribute, you can call an actionFunction inside javascript code, letting you write an event handler as normal, and call UpdatePicklist inside that code.

0

The problem with your code is that you are using {!$Component.pf} to find the correct select html element to update. This doesn't work because Salesforce generates the id before serving the pages and the generated string depends on placement of your component within other components.

Instead of relying on the id attribute we can safely use styleClass attribute with slight modifications to your code as follows.

Add a variable for generating unique class names

<!-- declare a visualforce variable outside of your pageBlockTable -->
<apex:variable value="{!0}" var="index" />

Add styleClass attribute and assign unique classNames using index variable

<apex:column headerValue="Checkbox Field">
    <!-- increment the value of this index inside apex:column -->
    <apex:variable var="index" value="{!index+1}" />
    <center>
        <table>
            <tr>      
                <td>
                    <!-- generates a unique className and assign it to checkbox field -->
                    <apex:inputCheckbox id="cb" styleClass="checkbox-{!index}" value="{!acc.Checkbox_Field__c}" onclick="check(this)"/>
                </td>    
            </tr>
        </table>
    </center>                                
</apex:column>
<apex:column headerValue="Picklist Field">   
    <center>
        <table>
            <tr>
                <!-- generates a unique className and assign it to select field -->                      
                <apex:selectList id="pf" styleClass="select-{!index}" value="{!acc.Picklist_Field__c}" disabled="true" size="1">  
                    <!--PickListFields came from a method in apex class....-->
                    <apex:selectOptions value="{!PickListFields}"/> 
                </apex:selectList>  
            </tr>
        </table>
    </center>    
</apex:column> 

Update the JavaScript function to get elements by className

<script type="text/javascript">
    function check(elem){
        var className = 'select-' + elem.className.split('-')[1];
        var selectFields = document.getElementsByClassName(className);
        for(var i=0; i<selectFields.length; i++) {
            // using for loop, but it going to be just one element
            if(elem.checked == true) {
                selectFields[i].disabled = false;
            } else {
                selectFields[i].disabled = true;
            }
        }
    }
</script>

Let me know if you have any questions.

Hope this helps.

PS: Make sure you generated classNames which are not there in your CSS otherwise CSS can modify the style of your markup.

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.