14

I have a list of Strings which can be selected or not. When the user clicks save, I need to check which Strings are selected or not from within Javascript.

I made an inner class to set a selected value for each String:

public class RelatedListWrapper{

        public String relListName {get;set;}
        public Boolean selected {get;set;}

        public RelatedListWrapper(String s){

            relListName = s;
            selected = false;           
        }
    }

and in the class itself I have the following variable:

public List<RelatedListWrapper> relatedListNames {get;set;}

which I am populating in the class.

In the Visualforce page, I have the following code:

<apex:pageBlockSection columns="1">
                <apex:outputPanel id="relatedListSelect">
                    <apex:repeat value="{!relatedListNames}" var="relList" id="theRelLists">
                        <apex:inputCheckbox value="{!relList.selected}"/>
                        <apex:outputText value="{!relList.relListName}"/><br/>
                    </apex:repeat>                                              
                </apex:outputPanel>
            </apex:pageBlockSection>

I have tried several ways of accessing this in javascript, including creating an Array and calling the push method for each repeat value, but as 'selected' is initially set to false, it doesn't recognize it has been checked.

I also tried getting a reference to the outputPanel with

<script> var relatedLists = document.getElementById("{!$Component.relatedListSelect}");</script>

which gives me an HTMLSpanElement I'm not sure what to do with.

Can anyone help? I can use jQuery if this is easier.

15

Add a styleclass="" to your components, then use jQuery's selectors. You can't use Id because it has to be set to a static item.

<apex:pageBlockSection columns="1">
                <apex:outputPanel id="relatedListSelect">
                    <apex:repeat value="{!relatedListNames}" var="relList" id="theRelLists">
                        <apex:inputCheckbox styleClass="{!relList.relListName} inputIsChecked" value="{!relList.selected}"/>
                        <apex:outputText value="{!relList.relListName}"/><br/>
                    </apex:repeat>                                              
                </apex:outputPanel>
</apex:pageBlockSection>

Then in jQuery you can do:

<script type="text/javascript">
$('.inputIsChecked').each(function(i,o){
   $(o).is(':checked');
   //can get the name of the element here in a variety of ways, 
   //split the classes and take the one that is the name of the list-element. 
});
</script>

Does that get you started?

  • 3
    I eventually went with this method and it seems to work fine. All the answers were great though. Loving the StackExchange site, much better than the SFDC graveyard dev forums. – George S. Aug 31 '12 at 13:24
  • 1
    @user449 If I could ++++ your comment.... :-) – Saariko Sep 1 '12 at 14:36
5

Even though everything looks nice and clean from the VF perspective, the resulting HTML is going to be a bunch of nested elements that makes referencing from javascript difficult.

In order to ease the burden of walking the DOM tree I would suggest using jQuery. Specifically you want to do 2 things.

     function getValue(checkbox){
     };
  1. Bind the input type=checkbox.

     $(input[type=checkbox]).click(getValue(el));
    
  2. traverse the dom to get the related value from the name element

    getValue(el){
      if(el.checked){
        //1. get first parent of both checkbox and textfield
        //2. find child text field and get value.
      }
    }
    
1

I usually use the styleClass approach with jQuery that Jordan suggested when dealing with pages, especially any non-trivial larger pages. However, you can access the individual elements if you need to using the Component IDs. Check out the reference Best Practices for Accessing Component IDs

Here is an example that roughly uses your Visualforce page and no jQuery and the documented way of accessing Component IDs generated from within an iteration. The key is to have IDs on everything up to what you are accessing so that you can reliably use the colon notation.

<apex:page controller="RelatedListController" id="page">
    <apex:form id="form">
        <apex:pageBlock id="block">
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save" onclick="saveValidation();"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection columns="1" id="section">
                <apex:outputPanel id="relatedListSelect">
                    <apex:repeat value="{!relatedListNames}" var="relList" id="list">
                        <apex:inputCheckbox value="{!relList.selected}" id="selected"/>
                        <apex:outputText value="{!relList.relListName}" id="name"/><br/>
                    </apex:repeat>                                              
                </apex:outputPanel>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
    <script type="text/javascript">
        function saveValidation() {
            var listSize = {!relatedListNames.size};
            var isValid = true;
            var i;
            var checkbox;
            var text;
            for (i = 0; i < listSize; i++) {
                checked = document.getElementById('page:form:block:section:list:' + i + ':selected').checked;
                text = document.getElementById('page:form:block:section:list:' + i + ':name').firstChild.data;

                // Do whatever you need to do here...
                alert(text + '=' + checked);
            }

            return isValid;
        }
    </script>
</apex:page>

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.