Skip to main content

Notifications

Announcements

No record found.

Customer experience | Sales, Customer Insights,...
Answered

Update JS code from CRM2011 to CRM365

(1) ShareShare
ReportReport
Posted on by 10

Hello

I have a JS code that worked in crm2011.I updated for crm365. The code retrieve some record and match and show in a sub grid. All things works right expect of matching result to sub grid. Here is the code:

var updateFlag = false;

function updateSubGrid() {
if (updateFlag) return; // Prevent multiple executions
updateFlag = true;

alert("Starting updateSubGrid function");

// Get the related products grid details
var relatedProducts = Xrm.Page.getControl("ContactActivities");
if (!relatedProducts) {
alert("Control 'ContactActivities' not found.");
updateFlag = false; // Reset flag
return;
}
alert("Related Products control found");

// Initialize the lookup field
var lookupField = Xrm.Page.getAttribute("customerid").getValue();
if (!lookupField || lookupField.length === 0) {
alert("No customer selected.");
updateFlag = false; // Reset flag
return;
}
var lookupId = lookupField[0].id.replace("{", "").replace("}", ""); // Extract GUID
alert("Lookup ID: " + lookupId);

// Fetch XML query
var fetchXml = `
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='activitypointer'>
<attribute name='subject' />
<attribute name='description' />
<attribute name='createdon' />
<attribute name='statecode' />
<attribute name='ownerid' />
<attribute name='activitytypecode' />
<attribute name='regardingobjectid' />
<order attribute='createdon' descending='false' />
<link-entity name='activityparty' from='activityid' to='activityid' alias='aa'>
<filter type='and'>

<condition attribute='partyid' operator='eq'
uiname='Contact Name' uitype='contact' value='${lookupId}' />
</filter>
</link-entity>
</entity>
</fetch>`;

alert("Fetch XML: " + fetchXml);

// Fetch data using Xrm.WebApi
Xrm.WebApi.retrieveMultipleRecords("activitypointer", "?fetchXml=" + encodeURIComponent(fetchXml)).then(
function success(result) {
var items = result.entities;
if (items.length > 0) {
alert("Data retrieved successfully. Count: " + items.length);

items.forEach(function(item) {
console.log("Activity Subject: " + item.subject);
});

// Ensure the grid is ready before attempting to bind data
ensureGridReady(relatedProducts, items);
} else {
alert("No data found.");
updateFlag = false; // Reset flag
}
},
function error(error) {
console.error("Error in fetch request: ", error.message);
alert("Error in fetch request: " + error.message);
updateFlag = false; // Reset flag
}
);
}

function ensureGridReady(relatedProducts, items) {
var retryCount = 0;
var maxRetries = 10; // Increase the retry limit to ensure the grid is ready

function checkGrid() {
if (retryCount >= maxRetries) {
alert("Max retries reached. The grid might not be ready or there is another issue.");
updateFlag = false; // Reset flag
return;
}

try {
var gridControl = relatedProducts.getGrid();
if (gridControl) {
alert("Grid control is ready");

// Bind data to the grid
bindDataToGrid(relatedProducts, items);
alert("Data bound successfully. Attempting to refresh the grid.");
relatedProducts.refresh();

// Verify if records are set in the grid
setTimeout(function() {
var gridControl = relatedProducts.getGrid();
var gridRows = gridControl.getRows();
if (gridRows.getLength() > 0) {
alert("Related Products grid updated with new records");
} else {
alert("No records found in the Related Products grid");
}
updateFlag = false; // Reset flag
}, 2000); // Wait for 2 seconds before checking
} else {
retryCount++;
console.log("Grid control not ready, retrying... (" + retryCount + ")");
setTimeout(checkGrid, 1000); // Retry after 1 second
}
} catch (e) {
console.error("Error checking grid: ", e);
alert("Error checking grid: " + e.message);
updateFlag = false; // Reset flag
}
}

checkGrid();
}

