This article demonstrates how to dynamically retrieve the ID of a custom view based on its name and the target table (entity) in Dynamics 365. This technique is useful when you need to apply a custom view for lookups or other scenarios where a filtered set of records is required.
Overview
Dynamics 365 stores system views in the savedquery entity and personal views in the userquery entity. To dynamically retrieve a view's ID:
- Build a FetchXML Query: Retrieve records from savedquery (or fallback to userquery) filtering by the view's name.
- Filter by Table Name: Use the
returnedtypecode
attribute to ensure the view is associated with the desired entity. - Return the View ID: If a matching view is found, return its ID wrapped in curly braces.
This approach allows you to programmatically use custom views in your JavaScript code without hardcoding the view ID.
Code Example
Below is the JavaScript function getViewIdByName
, which retrieves the view ID based on the provided view name and table name:
/**
* Retrieves the view id for a given view name and table name from the savedquery or userquery entity using FetchXML.
*
* @param {string} viewName - The name of the view to retrieve (e.g., "Active Drivers").
* @param {string} tableName - The logical name of the entity for which the view is defined (e.g., "systemuser").
* @returns {Promise<string>} - A promise that resolves with the view id in curly braces.
*
* Usage: Call this function with the view name and table name.
*/
function getViewIdByName(viewName, tableName)
{
return new Promise(function(resolve, reject)
{
var fetchXml = [
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>",
" <entity name='savedquery'>",
" <attribute name='savedqueryid' />",
" <attribute name='returnedtypecode' />",
" <filter>",
" <condition attribute='name' operator='eq' value='" + viewName + "' />",
" </filter>",
" </entity>",
"</fetch>"
].join("");
Xrm.WebApi.retrieveMultipleRecords("savedquery", "?fetchXml=" + encodeURIComponent(fetchXml)).then(
function(result)
{
var records = result.entities || result.value;
if (records && records.length > 0)
{
var filtered = records.filter(function(item)
{
return item.returnedtypecode && item.returnedtypecode.toLowerCase() === tableName.toLowerCase();
});
if (filtered.length > 0)
{
var viewId = filtered[0].savedqueryid;
resolve("{" + viewId + "}");
return;
}
}
// Fallback: query personal views in the userquery entity.
var userQuery = [
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>",
" <entity name='userquery'>",
" <attribute name='userqueryid' />",
" <attribute name='returnedtypecode' />",
" <filter>",
" <condition attribute='name' operator='eq' value='" + viewName + "' />",
" </filter>",
" </entity>",
"</fetch>"
].join("");
Xrm.WebApi.retrieveMultipleRecords("userquery", "?fetchXml=" + encodeURIComponent(userQuery)).then(
function(result2)
{
var records2 = result2.entities || result2.value;
if (records2 && records2.length > 0)
{
var filtered2 = records2.filter(function(item)
{
return item.returnedtypecode && item.returnedtypecode.toLowerCase() === tableName.toLowerCase();
});
if (filtered2.length > 0)
{
var viewId = filtered2[0].userqueryid;
resolve("{" + viewId + "}");
return;
}
}
reject("View not found: " + viewName);
},
function(error2)
{
reject(error2.message);
}
);
},
function(error)
{
reject(error.message);
}
);
});
}
How It Works
FetchXML Query Construction:
The function constructs a FetchXML query to retrieve the savedqueryid
and returnedtypecode
for records in the savedquery entity where the view name matches the input.
Filtering by Table Name:
The results are filtered using the returnedtypecode
attribute to ensure that the view is defined for the specified table (e.g., "systemuser").
Fallback to Personal Views:
If no matching view is found in savedquery, the function builds a similar FetchXML query for the userquery entity to check for personal views.
Promise Resolution:
The function resolves with the view ID (wrapped in curly braces) if a matching view is found, otherwise, it rejects with an error message.
Conclusion
By using this generalized function, you can dynamically retrieve view IDs by specifying both the view name and the target table. This approach provides flexibility for various lookup and filtering scenarios in Dynamics 365, allowing you to adapt your customizations without hardcoding view IDs.
Feel free to integrate and adapt this code to suit your specific Dynamics 365 customization needs. Happy coding!
No comments:
Post a Comment