function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
dfalsodfalso 

How to rerender/interact with custom component: design help needed

Hi all,
First let me say thanks for helping me out thus far. I'm very appreciative of those helping us out on this forum. Especiallly those of us like myself who are relatively new to SF development.

I'm making a custom VF page tied to an address table object:
Code:
<apex:page standardController="Address__c" extensions="AddressExt" showHeader="true" sidebar="true" >
    <apex:sectionHeader title="{!$ObjectType.Address__c.label}" subtitle="{!Address__c.name}"/>
 <apex:form >
  <apex:pageBlock title="Address Information">
   <apex:pageBlockSection columns="1">
             <apex:inputField id="curStreetNo" value="{!Address__c.Street_Number__c}"/>
             <apex:inputField id="curStreetName" value="{!Address__c.Street_Name__c}"/>
             <apex:inputField id="curCity" value="{!Address__c.City__c}"/>
             <apex:inputField id="curState" value="{!Address__c.State__c}"/>
             <apex:inputField id="curZIP" value="{!Address__c.ZIP_Code__c}"/>
             <p/>
             <apex:outputText id="AddressString" value="{!FullAddressString}"/>
      </apex:pageBlockSection>
     </apex:pageBlock>
 </apex:form>
 <apex:pageBLock title="PolicyMap">
  <c:MapComponent AddressString="{!FullAddressString}"/>
 </apex:pageBLock>
</apex:page>
 (FullAddressString is a method in my controller extension that simply concatenates the pieces together to send to the map component)

 I've created a custom component to map said address:
Code:
<apex:component >
 <apex:attribute name="AddressString" description="Address String" type="String" required="true" />
 
 <html>
        <head>
            <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
            <title>TRF Test</title>

   <script language="javascript" type="text/javascript">
    function setAddress()
    {
     var JSaddressString = '{!AddressString}';

     var curTextBox = document.getElementById("addressTextBox"); 
     curTextBox.value = JSaddressString;
    }

    function showAddress(address) 
    {
     var geocoder = new PClientGeocoder();
     var map = new PMap(document.getElementById("map"));
        // Geocode address, center, add marker and open info window
        if (geocoder) {
            geocoder.getLatLng(
                address,
                function(point) {
                    if (!point)
                            alert("Address \"" + address + "\" not found");
                    else {
                        map.setCenter(point, 13);
                        var marker = new PMarker(point);
                        map.addOverlay(marker);
                        marker.openInfoWindowHtml(address);
                    }
                }
            );
        }
    }
   </script>
            <script src="http://api.pushpin.com/js—key=<mykey>" type="text/javascript">
            </script>
        </head>
  <body onload="setAddress()" onunload="PUnload()">
   <form action="#" id="form1" onsubmit="showAddress(this.address.value); return false">
    <p>
    Find Address: 
    <input id="addressTextBox" type="text" size="55" name="address"/>
    <input type="submit" value="Go" />
    <input type="button" value="Refresh Textbox" onclick="setAddress();"/>
    </p>
   </form>
   <div id="map" style="position: relative; width: 700px; height: 700px; border: 1px solid #979797"></div>
   <div id="message"></div>
  </body>
 </html>
</apex:component>

 (Note: PushPin is very close to Google in API so this should look about the same to someone used to Google Maps)
This in itself works just fine. Well, almost - the onload() call in the HTML body doesn't work. I have to push the "Refresh Textbox" button to manually call the function. Any ideas?

But here's the design question:
Ultimately, what I want is to remove the textbox in the custom component and refresh the map component whenever someone changes a value in one of the address fields (not the saved row - this is meant for validation before committing the record). To do this I'll need to fire an onchange event from each inputField that reads from the component values themselves and either
a) rerenders the map component (assuming I can ever get onload() to work), or
b) directly calls a method inside the map component (say, setAddress())

Is b) even possible? Anyone have advice on how they would design this setup?

Thanks for any help provided.
dfalsodfalso
Update:
I've set this up to rerender every time the user changes a field value:
Code:
<apex:page standardController="Address__c" extensions="AddressExt" showHeader="true" sidebar="true" >
    <apex:sectionHeader title="{!$ObjectType.Address__c.label}" subtitle="{!Address__c.name}"/>
 <apex:form >
<!-- General Info -->
  <apex:pageBlock title="General Information">
   <apex:inputField id="thisName" value="{!Address__c.Name}"/>
  </apex:pageBlock>

<!-- Address Components -->
  <apex:pageBlock title="Address Information">
   <apex:pageBlockSection columns="1">
    <apex:inputField id="curStreetNo" value="{!Address__c.Street_Number__c}">
     <apex:actionSupport event="onchange" reRender="MapThisAddressComp"/>
             </apex:inputField>
             <apex:inputField id="curStreetName" value="{!Address__c.Street_Name__c}">
     <apex:actionSupport event="onchange" reRender="MapThisAddressComp"/>
             </apex:inputField>
             <apex:inputField id="curCity" value="{!Address__c.City__c}">
     <apex:actionSupport event="onchange" reRender="MapThisAddressComp"/>
             </apex:inputField>
             <apex:inputField id="curState" value="{!Address__c.State__c}">
     <apex:actionSupport event="onchange" reRender="MapThisAddressComp"/>
             </apex:inputField>
             <apex:inputField id="curZIP" value="{!Address__c.ZIP_Code__c}">
     <apex:actionSupport event="onchange" reRender="MapThisAddressComp"/>
             </apex:inputField>
             <p/>
      </apex:pageBlockSection>
     </apex:pageBlock>
  <apex:commandButton value="Save" action="{!save}"/>
 </apex:form>
 <apex:pageBlock title="PolicyMap">
        <apex:outputPanel id="MapThisAddress">
   <c:MapComponent id="MapThisAddressComp" AddressString="{!FullAddressString}"/>
  </apex:outputPanel>
 </apex:pageBlock>
</apex:page>

 
but it feels really clunky. I'd much rather call my setAddress() function that lives in the component.