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
KeithJKeithJ 

Lookup onchange with actionSupport

Hi there. I have the following code that leverages a custom object called "Test__c", that has
1 field, which is a lookup to Accounts.

Code:
<apex:page standardController="Test__c" tabStyle="Test__c">
    <apex:sectionHeader title="{!$ObjectType.Test__c.label} Edit" subtitle="New Test"/>
    <apex:form>
    <apex:pageBlock title="Test">
        <apex:pageBlockButtons>
            <apex:commandButton value="Save" action="{!save}" />
            <apex:commandButton value="Cancel" action="{!cancel}" />
        </apex:pageBlockButtons>
    <apex:actionRegion>
        <apex:pageBlockSection title="Information">
            <apex:inputField value="{!Test__c.Account__c}">
                <apex:actionSupport event="onselect" rerender="otherPanel" />
            </apex:inputField>
        </apex:pageBlockSection> 
    </apex:actionRegion>  
    
    <apex:pageBlockSection title="test" id="otherPanel" rendered="true">
        <apex:outputField value="{!Test__c.Account__c}" />
    </apex:pageBlockSection>
    </apex:pageBlock>
    </apex:form>
</apex:page>

Now, when I type a value into the lookup box and I select a value from the autocomplete, the value in the "test" pageBlockSection will update in an Ajax fashion like so:
 

But when I use the lookup dialog to select an account, the field will not update:


Any ideas??
Thanks
Ron HessRon Hess
i've noticed this also, the onchange event is associated with the input field at a javascript level, and when the lookup picker sets the value into this field, the onchange event is not fired.

I've not found a solution yet, i'll post back here if i figure this out.
TehNrdTehNrd
One workaround is have a button or command link that says "Retrieve Account Info". Then you can perform the query and rerender the output section.


Message Edited by TehNrd on 12-10-2008 01:52 PM
KeithJKeithJ
Thanks for the replies.
That workaround seems like a prudent approach. :)
Regards
KeithJKeithJ
Hi Ron. Any update relating to this? I had to work around it by using a select list instead of a lookup.
Not my optimal route albeit it works.
Would this be worth logging for the next release?
Kind regards
Ron WildRon Wild

Has anyone found a solution for this?  (In particular getting a lookup field to trigger a visualforce action and rerender)

 

 

 

 

mattdarnoldmattdarnold

Try using event="onblur"

 

I was dealing with this same issue and I ran across this thread. I am using event="oblur" in my actionSupport component and it is rerendering my components as expected whether the user enters information by hand or uses the look-up function. It does require that the user leave the field (in this case opportunity.accountId), but that seemed to be the case with event="onchange" as well.

 

-- Matt

Ron WildRon Wild

That's what I'm using right now (in lieu of support for 'onchange') ... however it's not an ideal work around.  I really need to execute the actionsupport when the content changes and not when the user tabs through the field.

 

Thanks though.

 

I'm curious to know if SF engineers are working to provide support for "onchange" events with lookup fields - or if it's just an issue we should plan to work around.   Can anyone on the inside report?

 

- RW

mattdarnoldmattdarnold

Not sure if this will help your situation, but I am checking to see if the data has actually changed in the getter for my rerendered components and when the lookup field doesn't change, my components don't appear to rerender. I agree it isn't ideal though.

 

-- Matt

LloydCLloydC
Has anyone found a solution to this?  In my case, a custom case edit page, a picklist would be unacceptable due to the large number of accounts and using onblur just doesn't work well enough.
LizIchihaLizIchiha

Ron,

 

Is there a solution for this yet?  I am currently using the onblur event, but it doesn't give me quite the behavior i want.

 

Thanks!

Rajesh ShahRajesh Shah

@mattdarnold  

How do you that? Can you provide some sample code? I am stuck in the same problem.

Message Edited by Rajesh Shah on 12-02-2009 09:12 PM
PaulATPimptastiPaulATPimptasti

