You need to sign in to do that
Don't have an account?
ContactId inputField fails to invoke "onchange" action if user uses magnifying glass
<apex:inputField value="{!theCase.ContactId}" id="the_contact"> <apex:actionSupport event="onchange" action="{!contactChangedAction}" status="updating_assets_status" rerender="assets, the_asset, asset_message" immediate="false"/> </apex:inputField>
If the user types or pastes in a valid Contact name, the apex contactChangedAction() method is invoked. But if the user presses the magnifying glass, contactChangedAction() is not invoked. How can I make sure that contactChangedAction() is invoked, by whatever means the user changes the contact?
Here's what I ended up doing. The actionSupport for onblur performs my ajax update in the case where the user pastes or types a contact name into the contactId lookup field.
The javascript at the bottom of the page is invoked when the window (the whole page) either loses or gains focus. On loss of focus, it remembers what the contact name was. On gaining focus, it forces the onblur actionsupport to run if the contact name has been changed. This handles the case where the user uses the magnifying glass.
Best of all, it doesn't seem likely to break when salesforce changes their implementation internals.
<apex:form id="theForm">
<apex:sectionHeader title="Case Edit" subtitle="New Case"/>
<apex:pageBlock title="Case Edit" id="whole_page">
<apex:pageBlockSection>
<apex:inputField value="{!theCase.ContactId}"
id="the_contact">
<apex:actionSupport event="onblur"
action="{!contactChangedAction}"
status="updating_assets_status"
rerender="whole_page"
immediate="false"/>
</apex:inputField>
<apex:inputField value="{!theCase.AssetId}"
styleClass="Asset"
id="the_asset"/>
<apex:pageBlockSectionItem>
<label/>
<apex:outputPanel id="asset_message">
<apex:outputPanel rendered="{!LEN(assetMessage)!=0}">
<div class="statusMsg">
<apex:outputText value="{!assetMessage}"/>
</div>
</apex:outputPanel>
</apex:outputPanel>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem>
<label/>
<apex:actionStatus startText="(updating...)" id="updating_assets_status" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<script>
var theContact = document.getElementById("{!$Component.contact_and_asset}"+":the_contact");
</script>
</apex:pageBlock>
</apex:form>
<script>
var previousOnblur = window.onblur;
var previousContact;
window.onblur = function() {
if (previousOnblur) {
previousOnblur();
}
console.log('losing focus');
previousContact = theContact.value;
}
var previousOnfocus = window.onfocus;
window.onfocus = function() {
if (previousOnfocus) {
previousOnfocus();
}
console.log('gaining focus');
if (theContact.value != previousContact) {
console.log('contact changed');
theContact.onblur();
}
}
</script>
</apex:page>
All Answers
So, I still wish someone could find a better solution, but that was one of workarounds.
If you really want to use onchange, you could implement the magnifying glass with SFDC JavaScript openlookup and set your function to window.close event, or use showModalpopup and call your function after that ( showModalpopup will wait for closing the window).
This is a very classic automation so that I hope there is easier way.
ThomasTT
Here's what I ended up doing. The actionSupport for onblur performs my ajax update in the case where the user pastes or types a contact name into the contactId lookup field.
The javascript at the bottom of the page is invoked when the window (the whole page) either loses or gains focus. On loss of focus, it remembers what the contact name was. On gaining focus, it forces the onblur actionsupport to run if the contact name has been changed. This handles the case where the user uses the magnifying glass.
Best of all, it doesn't seem likely to break when salesforce changes their implementation internals.
<apex:form id="theForm">
<apex:sectionHeader title="Case Edit" subtitle="New Case"/>
<apex:pageBlock title="Case Edit" id="whole_page">
<apex:pageBlockSection>
<apex:inputField value="{!theCase.ContactId}"
id="the_contact">
<apex:actionSupport event="onblur"
action="{!contactChangedAction}"
status="updating_assets_status"
rerender="whole_page"
immediate="false"/>
</apex:inputField>
<apex:inputField value="{!theCase.AssetId}"
styleClass="Asset"
id="the_asset"/>
<apex:pageBlockSectionItem>
<label/>
<apex:outputPanel id="asset_message">
<apex:outputPanel rendered="{!LEN(assetMessage)!=0}">
<div class="statusMsg">
<apex:outputText value="{!assetMessage}"/>
</div>
</apex:outputPanel>
</apex:outputPanel>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem>
<label/>
<apex:actionStatus startText="(updating...)" id="updating_assets_status" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<script>
var theContact = document.getElementById("{!$Component.contact_and_asset}"+":the_contact");
</script>
</apex:pageBlock>
</apex:form>
<script>
var previousOnblur = window.onblur;
var previousContact;
window.onblur = function() {
if (previousOnblur) {
previousOnblur();
}
console.log('losing focus');
previousContact = theContact.value;
}
var previousOnfocus = window.onfocus;
window.onfocus = function() {
if (previousOnfocus) {
previousOnfocus();
}
console.log('gaining focus');
if (theContact.value != previousContact) {
console.log('contact changed');
theContact.onblur();
}
}
</script>
</apex:page>
I wonder if there are any typos in the script. I'm getting an error that theContact.onblur() is not a function.
It seems the script is failing to invoke onblur on the lookup text component.
Please advise.
Thank you