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 / Model driven app - com...
Power Apps
Unanswered

Model driven app - command bar custom button

(0) ShareShare
ReportReport
Posted on by 68

I have the need to show/hide a sub-grid on a form.  Initially the subgrid would be hidden.  If the user needs to add records to the sub-grid they would click the button to display the sub-grid.  If they add records (one or more records have been saved) to the sub-grid then the Add button would be hidden and a delete button would be displayed.  Any time the user opens a record that has one or more records in the sub-grid the sub-grid should displayed along with the delete button.  If the user clicks delete they are warned that all rows will be deleted.  If they proceed, all rows are deleted, the delete button is hidden and the add button is displayed.

 

Is this something I can do with PowerFX functions?

 

What I've tried

I haven't gotten very far.  I've been trying to get the Add button to display or not display based on the count of rows in the sub-grid but haven't even gotten that far.  My plan was to use a syntax something like;

If(countif(<SubgridTableName>, <SubgridLookupColumnName> = <MainFormRecordName>)=0,true,false)

I can't seem to reference the <SubgridTableName>.

I'm certain I'm doing something wrong or perhaps this is something that I can't do with PowerFX.

 

Thanks in advance for any assistance you can provide.

Categories:
I have the same question (0)
  • Giraldoj Profile Picture
    872 Moderator on at

    Hi @MJL1 

     

    My understanding is that you want to show or hide the Delete button in the subgrid. If that's correct, then you're right that it's not possible to achieve this with Power FX. The default Delete button's show/hide properties cannot be modified without using an external tool.

    Even if you decide to build your own Delete button, it won't meet your requirements. If the command is configured in the main form, you won't be able to access the subgrid data. Conversely, if the command is configured in the subgrid table, you won't be able to access the main form data.

    However you can actually achieve pretty much all you mentioned with a combination of command buttons and JS.

    Lets start by creating the a JS file with the following code

     

    // Function to Show/Hide Subgrid Based on Record Count (Form OnLoad Event)
    function checkSubgridOnLoad(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     subgridControl.addOnLoad(function () {
     var rows = subgridControl.getGrid().getRows();
     if (rows.getLength() === 0) {
     subgridControl.setVisible(false);
     } else {
     subgridControl.setVisible(true);
     }
     });
    }
    
    // Function to Toggle Subgrid Visibility (Manual Button)
    function toggleSubgridVisibility(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     var currentVisibility = subgridControl.getVisible();
     subgridControl.setVisible(!currentVisibility);
    }
    
    // Function to Delete All Records from Subgrid with Confirmation
    function deleteSubgridRecords(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     if (confirm("Are you sure you want to delete all records?")) {
     var rows = subgridControl.getGrid().getRows();
     var deletePromises = [];
    
     rows.forEach(function (row) {
     var entityReference = row.getData().getEntity().getEntityReference();
     var deletePromise = Xrm.WebApi.deleteRecord(entityReference.entityType, entityReference.id);
     deletePromises.push(deletePromise);
     });
    
     Promise.all(deletePromises).then(
     function success(results) {
     console.log("All records deleted");
     subgridControl.refresh(); // Refresh subgrid to reflect changes
     subgridControl.setVisible(false); // Hide subgrid after deleting records
     },
     function error(error) {
     console.log("Error deleting records: " + error.message);
     }
     );
     }
    }
    
    // Ensure Subgrid is Visible When Manually Toggled Even if Initially Empty
    function ensureSubgridVisibility(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("Subgrid_new_1");
     subgridControl.setVisible(true);
    }

    Remember to change Subgrid_new_1 to the name of your subgrid before uploading your code.

    in this link you can find all the information about how to create your file with the JS conde and configure it in the onload event of your main form.
    https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/clientapi/walkthrough-write-your-first-client-script

    you should configure the function checkSubgridOnLoad in your OnLoad Event.

    Giraldoj_0-1719717768341.png


    that is going to automatically show/hide the subgrid based on the number of items.

    now the custom button, please edit your main form table command bar, select main Form and add a new command

    Giraldoj_1-1719717768342.png


    name It as you want and in action select Run JavaScript, load the same library we create for the onload event, put the function toggleSubgridVisibility and add a new parameter then select PrimaryControl

    Giraldoj_2-1719717768343.png

     



    Now for you delete button, please go and create a new Command this time in the Subgrids Table, and remember to select the Subgrid command bar.

    Giraldoj_3-1719717768343.png

     

     

    put the function deleteSubgridRecords  and add a new parameter then select PrimaryControl

    Giraldoj_4-1719717768344.png

     

     

    And that’s it, I Hope evething is clear enough so you can follow the steps and achieve your requirement.

     

    Feel free to ask any questions.

    If my response resolved your issue, please feel free to mark it as the solution by clicking "Accept as solution." This helps others find the answer more easily. If you found the content helpful in any other way, a "Thumbs Up" would be greatly appreciated. Thank you!

  • MJL1 Profile Picture
    68 on at

    @Giraldoj.  Thank you so much for your very comprehensive response!  It confirms what I had suspected/feared - that I can't achieve the behavior I want with PowerFX commands (which is unfortunate for me since I know nothing useful about scripting with JavaScript).

     

    Your instructions were clear and easy to follow.  Thank you for that.

     

    However, there is a problem.  It seems as though the checkSubgridOnLoad that is on the form load event get's re-triggered when the subgrid is displayed when the command button is clicked.  I was able to see the subgrid being briefly displayed and then hidden again.  When I disabled the form load function the command button behaved as desired.

     

    Since I don't know how to write JavaScript I don't know how to do this but my thought is that if the command button could additionally set a variable that indicates that the command button was clicked (and that the subgrid should be displayed even though it has zero rows) this variable could be tested by the checkSubgridOnLoad function.  How would I code that?

     

    I have not yet tried the deleteSubgridRecords function yet.

  • Giraldoj Profile Picture
    872 Moderator on at

    HI @MJL1 

     

    I have made some changes to the code, to fix that issue, now you should be able to show/hide the subgrid on demand clicking on the command

    var manualToggle = false;
    
    // Function to Show/Hide Subgrid Based on Record Count (Form OnLoad Event)
    function checkSubgridOnLoad(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     subgridControl.addOnLoad(function () {
     if (!manualToggle) {
     var rows = subgridControl.getGrid().getRows();
     if (rows.getLength() === 0) {
     subgridControl.setVisible(false);
     } else {
     subgridControl.setVisible(true);
     }
     }
     });
    }
    
    // Function to Toggle Subgrid Visibility (Manual Button)
    function toggleSubgridVisibility(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     var currentVisibility = subgridControl.getVisible();
     manualToggle = true;
     subgridControl.setVisible(!currentVisibility);
    }
    
    // Function to Delete All Records from Subgrid with Confirmation
    function deleteSubgridRecords(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("Subgrid_new_1");
    
     if (confirm("Are you sure you want to delete all records?")) {
     var rows = subgridControl.getGrid().getRows();
     var deletePromises = [];
    
     rows.forEach(function (row) {
     var entityReference = row.getData().getEntity().getEntityReference();
     var deletePromise = Xrm.WebApi.deleteRecord(entityReference.entityType, entityReference.id);
     deletePromises.push(deletePromise);
     });
    
     Promise.all(deletePromises).then(
     function success(results) {
     console.log("All records deleted");
     subgridControl.refresh(); // Refresh subgrid to reflect changes
     subgridControl.setVisible(false); // Hide subgrid after deleting records
     },
     function error(error) {
     console.log("Error deleting records: " + error.message);
     }
     );
     }
    }
    
    // Ensure Subgrid is Visible When Manually Toggled Even if Initially Empty
    function ensureSubgridVisibility(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("Subgrid_new_1");
     subgridControl.setVisible(true);
    }

     

     If my response resolved your issue, please feel free to mark it as the solution by clicking "Accept as solution." This helps others find the answer more easily. If you found the content helpful in any other way, a "Thumbs Up" would be greatly appreciated. Thank you!

  • MJL1 Profile Picture
    68 on at

    @Giraldoj 

     

    First, I apologize for not responding earlier.  I've been side tracked by a week off work only to return to a number of higher priority tasks that required my attention.

     

    Your assistance has been very valuable and spot on with regard to meeting my needs.  However, as I've evolved my project some new requirements have arisen.   

     

    The requirements of my my app are that the main from enables a data entry of information about an "Event Type".  Some "Event Types" (the ones that require the display of the subgrid) have "Event Sub-types".  In these cases some of the attributes captured at the "Event Type" level should be cleared and hidden on the main form and will be captured on the "Event Sub-type" form, instead.

     

    I've modified the code example you provided such that the OnLoad function works as desired (hiding fields on the form as well as displaying the subgrid).  I've tried to modify the toggleSubgridVisibility function to have comparable fuctionality but am struggling to get that working correctly.  What I've realized is that I don't understand the nature of the information being passed in the primaryControl parameter to the toggleSubgridVisibility function.  Below is my code.  You'll see that I've created functions to show and to hide the fields and the subgrid.  I was hoping to use those functions in the toggleSubgridVisibility function but they're not behaving as I desire (likely because the toggleSubgridVisibility is passing primaryControl to the function instead of 

    executionContext).

    Hopefully you can see what I'm trying to do and are able to advise how to achieve the desired functionality of hiding the fields and displaying the subgrid when the command button is clicked.  This command button should only be visible if the Event Type form - the main form of my app, does not have any Event Sub-types (records in the subgrid).  Once the command button has been clicked, ideally, the command button should be hidden (if the user chooses not to enter Event Sub-types and wants to hide the subgrid and re-display the hidden fields they will click the refresh command button).

     

     

     

    var manualToggle = false;
    
    function showEventSubtypes(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("EventSubTypes");
     var accountablebusinessunit = formContext.getControl("bipr_accountablebusinessunit");
     var manualacimplementationstatus = formContext.getControl("bipr_manualacimplementationstatus");
     var structuredreviewimplementationstatus = formContext.getControl("bipr_structuredreviewimplementationstatus");
     var onestopimplementationstatus = formContext.getControl("bipr_onestopimplementationstatus")
     var rvpimplementationstatus = formContext.getControl("bipr_rvpimplementationstatus");
     var daterangeofaverages = formContext.getControl("bipr_daterangeofaverages");
     var averageannualvolume = formContext.getControl("bipr_averageannualvolume");
     var averageprocessduration = formContext.getControl("bipr_averageprocessduration");
     var processdurationtarget = formContext.getControl("bipr_processdurationtarget");
    
     subgridControl.setVisible(true);
     accountablebusinessunit.setVisible(false);
     manualacimplementationstatus.setVisible(false);
     structuredreviewimplementationstatus.setVisible(false);
     onestopimplementationstatus.setVisible(false)
     rvpimplementationstatus.setVisible(false);
     daterangeofaverages.setVisible(false);
     averageannualvolume.setVisible(false);
     averageprocessduration.setVisible(false);
     processdurationtarget.setVisible(false);
    
    }
    
    function hideEventSubtypes(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("EventSubTypes");
     var accountablebusinessunit = formContext.getControl("bipr_accountablebusinessunit");
     var manualacimplementationstatus = formContext.getControl("bipr_manualacimplementationstatus");
     var structuredreviewimplementationstatus = formContext.getControl("bipr_structuredreviewimplementationstatus");
     var onestopimplementationstatus = formContext.getControl("bipr_onestopimplementationstatus")
     var rvpimplementationstatus = formContext.getControl("bipr_rvpimplementationstatus");
     var daterangeofaverages = formContext.getControl("bipr_daterangeofaverages");
     var averageannualvolume = formContext.getControl("bipr_averageannualvolume");
     var averageprocessduration = formContext.getControl("bipr_averageprocessduration");
     var processdurationtarget = formContext.getControl("bipr_processdurationtarget");
    
     subgridControl.setVisible(false);
     accountablebusinessunit.setVisible(true);
     manualacimplementationstatus.setVisible(true);
     structuredreviewimplementationstatus.setVisible(true);
     onestopimplementationstatus.setVisible(true)
     rvpimplementationstatus.setVisible(true);
     daterangeofaverages.setVisible(true);
     averageannualvolume.setVisible(true);
     averageprocessduration.setVisible(true);
     processdurationtarget.setVisible(true);
    
    }
    
    // Function to Show/Hide Subgrid Based on Record Count (Form OnLoad Event)
    function checkSubgridOnLoad(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("EventSubTypes");
    
     subgridControl.addOnLoad(function () {
     if (!manualToggle) {
     var rows = subgridControl.getGrid().getRows();
     if (rows.getLength() === 0) {
    // subgridControl.setVisible(false);
     hideEventSubtypes(executionContext)
     } else {
    // subgridControl.setVisible(true);
     showEventSubtypes(executionContext)
     }
     }
     });
    }
    
    // Function to Toggle Subgrid Visibility (Manual Button)
    function toggleSubgridVisibility(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("EventSubTypes");
    
    // var currentVisibility = subgridControl.getVisible();
     manualToggle = true;
     showEventSubtypes(formContext)
    // subgridControl.setVisible(!currentVisibility);
    }
    
    // Function to Delete All Records from Subgrid with Confirmation
    function deleteSubgridRecords(primaryControl) {
     var formContext = primaryControl;
     var subgridControl = formContext.getControl("EventSubTypes");
    
     if (confirm("Are you sure you want to delete all records?")) {
     var rows = subgridControl.getGrid().getRows();
     var deletePromises = [];
    
     rows.forEach(function (row) {
     var entityReference = row.getData().getEntity().getEntityReference();
     var deletePromise = Xrm.WebApi.deleteRecord(entityReference.entityType, entityReference.id);
     deletePromises.push(deletePromise);
     });
    
     Promise.all(deletePromises).then(
     function success(results) {
     console.log("All records deleted");
     subgridControl.refresh(); // Refresh subgrid to reflect changes
     subgridControl.setVisible(false); // Hide subgrid after deleting records
     },
     function error(error) {
     console.log("Error deleting records: " + error.message);
     }
     );
     }
    }
    
    // Ensure Subgrid is Visible When Manually Toggled Even if Initially Empty
    function ensureSubgridVisibility(executionContext) {
     var formContext = executionContext.getFormContext();
     var subgridControl = formContext.getControl("EventSubTypes");
     subgridControl.setVisible(true);
    }

     

     

     

    I hope this hasn't become too much of a bother for you and I thank you, in advance, for any assistance you can provide.

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

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Users!

Kudos to our 2025 Community Spotlight Honorees

Congratulations to our 2025 community superstars!

Congratulations to the March Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
11manish Profile Picture

11manish 536

#2
WarrenBelz Profile Picture

WarrenBelz 426 Most Valuable Professional

#3
Haque Profile Picture

Haque 305

Last 30 days Overall leaderboard