[SalesForce] Passing ID of an apex:inputfield to javascript

I'm new to developing visual force pages and forgive me if this is an easy question but I'm having problems getting the ID of an apex:inputfield and passing it to javascript. What I'm trying to do is

  1. create a link/button that will get the value (by passing ID) of a certain inputfield
  2. populate the other inputfields based on the value of #1

I have this code that calls the javascript

    <apex:outputLink value="javascript:compute('{!$Component.Amount}', '{!$Component.lc1}', '{!$Component.lc2}', '{!$Component.lc3}', '{!$Component.lc4}', '{!$Component.lc5}', '{!$Component.lc6}')">Compute</apex:outputLink>

lc1, lc2, lc3…lc6 as you might guess are the ids of the variables im going to use.

Here comes the part where i get the problem of no id being passed, the javascript.

    <script>
            function compute(amount, lc1, lc2, lc3, lc4, lc5, lc6) {
                alert(document.getElementById(amount));

                /* Compute the loan charges depending on the loan amount here
                document.getElementById(lc1).value = 6;
                document.getElementById(lc2).value = 6;
                document.getElementById(lc3).value = 5;
                document.getElementById(lc4).value = 5;
                document.getElementById(lc5).value = 5;
                document.getElementById(lc6).value = 5;*/
            }
    </script>

The part alert(document.getElementById(amount)) should alert the id of amount inputfield right? What am I doing wrong here? Are there specific places where the javascript call or the script itself should be placed? Thanks for an answer in advance!

Best Answer

The $Component notation is quite picky about the correct number of prefixes, so if your amount, lc1 elements are nested inside other Visualforce components (such as pageblocks, datatables, outputpanels) you need to include the full hierarchy to get the correct name. I used to build this up in baby steps starting with the outermost container and check the page source each time to see if the $Component rendered anything (meaning it was a valid path) or if it was blank (meaning invalid).

These days I use a JQuery selector to find the element that ends with the particular id - that way I don't have to worry about the location prefixes and I can move elements around the page without having to rebuild the "fully qualified" name.

I include JQuery from a CDN, but you could load it as a static resource :

<apex:includescript 
      value="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" />

and then pass the id string literals to the JavaScript function :

<apex:outputLink value="javascript:compute('Amount', 'lc1',  ... etc);
  Compute
</apex:outputLink>

then build up JQuery selectors based on the literal ids:

<script>
    function compute(amount, lc1, lc2, lc3, lc4, lc5, lc6) {

       /* Compute the loan charges depending on the loan amount here */
          $('[id$=' + lc1 + ']').val(6);
          $('[id$=' + lc2 + ']').val(6);
         ... etc
    }
</script>

The key aspect of the selector is the '[id$=' + lc1 + ']' this translates to 'the element with an id that ends with the contents of the lc1 variable'. I've also used the JQuery val() method to set the value of the element.