Clone invoices from the main grid/view

1. OPEN the command bar designer

To get to the command bar designer, open the model-drive app editor, click on the ellipsis next to the table you would be adding a button to, then select Edit command bar from the available options.

2. Insert a button into the command bar

Click + New located on the top left corner of the designer to pull down the available button options that can be inserted. Select Command. Drag the button to your preferred spot and on the right hand side of the screen, label it to its appropriate name. In this case, I’m naming it Copy. An icon for the button can be selected from the ‘Icon’ dropdown.

3. Edit the visibility rule of the button

If there is a need to control for when the button displays, then a visibility rule should be constructed. On the right hand side pane, select Show on condition from formula from the Visibility dropdown. Write the formula into the bar across the top. In mine, I want the button to display only when all the invoices selected have a status equal to Billed.

If(CountRows(Filter(Self.Selected.AllItems,’Status Reason'<>’Status Reason (Invoices)’.Billed))=0 && CountRows(Filter(Self.Selected.AllItems,’Status Reason’=’Status Reason (Invoices)’.Billed))>=1,true,false)
4. Set up the action the button does

In the Action dropdown, select Run JavaScript. I wrote a little function that will be triggered when the button is clicked on. In this case, I named the function CopyInvoiceConfirmation. I also chose the two parameters the values of which will be passed on to the function. This is MS’s documentation regarding those ribbon parameters. (I actually am not sure now why I added a second parameter. I think the first parameter called SelectedControlSelectedItemIds will do for what we want to achieve.)

This is the the CopyInvoiceConfirmation function. It will display the custom page with the name new_copyinvoice_e535d. Of course, you will need to replace this with the custom page you will have set up in step 5.

The recordId parameter will be the objects containing the selected invoices.

function CopyInvoiceConfirmation(data, grid) {
    var selectedRecordId = data;
    var gridcontext = grid;
        pageType: "custom",  
        name: "new_copyinvoice_e535d",
        recordId: selectedRecordId  
     }, {
     width: 700, 
     title: "Copy Invoice"}
    .then(function (){
5. Configure the custom page

The custom page will sort of be the pop-up that a user will interact with to confirm copying the invoice. Here it is in action when ran from the power apps studio:

5.1 OnStart formula

Set(selectedinvoice,Param(“recordId”));ClearCollect(colSplittedIds,Split(selectedinvoice,”,”));ClearCollect(invoiceids,Filter(Invoices,Invoice in colSplittedIds));Set(showspinner,false)

5.2 OK button’s OnSelect formula

This formula will show the spinner, run the Power Automate flow (see step 6 which describes most of its components) that actually copies the invoices, and when that process is done, it will cause the page to navigate to the second screen:

Set(showspinner, true);Set(completestatus,’Invoice-CopyInvoicefromGridView’.Run(JSON(colSplittedIds)).complete);If(completestatus=”true”,Navigate(Screen2,ScreenTransition.Fade));Set(showspinner, false)

5.3 Confirmation Screen (Screen1) controls

There’s a bunch of controls on this screen that are unnecessary and they were only here because I was trying to figure out how vertical and horizontal containers actually work in terms of making the screen responsive. The spinner image, OK and Cancel buttons, labels, and a rectangle overlay are the core ones.

5.4 Success Screen (Screen2) controls

A label saying the user can close off the screen is all we want here.

6. Configure the Power Automate flow

The flow should look like this:

  • The Compose action is triggerBody()[‘Compose_Inputs’]. The custom page will pass the collection of invoice GUIDS selected from the main grid.
  • The Parse JSON action will take the triggerBody()[‘Compose_Inputs’] as its input. The object schema is this:
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "Result": {
                "type": "string"
        "required": [
  • Within the Scope: Copy Invoice, an Apply to each will iterate over the body of the Parse JSON action. On the Get a row by ID action, the argument will be the Result property. I’ll leave the rest of the actions within this scope with you to as these are maybe self-explanatory.
  • The final step is to pass the string ‘true’ into a property I called ‘complete’. Note that in step 5.2 above, the value of this property is stored into the variable called ‘completestatus’ which is then evaluated to decide whether to navigate away from the current screen and on to the success screen.

Hope this helps!

Have a merry Christmas and a happy new year! 🎅


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: