Wednesday, January 26, 2011

Create a custom filtered lookup view in runtime - CRM 2011

Starting CRM 2011 you can filter a certain lookup view based on related entities or other system/custom views. But sometimes this is not enough. For example, if you wanna make a custom filtered view, that uses several filters, you can use the following approach.

Starting scenario (all of the completed lookup fields will be used as filters):


// *** ALL IN 1 CODE ***
// Structs
var FilterBy = MakeStruct("SchemaName Operator Value");
var ViewColumn = MakeStruct("SchemaName Width");

// Advanced Filtered Lookup
function AdvancedFilteredLookup(lookupSchemaName, viewId, entityName, primaryKeyName, primaryFieldName, viewDisplayName, filterBy, orderBy, viewColumns)
{
var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
"<entity name='" + entityName + "'>" +
"<attribute name='" + primaryFieldName + "' />" +
"<order attribute='" + orderBy + "' descending='false' />" +
"<filter type='and'>" +
"<filter type='and'>";
for(var i=0; i< filterBy.length; i++)
fetchXml += "<condition attribute='" + filterBy[i].SchemaName + "' operator='" + filterBy[i].Operator + "' value='" + filterBy[i].Value + "' />";
fetchXml += "</filter></filter></entity></fetch>";

var layoutXml = "<grid name='resultset' " +
"object='1' " +
"jump='name' " +
"select='1' " +
"icon='1' " +
"preview='1'>" +
"<row name='result' " +
"id='" + primaryKeyName + "'>";
for(var i=0; i< viewColumns.length; i++)
layoutXml += "<cell name='" + viewColumns[i].SchemaName + "' width='" + viewColumns[i].Width.toString() + "' />";
layoutXml += "</row></grid>";

try {
var lookupControl = Xrm.Page.ui.controls.get(lookupSchemaName);
lookupControl.addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);
}
catch(err) {
}
}

// USE - we gonna create a custom filtered lookup view for the new_productid lookup field
// Note: this function should be called on the OnChange() event of all the filter-fields (for example: new_type1id)
function FilterProducts()
{
try {
// Parameters
var customViewId = "{FD140AAF-4DF4-11DD-BD17-0019B9312238}"; // new id
var customViewName = "Type Filtered Products";
var lookupFieldName = "new_productid";
var entityName = "product";
var primaryKeyName = "productid";
var primaryFieldName = "name";
var orderBy = "name";

// Generate Filters
var type1id = crmForm.all.item("nov_type1id").DataValue != null ? crmForm.all.item("nov_type1id").DataValue[0].id : null;
var type2id = crmForm.all.item("nov_type2id").DataValue != null ? crmForm.all.item("nov_type2id").DataValue[0].id : null;
var type3id = crmForm.all.item("nov_type3id").DataValue != null ? crmForm.all.item("nov_type3id").DataValue[0].id : null;
var type4id = crmForm.all.item("nov_type4id").DataValue != null ? crmForm.all.item("nov_type4id").DataValue[0].id : null;
var clientneedid = crmForm.all.item("nov_clientneedid").DataValue != null ? crmForm.all.item("nov_clientneedid").DataValue[0].id : null;
var vendorid = crmForm.all.item("nov_vendorid").DataValue != null ? crmForm.all.item("nov_vendorid").DataValue[0].id : null;
var filters = new Array();
var index = 0;
if(type1id != null)
filters[index++] = new FilterBy("new_type1id", LogicalOperator.Eq, type1id);
if(type2id != null)
filters[index++] = new FilterBy("new_type2id", LogicalOperator.Eq, type2id);
if(type3id != null)
filters[index++] = new FilterBy("new_type3id", LogicalOperator.Eq, type3id);
if(type4id != null)
filters[index++] = new FilterBy("new_type4id", LogicalOperator.Eq, type4id);
if(clientneedid != null)
filters[index++] = new FilterBy("new_clientneedid", LogicalOperator.Eq, clientneedid);
if(vendorid != null)
filters[index++] = new FilterBy("nov_vendorid", LogicalOperator.Eq, vendorid);

// View Columns
var viewColumns = [new ViewColumn("name", 200), new ViewColumn("productnumber", 100), new ViewColumn("new_type1id", 100), new ViewColumn("new_type2id", 100), new ViewColumn("new_type3id", 100), new ViewColumn("new_type4id", 100), new ViewColumn("new_clientneedid", 100), new ViewColumn("nov_vendorid", 100)];

// Create Dynamics View
AdvancedFilteredLookup(lookupFieldName, customViewId, entityName, primaryKeyName, primaryFieldName, customViewName, filters, orderBy, viewColumns);

// Clear Previous Product Value
crmForm.all.item(lookupFieldName).DataValue = null;
}
catch(err) {
}
}

And now, the custom filtered lookup view for the new_productid lookup field will look like this:


Hope you'll find this article useful.

P.S.: In my opinion, filtering a lookup this way is a lot more efficient than altering the lookupsingle.aspx file (the unsupported method used in CRM 4.0) ;)

1 comentarii:

Stormen said...

Would it be possible to post this a sollution that I could download? I have been trying to reproduce the code in my environment, but haven't gotten it to work.

I might be able to figure out where I go wrong if I had an environment that I could try it out in..

Would this be possible? Thank you:)