web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Custom Filter in Dynam...
Power Apps
Answered

Custom Filter in Dynamics 365 Using JavaScript Shows All Records

(0) ShareShare
ReportReport
Posted on by 17

Hi everyone, I hope you’re doing well.

I’m facing an issue with a custom filter in Dynamics 365. It’s not the first time I’ve created a custom filter using JavaScript, but this time it’s not working as expected.

Initially, I used:
formContext.getControl('parentproductid').addCustomFilter(filter, "product");
and it didn’t work. After discussing with GPT, it advice me to use PreSearch.

the scenario:


  • When the user enters a Family ID, my code generates an XML filter to retrieve only the parent products.

  • The function pre_search_filter_parent is triggered on the OnChange event of the Family ID field.

The problem:

Even though the XML filter is created, the Parent (parentproductid) lookup always shows all records, not just the filtered ones.

 

i tried the filter in xrmtoolbox and it get the correct result :

 
function pre_search_filter_parent(executionContext){
var formContext = executionContext.getFormContext();
 var family_id= formContext.getAttribute('cr1da_familyid').getValue();
 if(family_id){
    var len_parent_family_id=family_id.length  - 2;
 console.log('the length  of the parent familly product is : '+len_parent_family_id);
Xrm.WebApi.retrieveMultipleRecords('product', "?$select=cr1da_familyid,name").then(
        function success(results) {
            var filter = '<filter type="and">';
            results.entities.forEach(result => {
                if(result["cr1da_familyid"].length ==len_parent_family_id){
                    filter+='<condition attribute="parentproductid" operator="eq" value="'+result["cr1da_familyid"]+'"/>';
                }
            });
            filter += '</filter>';
            console.log(filter);
            formContext.getControl('parentproductid').addPreSearch(filter,formContext);
        },
        function (error) {
            console.log(error.message);
            alert("there is an error in the research of the parent family query");
        });

    
 }
 else{
    console.log("we couldn't find attribute named 'cr1da_familyid'")
 }
}
function add_custom_filter(filter,formContext){

formContext.getControl('parentproductid').addCustomFilter(filter, "product");
}
 
 
I have the same question (0)
  • Suggested answer
    11manish Profile Picture
    3,333 on at
    Right now your code has three problems:
    • addPreSearch() is being used incorrectly
    • he filter XML is incorrect (parentproductid condition)
    • addPreSearch() expects a function, not a filter string
    Because of this, the lookup always returns all records.

    Main Problem in Your Code
    You currently do this:
    • formContext.getControl('parentproductid').addPreSearch(filter,formContext);
    But addPreSearch() expects:
    • addPreSearch(functionName)
    Then inside that function you call addCustomFilter().
     
    Try do the code like below :
     
    function onFamilyIdChange(executionContext) {
        var formContext = executionContext.getFormContext();
        // 1. Register the handler (only needs to be done once, usually OnLoad or OnChange)
        formContext.getControl("parentproductid").addPreSearch(applyProductFilter);
    }
    function applyProductFilter(executionContext) {
        var formContext = executionContext.getFormContext();
        var familyId = formContext.getAttribute("cr1da_familyid").getValue();
        if (familyId) {
            // Calculate your length logic
            var targetLength = familyId.length - 2;
            // Since we can't wait for WebAPI here without breaking the UI flow,
            // it is best to use a FetchXML filter that expresses your logic directly.
            // If the logic is too complex for FetchXML, you must pre-fetch the data 
            // into a variable/hidden field before the user clicks the lookup.

            
            var filter = "<filter type='and'>" +
                         "<condition attribute='cr1da_familyid_length' operator='eq' value='" + targetLength + "' />" +
                         "</filter>";
            formContext.getControl("parentproductid").addCustomFilter(filter, "product");
        }
    }
  • saifeddine Profile Picture
    17 on at
    hi @11manish , yes i forgot the name of the function in addpresearch 
    formContext.getControl('parentproductid').addPreSearch(add_custom_filter(filter,formContext));
    but the same problem maintain.
    my first code was 
    function pre_search_filter_parent(executionContext){
    var formContext = executionContext.getFormContext();
     var family_id= formContext.getAttribute('cr1da_familyid').getValue();
     if(family_id){
        var len_parent_family_id=family_id.length  - 2;
     console.log('the length  of the parent familly product is : '+len_parent_family_id);
    Xrm.WebApi.retrieveMultipleRecords('product', "?$select=cr1da_familyid,name").then(
            function success(results) {
                var filter = '<filter type="and">';
                results.entities.forEach(result => {
                    if(result["cr1da_familyid"].length ==len_parent_family_id){
                        filter+='<condition attribute="parentproductid" operator="eq" value="'+result["cr1da_familyid"]+'"/>';
                    }
                });
                filter += '</filter>';
                console.log(filter);
                
                formContext.getControl('parentproductid').addCustomFilter(filter, "product");
            },
            function (error) {
                console.log(error.message);
                alert("there is an error in the research of the parent family query");
            });
    
        
     }
     else{
        console.log("we couldn't find attribute named 'cr1da_familyid'")
     }
    }
    regarding these point :
     // Since we can't wait for WebAPI here without breaking the UI flow,
            // it is best to use a FetchXML filter that expresses your logic directly.

    Do you suggest creating a calculated column to calculate the length of the 'family ID' and then using the filter directly in FetchXML?


     
  • 11manish Profile Picture
    3,333 on at
    Yes — you are thinking in the right direction, and your current approach explains why the filter still doesn’t work reliably.
     
    The main problem is this:

    Your code calls Xrm.WebApi.retrieveMultipleRecords() and then applies addCustomFilter(). But lookup filtering in Microsoft Dynamics 365 must be applied before the lookup query runs. Because Web API is asynchronous, the lookup query often executes before your filter is ready, so the filter is ignored.
    That is why your lookup still shows all records.
  • Verified answer
    saifeddine Profile Picture
    17 on at
    Hi, the problem was related to how JavaScript handles functions. The issue was mainly due to two points:

    1. addCustomFilter must be executed inside the addPreSearch function.

    Previously, I used addCustomFilter directly inside the on-premise CRM . This used to work for me before, but it seems the behavior is different in the cloud version of Dynamics 365.

    2. Calling a function with parentheses executes it immediately.

    When we write something like test(), the JavaScript engine executes the function immediately instead of passing it as a reference. This caused the issue in my previous code.

    My previous code was:

    formContext.getControl('parentproductid').addPreSearch(add_custom_filter(filter, formContext));
     

    This executes add_custom_filter immediately instead of passing it to addPreSearch.

     

    Solution

    Use a function reference instead.

    Option 1

     
    formContext.getControl('parentproductid').addPreSearch(function ()  {
    // your code here
    });

    Option 2

    pre_search_handler = function () {
    console.log("filter inside the presearch " + filter);
    formContext.getControl('parentproductid').addCustomFilter(filter, 'product');
    };

    formContext.getControl('parentproductid').addPreSearch(pre_search_handler);
     

    I prefer the second approach because it allows me to reuse the same function reference and easily remove it later using removePreSearch().

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

Season of Sharing Community Challenge Launch!

Jump in, show your community spirit, and win prizes!

Kudos to our 2025 Community Spotlight Honorees

Expanding mentorship, skilling, and AI innovation

Congratulations to the May Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
Valantis Profile Picture

Valantis 424

#2
WarrenBelz Profile Picture

WarrenBelz 355 Most Valuable Professional

#3
11manish Profile Picture

11manish 290

Last 30 days Overall leaderboard