31 Aralık 2010 Cuma

CRM Filtered Lookup Multi

I had some posts last year about the CRM Filtered Lookup, these technique are broadly used in the CRM community.

The mysterious CRM Lookup (I)
The mysterious CRM Lookup (II)
The mysterious CRM Lookup (III)

A few days ago, I saw a post on the Microsoft Dynamics CRM Chinese Forum about how to add filter to LookupMulti.aspx ?
I think it's a very common requirements, so I'd like to give my idea.
When I start with this customization, my bottom line was: Not change any files/databases. However this customization should be marked as a "unsupported customization" (call CRM/JS function directly).


OK, the question was:
A customized entity: ShippingMark (new_shippingmark), it has N:1 relationship with Account; it also has N:N relationship with Quote.
And as we known by default, Quote has N:1 relationship with Account(via customerid)

So the relationship is simple: Account -< (customerid)Quote >< ShippingMark(new_accountid) >- Account

What the user wants was classic: Open a Quote record, then go to Add Existing ShippingMark, then in the LookupMulti page, only return the ShippingMark which has the same Account(new_account) with Quote's(customerid).

There are two parts of the code: server side Plugin.Execute event and client side CRM.Onload event. What the client side code does is: create a custom lookup window, and pass the customerid as a parameter, so the lookup URL looks like: ?&id=?, then the server side plugin will replace the FilterXml query string based on the parameter.

I give the code prototype for this specific requirement, you need to modify it for re-use. This technique should work for both LookupSingle.aspx and LookupMulti.aspx.


1. Plug-Ins
Register the Execute message on the Pre Stage/Synchronous/Server/Parent Pipeline.



/*
* Microsoft Dynamics CRM Lookup Filter
* Plug-Ins: Execute message on the Pre Stage/Synchronous/Server/Parent Pipeline.
* Jim Wang @ Aug 2009, http://jianwang.blogspot.com, http://mscrm.cn
*
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using Microsoft.Crm.Sdk;

namespace CRMExecuteEvent
{
public class CRMExecuteEvent : IPlugin
{
string lookupId;

public void Execute(IPluginExecutionContext context)
{

lookupId = HttpContext.Current.Request.QueryString["id"] == null ? null : HttpContext.Current.Request.QueryString["id"].ToString();

if (lookupId == null) return;

try
{
if (context.InputParameters.Contains("FetchXml"))
{
string beforeXml = (String)context.InputParameters["FetchXml"];

if (beforeXml.Contains("<entity name=\"new_shippingmark\">") && beforeXml.Contains("xml-platform"))
{
//Customise the FetchXml query string
string afterXml =
"<fetch version='1.0' page='1' count='100' output-format='xml-platform' mapping='logical'> " +
"<entity name='new_shippingmark'> " +
"<attribute name='new_shippingmarkid' /> " +
"<attribute name='new_name' /> " +
"<attribute name='createdon' /> " +
"<order attribute='new_name' /> " +
"<link-entity name='quote' to='new_accountid' from='customerid'> " +
"<filter type='and'> " +
"<condition attribute = 'customerid' operator='eq' value='" + lookupId + "'/> " +
"</filter> " +
"</link-entity> " +
"<filter type='and'> " +
"<condition attribute='statecode' operator='eq' value='0' /> " +
"<condition attribute='new_name' operator='like' value='%' /> " +
"</filter> " +
"</entity> " +
"</fetch>";

//Replace the FetchXml query string
context.InputParameters["FetchXml"] = beforeXml.Replace(beforeXml, afterXml);

}
}
}

catch (System.Web.Services.Protocols.SoapException ex)
{
throw new InvalidPluginExecutionException("An error occurred in the CRM plug-in.", ex);
}
}

}
}




2. Quote.OnLoad()


var relId = "new_new_shippingmark_quote";
var lookupId = crmForm.all.customerid;

var lookupEntityTypeCode;
var navId = document.getElementById("nav" + relId);
if (navId != null)
{
var la = navId.onclick.toString();
la = la.substring(la.indexOf("loadArea"), la.indexOf(";"));

navId.onclick = function()
{
eval(la);

var areaId = document.getElementById("area" + relId + "Frame");
if(areaId != null)
{
areaId.onreadystatechange = function()
{
if (areaId.readyState == "complete")
{
var frame = frames[window.event.srcElement.id];
var li = frame.document.getElementsByTagName("li");

for (var i = 0; i < li.length; i++)
{
var action = li[i].getAttribute("action");
if(action != null && action.indexOf(relId) > 1)
{
lookupEntityTypeCode = action.substring(action.indexOf("\(")+1, action.indexOf(","));
li[i].onclick = CustomLookup;
break;
}
}
}
}
}
}
}

function CustomLookup()
{
var lookupSrc = "/" + ORG_UNIQUE_NAME + "/_controls/lookup/lookupmulti.aspx?class=&objecttypes=" + lookupEntityTypeCode + "&browse=0";
if(lookupId != null && lookupId.DataValue != null && lookupId.DataValue[0] != null)
{
lookupSrc = lookupSrc + "&id=" + lookupId.DataValue[0].id;
}

var lookupItems = window.showModalDialog(lookupSrc, null);
if (lookupItems) // This is the CRM internal JS funciton on \_static\_grid\action.js
{
if ( lookupItems.items.length > 0 )
{
AssociateObjects( crmFormSubmit.crmFormSubmitObjectType.value, crmFormSubmit.crmFormSubmitId.value, lookupEntityTypeCode, lookupItems, true, null, relId);
}
}
}



microsoft crm online |business contact manager |open source crm |cheap crm |crm magic quadrant |

Hiç yorum yok:

Yorum Gönder