Hi Guys,

 

Has anyone found a fix for this? OnBlur works great as a workaround.

 

Cheers

 

Paul 

ConejoConejo

Back to top with this one...

 

This thread started quite a while ago, and there isn't a resolution yet. It seems like a pretty basic thing to have lookup fields work similarly to the other fields and trigger an 'onchange' event. Is there any method we can use to bring some attention to this longstanding issue?

 

Has anyone posted an Idea on this yet?

 

Can someone from SalesForce let us know if this is being looked at?

 

 

Thanks,

 

Rich C.

ConejoConejo

There is an idea posted:

 

https://sites.secure.force.com/ideaexchange/ideaView?c=09a30000000D9xt&id=08730000000HD0MAAW

 

Go vote it up everyone!

 

Thanks,

 

Rich C.

SteveBowerSteveBower

I've hacked this up as a proof of concept and it seems to work fine in Chrome.   It would need some cleaning up for IE seeing that it uses a different event listener call, etc.  

 

It's super-ugly!!!   :-)

 

1. In essence, set an onClick event of your own not on the *lookup* field, but on the Icon the user clicks to do the Lookup. 

 

2. That event starts an interval timer that polls the field to see if it changes, and if it does, calls the specific onChange function. 

 

<apex:page id="thePage" standardController="Opportunity">
<apex:form id="theForm">
<apex:inputField id="theField" value="{!Opportunity.AccountId}"/>
</apex:form>

<script type="text/javascript">

function a() {
	alert('Hi, I\'m your friendly onChange Trigger.');
}

var timer;
var nLoops;

function checker(id, startVal, changer) {
	if (startVal != (document.getElementById(id)).value) {
		nLoops = 99999;
		changer();
	} else {
		nLoops = nLoops + 1;
	}
	if (nLoops >= 120) {
		clearInterval(timer);   // Allow 120 intervals = 60 sec.
	}
}		
	
function setWatcher(id, changer) {
	var icon = document.getElementById(id + '_lkwgt'); // the lookup widget
	icon.addEventListener("click", 
		function startPoll() {
			nLoops = 0;
			timer = setInterval('checker(\'' + id + '\',\'' + (document.getElementById(id)).value + '\',' + changer + ')', 500)  // 1/2 sec loop.
		}
	,false);
}
	
setWatcher('j_id0:theForm:theField', a); // why isn't this "thePage"?
	
</script>

</apex:page>

 

 

 

Polling is very ugly, however since we know we're dealing with events at "user-speed", we can poll infrequently (I used 1/2 second), and we can limit the number of times we poll such that if the user doesn't choose an object using the lookup within a given period (I chose 60 seconds), the onChange wouldn't fire.  (So, that's a gap, but it limits the time this loop will be running.)

 

So, if you really can't use onBlur, this seems to do the job.  Again, it's a proof of concept and it's late.  :-)

 

Best, Steve.

 

 

ConejoConejo

Steve,

 

  Putting the event on the lookup icon and starting a timer is clever. I pondered a couple workarounds usign the lookup icon, but didn't think of this.

 

  I'll try to spend some time on it this evening and get it working in jQuery to eliminate the cross browser event problems and post my results.

 

  If someone around here has some extjs-fu and wants to get it working that would be appreciated as well! Then people could use this w/o bringing in another javascript library.

 

Thanks,

 

Rich C.

SteveBowerSteveBower

A little friendlier, but I still haven't addressed IE.   Sigh.

 

 

<!-- To try this, use /apex/onChangeTriggerHack?id= an opportunity id -->

