Search This Blog

Tuesday, October 26, 2010

CRM 4.0: Overriding lookup onclick

For one of my customer, I faced a difficulty. I wanted to override the lookup onclick event to provide my own lookup selection that uses a treeview (see below picture) which is much mor euser friendly when we talk about self related entities.

Lookup1

Lookup2

The problem : the behavior of the lookup is controled by a .htc file. It is a bad idea to change this kind of file (unsupported) and you can’t just remove the link to this file in the css class because you will loose all behaviors, not just onclick one.

The only way I found was to create a new lookup image with its own behavior, hide the original one, and add the new image next to the original one. All this using javascript. It is also unsupported but you are sure that your javascript won’t be override during rollup installation or other kind of CRM updates.

Here is the javascript:

   1: var lookupAttribute = "new_categoryid";
   2:  
   3: crmForm.performNewClick = function ()
   4: {
   5:     // Put here your alternative onclick code
   6: }
   7:  
   8: // Build lookup replacement image
   9: var replacementImage = "<img src='/_imgs/btn_off_lookup.gif'";
  10: replacementImage += "onclick='crmForm.performNewClick();'";
  11: replacementImage += "onmouseover='this.src=\"/_imgs/btn_on_lookup.gif\"'";
  12: replacementImage += "onmouseout='this.src=\"/_imgs/btn_off_lookup.gif\"'/>";
  13:  
  14: // Hide original lookup image
  15: window.document.getElementById(lookupAttribute).style.display= 'none';
  16:  
  17: // Add the replacement image on the lookup cell
  18: var lookupCell = window.document.getElementById(lookupAttribute).parentElement;
  19: lookupCellContent.innerHTML = lookupCellContent.innerHTML  + replacementImage;

Edit: the previous code seems to fail with a Javaµcript error. You can use the code below instead:

  1: // Entity to search
  2: var entityToSearch = "new_parameter";
  3: // Lookup attribute on form 
  4: var formLookupAttributeToFill = "new_parametreid";
  5: 
  6: document.CustomLookup = function ()
  7: {
  8: 	// Paste here your alternative onclick code	
  9: 
 10: 	crmForm.all[formLookupAttributeToFill].FireOnChange();
 11: }
 12: 
 13: crmForm.all[formLookupAttributeToFill].onclick = document.CustomLookup;

6 comments:

Anonymous said...

Work fine!!

Anonymous said...

2 questions:

1) When clicking on the textbox it shows an error on page.

2) How you make the treeview window?

Tanguy said...

Hi,

As you said, it seems that there is a JavaScript error that I didn't identified before...

Anyway, I found a much more easy way to override the lookup. See the edit on the post.

For the treeview window, it is all custom code. But it is static for the moment, I need to AJAX it to support entities with lot of records. As this treeview was part of a project, I can't deliver the source code, sorry about it.

Anonymous said...

Very nice :)
with crmForm.all.parameterName its even more typesafe.

Thx for the snippet.

markpittsnh said...

I want to cusotmize the call to lookupsingle.aspx by by overriding the onclick. This will entail defining my own url to lookupsingle.aspx and loading it via a modal window.

Before I start, I pasted your solution and simply added an alert where the above logic will eventually exist.

The issue I see is that, after the alert is executed, it calls the out-of-box lookup aspx. I suspect this is because the onclick relates to the HTML anchor, which, I believe is different the crmForm.all.field1.onclick.

Any suggestions on how to prevent the out-of-box from getting called?

Cheers!

markpittsnh said...

I figured it out.

crmForm.all.productid.onclick = function ()
{

var url = "/CRMDEV3/_controls/lookup/lookupsingle.aspx?class=ProductWithPriceLevel&objecttypes=1024&browse=0&ShowNewButton=1&ShowPropButton=1";

var lookupItem = window.showModalDialog(url, null,'dialogWidth:600px;dialogHeight:600px;resizable:yes');
var objs = lookupItem.items;
var iLength = objs.length;

if (iLength > 0)
{
var lookupData = new Array()
var lookupItem = new Object()
lookupData[0] = objs[0];

crmForm.all.productid.DataValue = lookupData;
}
}

Cheers!