[SalesForce] Binding input to a hidden variable with JS

I've got a datepicker attached to an input text, and I need to make the text value available to my apex variable "LaunchDate." It's not binding. I even tried putting onfocus="SetLaunchD()" in the commandlink, without luck.

Further inspection reveals the Javascript isn't getting the value of the input text id="datepicker" — an alert I put in there to dubug shows ddate is undefined. Am I missing something?

Sub-question: I use a commandlink to post the form. Method InsertNewData flags any blank fields by setting a boolean for an applicable output panel. So, for example, someone forgot to enter a Launch Date, the error panel will be rendered. This works fine with rerender="" or none at all, but when using rerender="LaunchDateError" the panel doesn't become visible, consequently needing to reload the whole form in order to see any form validation errors. What's up? I need to save my launch date variable definitely, and secondarily a more fluid response would be nice.

Any Suggestions?

VisualForce:

<apex:outputpanel id="LaunchDateError" styleclass="RedError" rendered="{!ShowLaunchDateRequired}"> 
Launch Date is Required.</apex:outputpanel>

<apex:inputHidden value="{!LaunchDate}" id="myHiddenVar" />

<input type="Text" id="datepicker"  value="{!LaunchDate}" onblur="SetLaunchD()"/>

<apex:commandLink styleClass="SubmitButton" action="{!InsertNewData}" 
                                  rerender="">
<!--  "Mainform, Pro1Error, ProductError, ClientError, LaunchDateError"> -->
Submit New Client </apex:commandLink>

Javascript:

function SetLaunchD() {
   var ddate = document.getElementById('datepicker').Value;
    document.getElementById('{!$Component.myHiddenVar}').value=ddate;  
} 

Best Answer

Accessing elements with $Component variable is sometimes tricky as it requires full path from the location where its accessed upto the element.

Prepared a visual diagram, might help in understanding clearly-

enter image description here

Here is an example to illustrate:

<apex:page id="page">

    <script>
        // method to print the value
        function printElementId(elementId, location) {
            console.log('elementId is ' + elementId + 
                ' | clicked from ' + location + 
                ' | value is ' + document.getElementById(elementId).innerHTML);
        }
    </script>
    <apex:form id="form">
        <apex:pageBlock id="pb"> 
            <apex:pageBlockSection id="pbs">
                <apex:pageBlockSectionItem id="pbsi">
                    <apex:outputLabel value="User Name"/>
                    <apex:outputPanel onclick="printElementId('{!$Component.userName}', 'outputPanel');"
                        id="userName">Dummy Panel</apex:outputPanel>
                </apex:pageBlockSectionItem>
                <apex:commandButton value="Inside PBS"
                    onclick="printElementId('{!$Component.pbsi:userName}', 'PBS button');"
                    rerender="form"/>
            </apex:pageBlockSection>
            <apex:commandButton value="Inside PB"
                onclick="printElementId('{!$Component.pbs:pbsi:userName}', 'PB button');"
                rerender="form"/>
        </apex:pageBlock>
        <apex:commandButton value="Inside form"
            onclick="printElementId('{!$Component.form:pb:pbs:pbsi:userName}', 'form button');"
            rerender="form"/>
    </apex:form>
    <input value="Inside page" type="button"
        onclick="printElementId('{!$Component.page:form:pb:pbs:pbsi:userName}', 'page button');"/>
</apex:page>
Related Topic