<apex:page id="thePage" standardController="Opportunity">
	<apex:form id="theForm">
	
	<apex:messages />
	
	<apex:actionFunction name="myAction" action="{!save}" rerender="theOutputSection"/>
	
		<apex:pageBlock id="thePageBlock">
			<apex:pageBlockSection id="theSection">
				<apex:inputField id="theField1" onChange="myAction()" value="{!Opportunity.AccountId}"/>
				<apex:inputField id="theField2" onChange="a()" value="{!Opportunity.CampaignId}"/>
			
				<apex:inputField id="theField3" value="{!Opportunity.OwnerId}"/>
			</apex:pageBlockSection>

			<apex:pageBlockSection id="theOutputSection">
				<apex:outputField value="{!Opportunity.Account.Name}"/>
				<apex:outputField value="{!Opportunity.Campaign.Name}"/>
			</apex:pageBlockSection>
			
		</apex:pageBlock>
	</apex:form>

<script type="text/javascript">
function a() {
	// Or you could have an intermediate JS function.
	alert('Hi, I\'m your friendly onChange Trigger: A, calling actionFunction: myAction');
	myAction();
}
</script>



<script type="text/javascript">

/*
So, all you have to do is take this block of Javascript and append it to your VF page (before the closing apex:page tag).  
It will find all your Lookups and give them all onChange capability.

Instead of using actionSupport, define a actionFunction and set your onChange function to call it. 

Sadly, still not working for IE as I haven't broached the jQuery or ExtJs stuff yet.
*/

var timer;
var nLoops;

function checker(id, startVal, changer) {
	if (startVal != (document.getElementById(id)).value) {
		nLoops = 99999;
		changer();
	} else {
		nLoops = nLoops + 1;
	}
	if (nLoops >= 120) {
		clearInterval(timer);   // Allow 120 intervals = 60 sec.
	}
}
	
function setAllLookupOnchangeTriggers() {
	var node_list = document.getElementsByTagName('input');
	for (var i = 0; i < node_list.length; i++) {
    	var node = node_list[i];
    	if (node.onchange) {
    		var widget = document.getElementById(node.id + '_lkwgt');
    		if (widget) {
    			// For standard lookup fields without a user specifid onchange, SFDC uses class="error" on the widget. 
    			// there is no onChange, so let's piggyback on it.  If the user specifies a class on the tag, it might
    			// override this, I'm not sure.   Kind of hokey.
    			if (widget.className != 'error') { 
	    			attachEventToElement(widget,"click",
						function startPoll() {
							// "this" is the widget that has fired the event.  Get the id and trim off the '_lkwgt'
							var node = document.getElementById((this.id).slice(0,-6));
							nLoops = 0;
							timer = setInterval('checker(\'' + node.id + '\',\'' + node.value + '\',' + node.onchange + ')', 500);  // 1/2 sec loop.
						}
					)
				}
    		}
    	}
    }
} 

 
setAllLookupOnchangeTriggers();
</script>

</apex:page>

 

 

JDawg808JDawg808

Hi All,

 

I was having issues with this as well. After beating my head against the wall I think I may have discovered why it is not working. If this is old news, sorry for re-posting. I am only including the code that is relevent to the issue.

 

Here is the piece from my VF page

 

 

<apex:pageBlockSectionItem >            
    <apex:outputLabel for="CampaignId" id="CampaignLabel" value="Campaign"/>
    <apex:outputPanel >            
        <apex:inputField id="CampaignId" value="{!CampaignRecord.CampaignId}">                             
            <apex:actionSupport event="onchange" rerender="taskBlock" status="status" action="{!refreshTask}" immediate="true"/>
        </apex:inputField>
    </apex:outputPanel>
</apex:pageBlockSectionItem>

 

 

 

 

Here is the refreshTask code

 

 

public PageReference refreshTask()
{
    this.showTaskSectionValue = true;
        
    return null; //ApexPages.currentPage();    
} 

 

I was having problems with even just getting the action fire, or so it would seem. Once I change the refreshTask to return null, the onchange started working. Not sure why or if it is the correct thing to do but it works at this point :-). I have only tested the onchange part in the various browsers so not sure if there will be other issues but it seems to work as expected at this point.

 

 

If this does not work you, please post back so hopefully we can get this resolved and move on.

 

Jason