function bindDataToGrid(relatedProducts, items) {
try {
// Implement a function to bind the data to the subgrid
alert("Binding data to subgrid. Item count: " + items.length);

// In this context, we assume data binding means just refreshing the grid
relatedProducts.refresh();
} catch (e) {
console.error("Error binding data to grid: ", e);
alert("Error binding data to grid: " + e.message);
updateFlag = false; // Reset flag
}
}

  • CU28110705-0 Profile Picture
    CU28110705-0 10 on at
    Update JS code from CRM2011 to CRM365
     
    Thanks
  • Verified answer
    Amit Katariya007 Profile Picture
    Amit Katariya007 8,699 Super User 2024 Season 1 on at
    Update JS code from CRM2011 to CRM365
    You can define in in the fetchXML variable and then pass it as a parameter. Refer the article which I have shared with you.
    Here I haved used simple example where I have added a single condition. You can add attributes also which you want to get from CRM.
     
    const fetchXml = `
            <fetch>
                <entity name="activitypointer">
                    <filter type="and">
                        <condition attribute="partyid" operator="eq" value="${lookupId}" />
                    </filter>
                </entity>
            </fetch>`;
  • CU28110705-0 Profile Picture
    CU28110705-0 10 on at
    Update JS code from CRM2011 to CRM365
    How can I "Update Subgrid View Filter" ?
  • CU28110705-0 Profile Picture
    CU28110705-0 10 on at
    Update JS code from CRM2011 to CRM365
    How can I "Update Subgrid View Filter" ?
  • Suggested answer
    Amit Katariya007 Profile Picture
    Amit Katariya007 8,699 Super User 2024 Season 1 on at
    Update JS code from CRM2011 to CRM365
    The issue you're experiencing likely stems from the fact that in Dynamics 365 (CRM Online), JavaScript client-side APIs have evolved significantly since CRM 2011, and there are now stricter guidelines for interacting with grids and records programmatically. Specifically, you cannot programmatically bind custom data directly to subgrids using standard Dynamics 365 client APIs. Subgrids in Dynamics 365 are tied to specific relationships or FetchXML queries defined in the entity form.
     
    Key Considerations:
     
    1. Subgrid Data Source:
     
    Subgrids are tied to a specific relationship or FetchXML query set in the form editor. You cannot programmatically inject records into the subgrid directly.
    To display filtered or matched data, you must update the subgrid's underlying query or use an alternative approach.
     
    2. Modern API Changes:
     
    The Xrm.WebApi.retrieveMultipleRecords API retrieves data but does not directly integrate with subgrids. The subgrid itself must be configured to fetch the appropriate data.
     
    3. Recommended Solution:
     
    If the data you want to display is not appearing in the subgrid, verify and update the subgrid's FetchXML definition or filtering logic.
     
    Updated Approach for Dynamics 365
     
    1. Update Subgrid View Filter:
     
    Instead of trying to programmatically bind data, dynamically update the subgrid's view or filter conditions.
     
     
    function updateSubGridView() {
        const relatedProducts = Xrm.Page.getControl("ContactActivities");
        if (!relatedProducts) {
            alert("Control 'ContactActivities' not found.");
            return;
        }
     
        const lookupField = Xrm.Page.getAttribute("customerid").getValue();
        if (!lookupField || lookupField.length === 0) {
            alert("No customer selected.");
            return;
        }
        const lookupId = lookupField[0].id.replace("{", "").replace("}", "");
     
        // Use setFilterXml to apply a filter dynamically
        const filterXml = `
            <filter type="and">
                <condition attribute="partyid" operator="eq" value="${lookupId}" />
            </filter>`;
        relatedProducts.addCustomFilter(filterXml, "activitypointer");
        relatedProducts.refresh(); // Refresh the grid to apply the filter
    }
     
     
    2. Use Custom FetchXML (Optional):
     
    If the subgrid is tied to a specific entity and relationship, you can define a FetchXML query to filter the data.
     
    Update the subgrid's associated view using the addCustomView API if you want to dynamically change its contents.
     
     
    function updateSubGridCustomView() {
        const relatedProducts = Xrm.Page.getControl("ContactActivities");
        if (!relatedProducts) {
            alert("Control 'ContactActivities' not found.");
            return;
        }
     
        const lookupField = Xrm.Page.getAttribute("customerid").getValue();
        if (!lookupField || lookupField.length === 0) {
            alert("No customer selected.");
            return;
        }
        const lookupId = lookupField[0].id.replace("{", "").replace("}", "");
     
        const fetchXml = `
            <fetch>
                <entity name="activitypointer">
                    <filter type="and">
                        <condition attribute="partyid" operator="eq" value="${lookupId}" />
                    </filter>
                </entity>
            </fetch>`;
     
        relatedProducts.addCustomView(
            "customViewId", // Unique ID for the custom view
            "activitypointer", // Entity logical name
            "Filtered Activities", // View display name
            fetchXml,
            [] // List of columns to display
        );
        relatedProducts.refresh(); // Refresh the grid to apply the custom view
    }
     
     
    3. Use a PCF Control (PowerApps Component Framework):
     
    If the built-in subgrid is insufficient for your needs, consider developing a custom PCF control for the subgrid to display and manage data exactly how you want.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Verified Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,391 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,445 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans