Power Apps Product Edit Screen
Build a SharePoint-connected product editing Canvas App with image upload.
Introduction
30 Second Summary
When a product team manages details across PowerPoint (for visual context) and Excel (for data), they end up typing the same information twice. Mistakes creep in, versions drift apart, and nobody trusts the "master" spreadsheet.
In this project, you will build a Power Apps Canvas App that displays product images alongside editable data fields in a single interface. The app saves directly to SharePoint, eliminating double-entry between presentation decks and spreadsheets.
What You'll Build
A visual product editing screen in a Canvas App connected to a SharePoint data layer, with image upload handled by a Power Automate flow.
By the end of this project, you'll have:
- A SharePoint List and Document Library storing all product finalisation data and images, with metadata linking each file back to its product record.
- A Canvas App editing screen with a large product image on the left and grouped field sections on the right, connected to both SharePoint data sources.
- A Power Automate flow that uploads images from the app to the Document Library and returns the file URL to the product record, plus draft save functionality using the Patch function.
- Secret Mission: Add field validation rules and an unsaved-changes indicator that warns users before navigating away from an edited product.
Are there any prerequisites?
This project assumes you have an existing Microsoft 365 license with Power Apps and SharePoint Online access. You should also be familiar with basic Canvas App development (creating screens, adding controls, and navigating Power Apps Studio).
Create the SharePoint Data Layer
Every app needs a place to store its data. For this product finalisation tool, the data layer lives in SharePoint because it integrates directly with Power Apps and gives the team a familiar place to manage records.
You will create two SharePoint resources: a List that holds all product fields (40+ columns across five groups), and a Document Library that stores product images separately. Splitting images into their own library gives you full control over file management and URL-based display inside the app.
In this step, get ready to:
- Create the Products SharePoint List with columns for all five field groups.
- Create the ProductImages Document Library with metadata columns.
- Verify the setup with a test product record and a test image upload.
Create the Products SharePoint List
The Products list stores every piece of product data the finalisation team needs. You will organise 40+ columns into five logical groups so they map cleanly to sections in the app later.
- Navigate to your SharePoint site home page.
- Select + New in the command bar, then select List.
- In the dialog, select Blank list.
- Enter Products as the list name.
- Click Create.
You now have an empty list with just the default Title column. Next, you will add columns group by group.
How to add a column
To add each column: click + Add column at the right of the column header row, choose the column type from the dropdown, enter the column name in the Name field, and click Save. Repeat for every column listed below.
For Choice columns, you will also need to type the choice values into the Choices field (one per line) before saving.
Add the following columns for the General Info group:
- STAGE (Choice). Enter choice values such as: Concept, Sample, Pre-Production, Production, Launched.
- WEEK (Single line of text).
- FLOW (Single line of text).
- Item Status (Choice). Enter choice values such as: New, In Progress, On Hold, Completed, Cancelled.
- BUYER (Single line of text).
- PRODUCT GROUP (Single line of text).
- Item Category (Single line of text).
- Article Number (Single line of text).
- Vendor Name (Single line of text).
- PRODUCT DESCRIPTION (Single line of text).
Add the following columns for the Logistics group:
- MOQ in CE (Number).
- Min BBD days (Number).
- Leadtime WEEKS (Number).
- SAMPLE (Choice). Enter choice values such as: Requested, Received, Approved, Rejected.
- WHY (Single line of text).
- CU/Case (Number).
- Cases/Pallet (Number).
- CU/Pallet (Number).
- Languages (Single line of text).
- Comments Logistics (Multiple lines of text).
Add the following columns for the Benchmark group:
- Benchmark Product Description 1 (Single line of text).
- Benchmark Retailer 1 (Single line of text).
- Benchmark RSP 1 (Number).
- Benchmark Product Description 2 (Single line of text).
- Benchmark Retailer 2 (Single line of text).
- Benchmark RSP 2 (Number).
Add the following columns for the Pricing and Margins group:
- RSP (Number).
- BTW NL (Number).
- RSP ex BTW (Number).
- Delta vs Benchmark (Number).
- MSP ex works (Number).
- MSP Incl Avg Works (Number).
- Retailer Margin (Number).
- CPB (Number).
- CPS (Number).
- CPW (Number).
- BM Sales Margin Incl Average Works (Number).
- Min BM Sales Margin (Number).
- Target Sales Margin (Number).
Add the following columns for the Market and Compliance group:
- ACTION (Single line of text).
- BNL (Single line of text).
- DACH (Single line of text).
- FRANCE (Single line of text).
- EMMA (Single line of text).
- UK (Single line of text).
- TRADE (Single line of text).
- ESG Compliant (Yes/No).
- QA Compliant (Yes/No).
Finally, add three columns to store image URLs that will link products to their uploaded images:
- MainImageURL (Single line of text).
- BenchmarkImage1URL (Single line of text).
- BenchmarkImage2URL (Single line of text).
Why store image URLs as text columns?
SharePoint's built-in Image column type has rendering quirks and a 30-second refresh delay. Storing the URL as plain text gives Power Apps full control over when and how the image displays. A Power Automate flow will populate these URLs automatically when images are uploaded later.
What about column names with spaces?
SharePoint encodes column names with spaces as _x0020_ in Power Apps formulas. For example, Item Status becomes Item_x0020_Status internally. You will reference these with single quotes in Power Fx (e.g., 'Item Status') in later steps.
Speed up column creation with grid view
After adding a few columns, switch to Edit in grid view from the command bar. This lets you see all columns at once and verify nothing was missed. You can also use + Add column directly from the grid header.
Column type not available in the dropdown?
If you do not see the column type you need (like Yes/No), scroll to the bottom of the column type dropdown and select More. This reveals additional column types including Yes/No and Multiple lines of text.
Still stuck? Help me find the right column type in SharePoint.
Create the ProductImages Document Library
Product images need their own storage location. A Document Library is the right choice because it supports file uploads and custom metadata columns that link each image back to its product record.
- Return to your SharePoint site home page.
- Select + New in the command bar, then select Document library.
- Enter ProductImages as the library name.
- Click Create.
Now add two custom columns to the library so each uploaded image can be linked to a product:
- Click + Add column in the library header row.
- Select Single line of text as the type.
- Enter ProductID as the column name and click Save.
- Click + Add column again.
- Select Choice as the type.
- Enter ImageType as the column name.
- In the Choices field, enter three values on separate lines: Main, Benchmark1, Benchmark2.
- Click Save.
What do ProductID and ImageType do?
ProductID links an uploaded image file back to the product record in your Products list (using the SharePoint item ID). ImageType tells the app which slot the image belongs to: the main product photo, or one of the two benchmark screenshots.
Verify the setup with test data
Before connecting Power Apps, confirm that both data sources work by adding a test record and a test file.
- Navigate back to the Products list.
- Click + New in the command bar (or select + Add new item).
- Fill in a few fields to create a test product. For example, set PRODUCT DESCRIPTION to Test Product Alpha and STAGE to Concept.
- Click Save.
Your test record now appears in the list. Note the ID column value (this is auto-generated by SharePoint).
- Navigate to the ProductImages library.
- Click Upload in the command bar and select any image file from your computer.
- After the file uploads, click on it to open the details pane.
- In the ProductID field, enter the ID number of your test product (e.g., 1).
- In the ImageType field, select Main.
- Close the details pane.
You should now see your test image in the library with the ProductID and ImageType columns filled in.
Don't see the custom columns in the library view?
By default, newly added columns may not appear in the All Documents view. Click the column header area and select Add column, then choose Show/hide columns. Tick the boxes for ProductID and ImageType, then click Apply.
Still not working? Help me show custom columns in my Document Library view.
Your data layer is ready. Next up, you will create the Canvas App and connect it to both of these SharePoint sources.
Create the Canvas App and Connect Data Sources
Your SharePoint data layer is ready. You have a Products list with all the fields you need and a Document Library configured to store product images.
Now it is time to build the app that brings this data to life. In this step, you will create a blank Canvas App in Power Apps Studio and connect it to both SharePoint sources so the app can read and write product data.
In this step, get ready to:
- Create a blank Canvas App in tablet layout.
- Connect the Products list and ProductImages library as data sources.
- Set up a loading pattern with a current product variable.
Create a blank Canvas App in Power Apps Studio
You need a wide canvas to display a product image alongside field sections. The tablet layout gives you the most screen real estate for this two-panel design.
- Open your browser and navigate to https://make.powerapps.com.
- Sign in with your Microsoft 365 account if prompted.
- In the left navigation pane, select Create.
- Select Create from blank.
- In the Start with a blank canvas dialog, choose Tablet size.
- Enter Product Finalisation as the app name, then select Create.
Power Apps opens the app in Power Apps Studio with a blank canvas.
Why tablet layout?
The tablet layout gives you a wide, landscape canvas. This is essential for the two-panel design you will build in the next step, where a large product image sits on the left and field sections fill the right.
Don't see the Create option?
Make sure you have a Power Apps license assigned to your Microsoft 365 account. If the left pane shows a different layout, look for a + Create option or a Blank app card on the home screen.
help me find where to create a blank canvas app in Power Apps
- Connect both SharePoint data sources by selecting Data in the left pane.
- Select Add data.
- Search for SharePoint and select the SharePoint connector.
- Select your SharePoint site from the list, or paste the site URL directly.
- Check the box next to Products (your SharePoint List).
- Also check the box next to ProductImages (your Document Library).
- Select Connect.
Both data sources now appear in the Data pane on the left side of Power Apps Studio.
What is a data source in Power Apps?
A data source is a live connection between your app and an external service like SharePoint. Once connected, you can read from, write to, and filter the data directly using Power Fx formulas inside the app.
Don't see your SharePoint site?
Make sure you are signed into Power Apps with the same Microsoft 365 account that has access to your SharePoint site. If the site still does not appear, paste the full site URL directly into the search field.
help me connect my Power Apps canvas app to SharePoint
Set up the app structure with OnStart
Your app needs to know which product record to display when it first loads. You will create a variable that holds the currently selected product and a loading pattern that prevents the screen from rendering before data is ready.
- In the left pane, select the Tree view tab, then select App (the top-level object in the tree).
- In the property dropdown at the top left of the formula bar, select OnStart.
- Enter the following formula in the formula bar:
Set(varCurrentProduct, First(Products))
What does this formula do?
Set(varCurrentProduct, First(Products)) creates a global variable called varCurrentProduct and fills it with the first record from your Products list.
Every control on your edit screen will read from this variable to display the current product's data. Using a variable means the app queries SharePoint once on load, then works with the cached record until you save or navigate.
- Now add a loading indicator. Select Insert from the command bar at the top.
- Search for and insert a Label control onto Screen1.
- Set the Label's Text property to "Loading...".
- Set the Label's Visible property to IsBlank(varCurrentProduct).
How does this loading pattern work?
When the app first opens, varCurrentProduct is blank until OnStart finishes running. The label stays visible during that moment.
Once the variable is populated with a product record, IsBlank(varCurrentProduct) becomes false and the label hides itself automatically. You will use the inverse of this pattern on your main content controls later so they only appear once data is ready.
- Save your app by pressing Ctrl+S (Windows) or Cmd+S (macOS).
- If prompted, confirm the app name as Product Finalisation and select Save.
App.OnStart not running?
Make sure you selected App in the Tree view (not Screen1) before setting the OnStart property. You can manually trigger OnStart by selecting the three dots (...) next to App and choosing Run OnStart.
help me get App.OnStart to run in my Power Apps canvas app
Verify the data connection with a test gallery
Before building the full edit screen, confirm that your app can actually read data from the Products list. A temporary Gallery control is the fastest way to check this.
- Select Insert from the command bar at the top.
- Search for and select Vertical gallery.
- A gallery control appears on the canvas. In the Properties pane on the right, set the Data source (or Items property) to Products.
- Confirm your test product record appears in the gallery. You should see at least one row with data from the product you created in Step 1.
What should I see?
The gallery should display at least one row populated with field values from your test record. The exact fields shown depend on the gallery's default layout, but you should see text like your product description or article number.
- Now that the connection is confirmed, delete the temporary gallery. Select the gallery control on the canvas, then press the Delete key on your keyboard.
- Save your app again with Ctrl+S (Windows) or Cmd+S (macOS).
Gallery showing no records?
Check that the gallery's Items property is set to Products (not ProductImages). Also verify that the test product record you created in Step 1 has data in at least one visible column like PRODUCT DESCRIPTION.
help me debug why my Power Apps gallery shows no records from SharePoint
Your Canvas App is connected and loading product data. Next up, you will build the visual product editing screen with the two-panel layout.
Build the Product Edit Screen Layout
Your app is connected to both SharePoint data sources and loads the first product into varCurrentProduct. Now you need a screen where the finalisation team can actually see and edit product details.
The editing experience needs to feel visual. Product images should dominate the left side of the screen so the team can assess what they are working with at a glance. Field inputs grouped by category sit on the right. This mirrors how the team currently works in PowerPoint, but now the data is structured and saveable.
In this step, get ready to:
- Create a two-panel layout with a horizontal container (image panel left, fields panel right).
- Add image controls and upload buttons to the left panel.
- Build grouped field sections with input controls on the right panel.
Create the two-panel layout with a horizontal container
The product edit screen uses a split-panel design. The left panel takes 40% of the width for images. The right panel takes 60% for all the data entry fields.
What is a horizontal container?
A horizontal container in Power Apps automatically positions child controls side by side. You control how much space each child gets using the Fill portions property. A child with Fill portions set to 2 gets twice as much space as a child set to 1.
- In Power Apps Studio, select the screen in the Tree view on the left.
- Click Insert in the top menu bar.
- Select the Layout tab in the Insert pane, then click Horizontal container.
- Select the new horizontal container and set its properties in the Properties pane on the right:
X: 0
Y: 0
Width: Parent.Width
Height: Parent.Height
- With the horizontal container selected, set Align (vertical) to Stretch so child containers fill the full height.
- From the Insert pane, add two Vertical container controls inside the horizontal container.
- Select the first vertical container (left panel). Confirm Flexible width is turned on, then set Fill portions to 2.
- Select the second vertical container (right panel). Confirm Flexible width is turned on, then set Fill portions to 3.
Why 2 and 3 for Fill portions?
Fill portions distributes space proportionally. The total is 2 + 3 = 5 parts. The left panel gets 2/5 (40%) and the right panel gets 3/5 (60%) of the available width.
- Set Vertical Overflow to Scroll on the right panel container so long lists of fields remain accessible.
- Set the left panel's Fill (background colour) to RGBA(245, 245, 245, 1) for a light grey that makes images stand out.
- Set the right panel's Fill to RGBA(255, 255, 255, 1) for a clean white background.
Press F5 to preview your app. You should see the screen split into two coloured panels side by side.
Panels not splitting correctly?
Make sure both vertical containers are direct children of the horizontal container. Check the Tree view to confirm they are nested inside it, not placed on the screen alongside it.
If you see the panels stacked vertically instead of side by side, confirm the parent container's Direction is set to Horizontal.
Help me fix my container layout in Power Apps
Add image controls and upload buttons to the left panel
The left panel displays the main product image prominently, with two smaller benchmark images below it. Each image slot gets its own upload button.
- Select the left vertical container in the Tree view.
- Click Insert and add an Image control (from the Media section).
- Set the Image control's Height to 400 to make it large and prominent.
- Select the Image control and set its Image property in the formula bar to this formula:
If(
IsBlank(varCurrentProduct.MainImageURL),
Icon.Image,
varCurrentProduct.MainImageURL
)
What does this formula do?
The IsBlank function checks whether the product has a main image URL stored. If the URL is empty, it shows a built-in image placeholder icon. Otherwise, it loads the image from the stored URL.
- Below the main image, insert a Button control. Set its Text property to "Upload Image".
- Add a second Image control below the button. Set its Height to 200 for a smaller benchmark image size.
- Set the second Image control's Image property to:
If(
IsBlank(varCurrentProduct.BenchmarkImage1URL),
Icon.Image,
varCurrentProduct.BenchmarkImage1URL
)
- Add an "Upload Image" button below the second image.
- Add a third Image control with Height set to 200.
- Set the third Image control's Image property to:
If(
IsBlank(varCurrentProduct.BenchmarkImage2URL),
Icon.Image,
varCurrentProduct.BenchmarkImage2URL
)
- Add a third "Upload Image" button below the third image control.
- Set the left panel's Align (horizontal) property to Center so images and buttons are centred within the panel.
- Set the left panel's Gap property to 16 to add consistent spacing between each control.
Press F5 to preview. You should see three image placeholders (showing the default icon) stacked vertically in the left panel, each with an Upload Image button below it.
Images showing as blank white boxes?
If you see empty white space instead of the placeholder icon, check that you typed Icon.Image (capital I) as the fallback value in each formula. Also verify that varCurrentProduct is loading correctly by checking that App.OnStart still contains your Set(varCurrentProduct, First(Products)) formula.
Help me debug my Image control placeholder formula
Build grouped field sections in the right panel
The right panel organises all 40+ product fields into five logical groups. Each group has a header label followed by the appropriate input controls.
Why group fields into sections?
With 40+ fields, a flat list would be overwhelming. Grouping fields by category (General Info, Logistics, Benchmark, Pricing, Market) matches how the team thinks about the data. Headers give visual anchors so users can quickly jump to the section they need.
- Select the right vertical container in the Tree view.
- Set the right panel's Padding (all sides) to 20 for breathing room around the content.
- Set the right panel's Gap to 12 for consistent spacing between controls.
Now add the first field group. You will repeat this pattern for all five groups.
- Inside the right panel, insert a Label control. Set its Text to "General Info".
- Set the label's Font weight to Bold and Size to 16 so it stands out as a section header.
- Below the header, insert a Text input control for the STAGE field. Rename it to txtStage in the Tree view.
- Set txtStage's Default property to:
varCurrentProduct.STAGE.Value
Why use .Value for Choice columns?
STAGE is a Choice column in SharePoint. Power Apps stores Choice values as records with a .Value property containing the text. For columns that are plain text or numbers, you reference them directly (e.g., varCurrentProduct.WEEK).
- Continue adding TextInput controls for the remaining General Info fields. Name and bind each one:
- txtWeek with Default: varCurrentProduct.WEEK.
- txtFlow with Default: varCurrentProduct.FLOW.
- txtItemStatus with Default: varCurrentProduct.'Item Status'.Value.
- txtBuyer with Default: varCurrentProduct.BUYER.
- txtProductGroup with Default: varCurrentProduct.'PRODUCT GROUP'.
- txtItemCategory with Default: varCurrentProduct.'Item Category'.
- txtArticleNumber with Default: varCurrentProduct.'Article Number'.
- txtVendorName with Default: varCurrentProduct.'Vendor Name'.
- txtProductDescription with Default: varCurrentProduct.'PRODUCT DESCRIPTION'.
What about column names with spaces?
SharePoint column names with spaces must be wrapped in single quotes in Power Fx formulas. For example, the column "Item Category" becomes 'Item Category' when referenced in Power Apps.
- Add a new section header Label with Text set to "Logistics". Apply the same bold, size 16 styling.
- Add TextInput controls for the Logistics fields:
- txtMOQ with Default: varCurrentProduct.'MOQ in CE'.
- txtMinBBD with Default: varCurrentProduct.'Min BBD days'.
- txtLeadtime with Default: varCurrentProduct.'Leadtime WEEKS'.
- txtWHY with Default: varCurrentProduct.WHY.
- txtCUCase with Default: varCurrentProduct.'CU/Case'.
- txtCasesPallet with Default: varCurrentProduct.'Cases/Pallet'.
- txtCUPallet with Default: varCurrentProduct.'CU/Pallet'.
- txtLanguages with Default: varCurrentProduct.Languages.
- txtCommentsLogistics with Default: varCurrentProduct.'Comments Logistics'.
- Add a Dropdown control for the SAMPLE field. Rename it to drpSample.
- Set drpSample's Items property to Choices(Products.SAMPLE) to pull the choice values from SharePoint.
- Set drpSample's Default property to varCurrentProduct.SAMPLE.Value.
- Add a "Benchmark" section header Label. Then add these TextInput controls:
- txtBenchmarkDesc1 with Default: varCurrentProduct.'Benchmark Product Description 1'.
- txtBenchmarkRetailer1 with Default: varCurrentProduct.'Benchmark Retailer 1'.
- txtBenchmarkRSP1 with Default: varCurrentProduct.'Benchmark RSP 1'.
- txtBenchmarkDesc2 with Default: varCurrentProduct.'Benchmark Product Description 2'.
- txtBenchmarkRetailer2 with Default: varCurrentProduct.'Benchmark Retailer 2'.
- txtBenchmarkRSP2 with Default: varCurrentProduct.'Benchmark RSP 2'.
- Add a "Pricing and Margins" section header Label. Add these TextInput controls:
- txtRSP with Default: varCurrentProduct.RSP.
- txtBTWNL with Default: varCurrentProduct.'BTW NL'.
- txtRSPexBTW with Default: varCurrentProduct.'RSP ex BTW'.
- txtDeltaBenchmark with Default: varCurrentProduct.'Delta vs Benchmark'.
- txtMSPexWorks with Default: varCurrentProduct.'MSP ex works'.
- txtMSPInclAvgWorks with Default: varCurrentProduct.'MSP Incl Avg Works'.
- txtRetailerMargin with Default: varCurrentProduct.'Retailer Margin'.
- txtCPB with Default: varCurrentProduct.CPB.
- txtCPS with Default: varCurrentProduct.CPS.
- txtCPW with Default: varCurrentProduct.CPW.
- txtBMSalesMargin with Default: varCurrentProduct.'BM Sales Margin Incl Average Works'.
- txtMinBMSalesMargin with Default: varCurrentProduct.'Min BM Sales Margin'.
- txtTargetSalesMargin with Default: varCurrentProduct.'Target Sales Margin'.
- Add a "Market and Compliance" section header Label. Add these TextInput controls:
- txtACTION with Default: varCurrentProduct.ACTION.
- txtBNL with Default: varCurrentProduct.BNL.
- txtDACH with Default: varCurrentProduct.DACH.
- txtFRANCE with Default: varCurrentProduct.FRANCE.
- txtEMMA with Default: varCurrentProduct.EMMA.
- txtUK with Default: varCurrentProduct.UK.
- txtTRADE with Default: varCurrentProduct.TRADE.
- For the boolean fields, insert two Toggle controls (from the Input section of the Insert pane).
- Rename the first Toggle to tglESGCompliant. Set its Default property to varCurrentProduct.'ESG Compliant'.
- Rename the second Toggle to tglQACompliant. Set its Default property to varCurrentProduct.'QA Compliant'.
- Add a label next to each Toggle so users know what they are toggling (e.g., "ESG Compliant" and "QA Compliant").
- Also add Dropdown controls for the two remaining Choice fields in General Info. Insert a Dropdown, rename it to drpStage, set Items to Choices(Products.STAGE), and Default to varCurrentProduct.STAGE.Value.
- Insert another Dropdown, rename it to drpItemStatus, set Items to Choices(Products.'Item Status'), and Default to varCurrentProduct.'Item Status'.Value.
Press F5 to preview. You should see all five field groups stacked in the right panel with your test product data populated in each input.
Rename controls as you go
Right-click each control in the Tree view and select Rename immediately after inserting it. Keeping names like txtStage rather than the default TextInput1 will make your Patch formulas in the next step far easier to write.
Fields showing default placeholder text instead of data?
If your TextInput controls show "Text input" instead of your test data, double-check that each Default property references varCurrentProduct with the correct column name. Column names with spaces need single quotes around them.
Also confirm your test record in SharePoint has values filled in for those columns.
Help me bind my TextInput controls to SharePoint data
Add the Save Draft button and product title
The final pieces are a Save Draft button for persisting changes and a title label so the user always knows which product they are editing.
- Select the top of the right panel container in the Tree view.
- Insert a Label control at the top of the right panel. Set its Text property to:
varCurrentProduct.'PRODUCT DESCRIPTION'
- Set the label's Font weight to Bold and Size to 20 so it reads as the screen title.
- Insert a Button control. Set its Text property to "Save Draft".
- Position the Save Draft button at the top-right area of the right panel by placing it right after the product title label.
- Style the button with a distinct colour so it is easy to find. Set Fill to RGBA(56, 96, 178, 1) and Color (text) to RGBA(255, 255, 255, 1).
What about the OnSelect formula?
You will wire up the Save Draft button's OnSelect property with a Patch formula in the next step. For now, leaving it empty is fine.
- Add subtle section borders by setting each section header label's BorderThickness (Bottom) to 1 and BorderColor to RGBA(220, 220, 220, 1). This adds a faint line below each group header.
- Press Ctrl+S to save your app.
Press F5 to preview. You should see the product description as a bold title at the top of the right panel, a blue Save Draft button next to it, and all five field groups with subtle separator lines between them.
Product title label showing blank?
If the product title label is empty, your test record's PRODUCT DESCRIPTION column in SharePoint might be blank. Return to your SharePoint list and confirm the test record has a value in that column.
Help me fix my product title label formula
Your product edit screen is fully laid out. Next up, you will build the Power Automate flow that handles image uploads from those Upload Image buttons directly into the SharePoint Document Library.
Build the Image Upload Flow
Your editing screen looks great, but those Upload Image buttons don't do anything yet. Power Apps cannot write files directly to a SharePoint Document Library from a Canvas App.
The solution is a Power Automate instant cloud flow that acts as a middle layer. Your app sends the image file to the flow, the flow uploads it to the ProductImages library, and then it sends the file URL back to the app so the Image control can display it.
In this step, get ready to:
- Create a Power Automate flow that accepts an image file and metadata from the Canvas App.
- Configure the flow to upload the file to the ProductImages library and return the URL.
- Wire the Upload Image buttons to call the flow and update the product record.
Create the Power Automate flow with a Power Apps trigger
The Power Automate pane is built into Power Apps Studio. You can create flows without leaving the app editor.
- In Power Apps Studio, select Power Automate from the app authoring menu on the left.
- In the Power Automate pane, select Create new flow.
- In the Create your flow dialog, select Create from blank.
- Select PowerApps as the trigger.
- Name the flow UploadProductImage at the top of the flow editor.
Now add the four inputs that the Canvas App will pass to this flow.
- In the Power Apps trigger card, select Add an input.
- Select File and name the input FileContent.
- Select Add an input again, choose Text, and name it FileName.
- Add another Text input named ProductID.
- Add a final Text input named ImageType. This will receive values like Main, Benchmark1, or Benchmark2.
Why a Power Automate flow instead of direct upload?
Canvas Apps have no built-in action to create files in a Document Library. The Attachments control only works inside a form, and Image columns have rendering delays.
An instant cloud flow triggered from Power Apps is the recommended pattern for file uploads to SharePoint. The flow handles the file creation, sets metadata, and returns the URL all in one call.
Don't see the Power Automate pane?
The Power Automate pane is enabled by default in Power Apps Studio. If you don't see it, check that you're using the modern authoring experience and that your environment has Power Automate access.
help me find the Power Automate pane in Power Apps Studio
Add the SharePoint actions and response
With the trigger configured, you need three actions: one to upload the file, one to tag it with metadata, and one to return the URL to Power Apps.
- Below the trigger, select New step.
- Search for SharePoint and select the Create file action.
- Set Site Address to your SharePoint site.
- Set Library Name to ProductImages.
- Set Folder Path to /.
- Set File Name to the FileName dynamic content from the trigger.
- Set File Content to the FileContent dynamic content from the trigger.
Next, tag the uploaded file with its product metadata.
- Select New step.
- Search for SharePoint and select Update file properties.
- Set Site Address to the same SharePoint site.
- Set Library Name to ProductImages.
- Set Id to the ItemId dynamic content from the Create file action.
- Set the ProductID field to the ProductID dynamic content from the trigger.
- Set the ImageType field to the ImageType dynamic content from the trigger.
Finally, return the file URL back to Power Apps.
- Select New step.
- Search for Respond to a PowerApp or flow and select it.
- Select Add an output, choose Text, and name the output FileURL.
- Set the value to the Link to item dynamic content from the Create file action.
- Select Save at the top of the flow editor.
What does each action do?
- Create file uploads the image bytes to the ProductImages Document Library with the filename your app provides.
- Update file properties sets the ProductID and ImageType metadata columns on the new file so you can trace which product and slot it belongs to.
- Respond to a PowerApp or flow sends the file's URL back to the Canvas App so the Image control can display it immediately.
Verify your flow by selecting Test in the top-right of the flow editor. Choose Manually and confirm the flow saves without errors.
Flow won't save?
Check that each dynamic content reference points to the correct action. The Link to item output must come from the Create file step, not the Update file properties step.
help me debug my Power Automate flow that won't save
Wire the Upload Image buttons to call the flow
The flow is ready. Now you need to connect the Upload Image buttons in your Canvas App so that selecting an image triggers the flow automatically.
- Return to the Power Apps Studio canvas editor.
- In the Tree view on the left, expand the Add picture control for the main product image.
- Select the AddMediaButton1 control inside it.
- In the property dropdown at the top-left of the formula bar, select OnChange.
- Enter the following formula in the formula bar:
// Call the upload flow and store the result
Set(
varUploadResult,
UploadProductImage.Run(
AddMediaButton1.Media,
AddMediaButton1.FileName,
Text(varCurrentProduct.ID),
"Main"
)
);
// Update the product record with the returned URL
Patch(
Products,
LookUp(Products, ID = varCurrentProduct.ID),
{ MainImageURL: varUploadResult.fileurl }
)
What does this formula do?
- UploadProductImage.Run(...) calls the flow you just created, passing the selected image, its filename, the current product's ID, and the image type.
- Set(varUploadResult, ...) stores the flow's response (which includes the file URL) in a variable.
- The Patch call updates the product's MainImageURL column in the Products list so the Image control can display the uploaded photo.
Now repeat the same pattern for the two Benchmark image slots.
- Select the Add picture control for Benchmark Image 1.
- Select its AddMediaButton control and set the OnChange property to the same pattern, but with "Benchmark1" as the ImageType and patching BenchmarkImage1URL instead.
- Select the Add picture control for Benchmark Image 2.
- Set its OnChange to the same pattern with "Benchmark2" as the ImageType and patching BenchmarkImage2URL.
Keep the formula consistent
The only differences between the three upload buttons are the ImageType string and the URL column being patched. Everything else (the flow call pattern, the variable name) stays the same.
- Save the app by pressing Ctrl+S.
- Select Preview (the play button in the top-right) to test.
- Click the main image Upload button and select any image file from your computer.
- After a few seconds, the large Image control on the left panel should display your uploaded image.
Verify the upload landed correctly by checking the ProductImages library in SharePoint. You should see the new file with the ProductID and ImageType columns filled in.
Image not appearing after upload?
- Check the flow run history in the Power Automate pane. Select the ... (ellipsis) next to your flow and look for failed runs.
- Make sure the Image control's Image property is set to varCurrentProduct.MainImageURL. If you changed it during testing, reset it.
- Confirm the Patch call references the correct field name. SharePoint columns with spaces use _x0020_ encoding in Power Apps formulas.
help me debug why my uploaded image is not displaying in Power Apps
Your image upload pipeline is complete. Next up, you'll wire the Save Draft button so all field edits persist to the SharePoint List using the Patch function.
Wire Up Save Draft with Patch
Your image upload flow is working and the editing screen displays product data beautifully. There is one critical piece missing: when a user fills in all those fields and closes the app, everything disappears.
In this step, you'll wire up the Save Draft button to write every field value back to the SharePoint Products list using the Patch function. You'll also add error handling and a visual save indicator so users always know whether their changes are persisted.
In this step, get ready to:
- Build the Patch formula to save all product fields to SharePoint.
- Add error handling and visual feedback for the save action.
- Test the full product editing workflow end-to-end.
Build the Patch formula for the Save Draft button
The Patch function is how Power Fx writes data back to a data source. It takes three arguments: the data source, the record to update (found with LookUp), and a record of field-value pairs representing the new data.
- Select the Save Draft button at the top-right of your edit screen.
- In the property dropdown (top-left of the formula bar), select OnSelect.
- Paste the following Patch formula into the formula bar:
Patch(
Products,
LookUp(Products, ID = varCurrentProduct.ID),
{
// General Info
STAGE: txtStage.Text,
WEEK: txtWeek.Text,
FLOW: txtFlow.Text,
'Item Status': ddItemStatus.Selected.Value,
BUYER: txtBuyer.Text,
'PRODUCT GROUP': txtProductGroup.Text,
'Item Category': txtItemCategory.Text,
'Article Number': txtArticleNumber.Text,
'Vendor Name': txtVendorName.Text,
'PRODUCT DESCRIPTION': txtProductDescription.Text,
// Logistics
'MOQ in CE': Value(txtMOQ.Text),
'Min BBD days': Value(txtMinBBD.Text),
'Leadtime WEEKS': Value(txtLeadtime.Text),
SAMPLE: ddSample.Selected.Value,
WHY: txtWHY.Text,
'CU/Case': Value(txtCUCase.Text),
'Cases/Pallet': Value(txtCasesPallet.Text),
'CU/Pallet': Value(txtCUPallet.Text),
Languages: txtLanguages.Text,
'Comments Logistics': txtCommentsLogistics.Text,
// Benchmark
'Benchmark Product Description 1': txtBenchmarkDesc1.Text,
'Benchmark Retailer 1': txtBenchmarkRetailer1.Text,
'Benchmark RSP 1': Value(txtBenchmarkRSP1.Text),
'Benchmark Product Description 2': txtBenchmarkDesc2.Text,
'Benchmark Retailer 2': txtBenchmarkRetailer2.Text,
'Benchmark RSP 2': Value(txtBenchmarkRSP2.Text),
// Pricing and Margins
RSP: Value(txtRSP.Text),
'BTW NL': Value(txtBTWNL.Text),
'RSP ex BTW': Value(txtRSPexBTW.Text),
'Delta vs Benchmark': Value(txtDeltaBenchmark.Text),
'MSP ex works': Value(txtMSPexWorks.Text),
'MSP Incl Avg Works': Value(txtMSPInclAvgWorks.Text),
'Retailer Margin': Value(txtRetailerMargin.Text),
CPB: Value(txtCPB.Text),
CPS: Value(txtCPS.Text),
CPW: Value(txtCPW.Text),
'BM Sales Margin Incl Average Works': Value(txtBMSalesMargin.Text),
'Min BM Sales Margin': Value(txtMinBMSalesMargin.Text),
'Target Sales Margin': Value(txtTargetSalesMargin.Text),
// Market and Compliance
ACTION: txtACTION.Text,
BNL: txtBNL.Text,
DACH: txtDACH.Text,
FRANCE: txtFRANCE.Text,
EMMA: txtEMMA.Text,
UK: txtUK.Text,
TRADE: txtTRADE.Text,
'ESG Compliant': togESG.Value,
'QA Compliant': togQA.Value
}
)
What does this formula do?
The formula uses LookUp(Products, ID = varCurrentProduct.ID) to find the existing product record in the SharePoint list. It then overwrites every field with the current value from your input controls.
Notice the three patterns used for different data types. Text fields map directly (txtStage.Text). Number fields wrap in Value() to convert the text input to a number. Choice fields use ddItemStatus.Selected.Value to extract the selected choice text. Boolean fields (Yes/No) use the Toggle control's .Value property directly.
Column names with spaces are wrapped in single quotes ('Item Status') because SharePoint encodes spaces internally.
What about creating a new product?
To create a brand-new record instead of updating an existing one, replace the LookUp line with Defaults(Products). The pattern becomes Patch(Products, Defaults(Products), { ... }). You can add a New Product button that uses this variant later.
- Save the app by pressing Ctrl+S.
Seeing a formula error in the bar?
Check that every column name with spaces is wrapped in single quotes. A common mistake is writing Item Status without quotes. Power Apps shows a red underline if it cannot resolve the column name.
Also confirm your TextInput control names match exactly (e.g., txtStage, txtWeek). You can check a control's name in the left-hand tree view panel.
Help me fix a formula error in my Patch formula
Add error handling and a visual save indicator
The raw Patch formula works, but if the network drops or SharePoint returns an error, the user gets no feedback. You need to wrap the call in error handling and give users clear visual feedback about save state.
- Select the Save Draft button and return to its OnSelect property.
- Replace the entire formula with this wrapped version:
// Wrap Patch in IfError to catch failures
IfError(
Patch(
Products,
LookUp(Products, ID = varCurrentProduct.ID),
{
STAGE: txtStage.Text,
WEEK: txtWeek.Text,
FLOW: txtFlow.Text,
'Item Status': ddItemStatus.Selected.Value,
BUYER: txtBuyer.Text,
'PRODUCT GROUP': txtProductGroup.Text,
'Item Category': txtItemCategory.Text,
'Article Number': txtArticleNumber.Text,
'Vendor Name': txtVendorName.Text,
'PRODUCT DESCRIPTION': txtProductDescription.Text,
'MOQ in CE': Value(txtMOQ.Text),
'Min BBD days': Value(txtMinBBD.Text),
'Leadtime WEEKS': Value(txtLeadtime.Text),
SAMPLE: ddSample.Selected.Value,
WHY: txtWHY.Text,
'CU/Case': Value(txtCUCase.Text),
'Cases/Pallet': Value(txtCasesPallet.Text),
'CU/Pallet': Value(txtCUPallet.Text),
Languages: txtLanguages.Text,
'Comments Logistics': txtCommentsLogistics.Text,
'Benchmark Product Description 1': txtBenchmarkDesc1.Text,
'Benchmark Retailer 1': txtBenchmarkRetailer1.Text,
'Benchmark RSP 1': Value(txtBenchmarkRSP1.Text),
'Benchmark Product Description 2': txtBenchmarkDesc2.Text,
'Benchmark Retailer 2': txtBenchmarkRetailer2.Text,
'Benchmark RSP 2': Value(txtBenchmarkRSP2.Text),
RSP: Value(txtRSP.Text),
'BTW NL': Value(txtBTWNL.Text),
'RSP ex BTW': Value(txtRSPexBTW.Text),
'Delta vs Benchmark': Value(txtDeltaBenchmark.Text),
'MSP ex works': Value(txtMSPexWorks.Text),
'MSP Incl Avg Works': Value(txtMSPInclAvgWorks.Text),
'Retailer Margin': Value(txtRetailerMargin.Text),
CPB: Value(txtCPB.Text),
CPS: Value(txtCPS.Text),
CPW: Value(txtCPW.Text),
'BM Sales Margin Incl Average Works': Value(txtBMSalesMargin.Text),
'Min BM Sales Margin': Value(txtMinBMSalesMargin.Text),
'Target Sales Margin': Value(txtTargetSalesMargin.Text),
ACTION: txtACTION.Text,
BNL: txtBNL.Text,
DACH: txtDACH.Text,
FRANCE: txtFRANCE.Text,
EMMA: txtEMMA.Text,
UK: txtUK.Text,
TRADE: txtTRADE.Text,
'ESG Compliant': togESG.Value,
'QA Compliant': togQA.Value
}
),
Notify("Save failed - check your connection", NotificationType.Error)
);
Notify("Product saved successfully", NotificationType.Success)
How does this error handling work?
IfError tests the Patch call for errors. If the Patch succeeds, IfError returns the result and skips the error branch. If the Patch fails (network issue, permissions, data conflict), the second argument fires and the user sees a red error banner.
The semicolon separates chained behavior actions in Power Fx. After the IfError block completes, the success Notify fires and displays a green success banner at the top of the screen.
Now add a visual indicator so users can tell at a glance whether they have unsaved edits.
- From the Insert menu, select Icons and shapes, then choose Circle.
- Position the circle next to the Save Draft button and resize it to be small (about 12x12 pixels).
- Set the circle's Fill property to a conditional formula that shows green when saved and amber when unsaved:
// Green when saved, amber when edits are unsaved
If(varHasUnsavedChanges, RGBA(255, 191, 0, 1), RGBA(76, 175, 80, 1))
- To track unsaved changes, set a variable on each input's OnChange property. Select any TextInput control (e.g., txtStage), set its OnChange to:
// Mark that unsaved changes exist
Set(varHasUnsavedChanges, true)
- Repeat this OnChange formula for all TextInput, Dropdown, and Toggle controls on your edit screen.
- Finally, add Set(varHasUnsavedChanges, false) at the end of your Save Draft button's OnSelect formula (after the success Notify) so the dot turns green after a successful save.
- Save the app by pressing Ctrl+S.
What should I see?
The small circle next to the Save Draft button should appear green initially. When you edit any field, it turns amber. After clicking Save Draft, it returns to green and a success banner appears at the top of the screen.
Dot stays amber after saving?
Make sure Set(varHasUnsavedChanges, false) comes after the Notify call in the OnSelect formula, separated by a semicolon. If it appears inside the IfError block, it may not execute on success.
Help me fix my save indicator formula
Test the full workflow end-to-end
You now have a complete product editing interface. Time to verify everything works together from start to finish.
- Press F5 (or click the Play icon in the top-right) to preview the app.
- Fill in fields across all five sections (General Info, Logistics, Benchmark, Pricing and Margins, Market and Compliance).
- Click one of the Upload Image buttons and select a product image from your computer.
- Click the Save Draft button.
- Confirm you see a green success banner at the top of the screen and the indicator dot turns green.
Now verify the data landed in SharePoint.
- Open your SharePoint site in a new browser tab.
- Navigate to the Products list and confirm your test record shows the field values you entered.
- Navigate to the ProductImages Document Library and confirm the uploaded image appears with the correct ProductID and ImageType metadata.
- Return to the app preview, change a field value (e.g., update the PRODUCT DESCRIPTION), and click Save Draft again.
- Refresh the Products list in SharePoint and confirm the updated value persists.
What should I see in SharePoint?
Your Products list item should show all field values you entered in the app. The MainImageURL column should contain a URL pointing to the uploaded file in the ProductImages library.
In the ProductImages library, the uploaded file should have its ProductID column set to the product's ID number and ImageType set to Main.
Save succeeds but SharePoint shows blank fields?
This usually means the control names in your Patch formula do not match the actual control names on your screen. Double-check by selecting each input control and comparing its Name property (in the left tree view) against what the formula references.
For Number columns that appear blank, ensure you wrapped the text input in Value(). Without this conversion, SharePoint rejects the text-to-number mismatch silently.
Help me troubleshoot my Patch save to SharePoint
✔️ Awesome, I've got everything!
Great. Double check you've saved your app with Ctrl+S and confirmed the end-to-end flow works in both the app and SharePoint.
ⓧ I'd like to double check the full code
Here is the complete Save Draft button OnSelect formula:
IfError(
Patch(
Products,
LookUp(Products, ID = varCurrentProduct.ID),
{
STAGE: txtStage.Text,
WEEK: txtWeek.Text,
FLOW: txtFlow.Text,
'Item Status': ddItemStatus.Selected.Value,
BUYER: txtBuyer.Text,
'PRODUCT GROUP': txtProductGroup.Text,
'Item Category': txtItemCategory.Text,
'Article Number': txtArticleNumber.Text,
'Vendor Name': txtVendorName.Text,
'PRODUCT DESCRIPTION': txtProductDescription.Text,
'MOQ in CE': Value(txtMOQ.Text),
'Min BBD days': Value(txtMinBBD.Text),
'Leadtime WEEKS': Value(txtLeadtime.Text),
SAMPLE: ddSample.Selected.Value,
WHY: txtWHY.Text,
'CU/Case': Value(txtCUCase.Text),
'Cases/Pallet': Value(txtCasesPallet.Text),
'CU/Pallet': Value(txtCUPallet.Text),
Languages: txtLanguages.Text,
'Comments Logistics': txtCommentsLogistics.Text,
'Benchmark Product Description 1': txtBenchmarkDesc1.Text,
'Benchmark Retailer 1': txtBenchmarkRetailer1.Text,
'Benchmark RSP 1': Value(txtBenchmarkRSP1.Text),
'Benchmark Product Description 2': txtBenchmarkDesc2.Text,
'Benchmark Retailer 2': txtBenchmarkRetailer2.Text,
'Benchmark RSP 2': Value(txtBenchmarkRSP2.Text),
RSP: Value(txtRSP.Text),
'BTW NL': Value(txtBTWNL.Text),
'RSP ex BTW': Value(txtRSPexBTW.Text),
'Delta vs Benchmark': Value(txtDeltaBenchmark.Text),
'MSP ex works': Value(txtMSPexWorks.Text),
'MSP Incl Avg Works': Value(txtMSPInclAvgWorks.Text),
'Retailer Margin': Value(txtRetailerMargin.Text),
CPB: Value(txtCPB.Text),
CPS: Value(txtCPS.Text),
CPW: Value(txtCPW.Text),
'BM Sales Margin Incl Average Works': Value(txtBMSalesMargin.Text),
'Min BM Sales Margin': Value(txtMinBMSalesMargin.Text),
'Target Sales Margin': Value(txtTargetSalesMargin.Text),
ACTION: txtACTION.Text,
BNL: txtBNL.Text,
DACH: txtDACH.Text,
FRANCE: txtFRANCE.Text,
EMMA: txtEMMA.Text,
UK: txtUK.Text,
TRADE: txtTRADE.Text,
'ESG Compliant': togESG.Value,
'QA Compliant': togQA.Value
}
),
Notify("Save failed - check your connection", NotificationType.Error)
);
Notify("Product saved successfully", NotificationType.Success);
Set(varHasUnsavedChanges, false)
And the save indicator circle's Fill property:
If(varHasUnsavedChanges, RGBA(255, 191, 0, 1), RGBA(76, 175, 80, 1))
Each input control's OnChange property:
Set(varHasUnsavedChanges, true)
Secret mission
Add Validation and Unsaved Changes Warning
Your app saves data, but it does not stop users from saving incomplete records or accidentally navigating away from unsaved edits. In this secret mission, add field validation rules that disable the Save button when required fields are empty, an unsaved-changes banner that appears whenever a field is modified, and a navigation warning popup that prevents accidental data loss.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely within your existing Microsoft 365 and Power Platform licensing, so there are no additional ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- SharePoint List: Products (40+ columns across 5 field groups).
- SharePoint Document Library: ProductImages (with ProductID and ImageType columns).
- Canvas App: Product Finalisation (tablet layout with edit screen, image upload, and save draft functionality).
- Power Automate Flow: UploadProductImage (instant cloud flow for image uploads).
Keep everything running
No action needed. Choose this if you are still actively building on this app or plan to extend it soon.
- Your Canvas App, Power Automate flow, SharePoint List, and Document Library all remain available in your Microsoft 365 environment.
- None of these resources consume additional cost beyond your existing Microsoft 365 license.
Pause - I'll come back to this later
Turn off the Power Automate flow to prevent any accidental triggers while you are away. Your data and app stay intact.
- In Power Automate, select My flows in the left pane.
- Find the UploadProductImage flow, click the vertical ellipsis, and select Turn off.
- Your Canvas App and SharePoint data remain untouched and ready when you return.
Delete - I don't want to use this again
Remove all project resources completely. Follow these steps in order to avoid dependency issues.
- Delete the Canvas App: go to make.powerapps.com, select Apps in the left pane, select the Product Finalisation app, click Delete from the top menu, then confirm by selecting Delete from cloud.
- Delete the Power Automate flow: in Power Automate, select My flows in the left pane, find the UploadProductImage flow, click the vertical ellipsis, select Delete, and confirm by selecting Delete in the dialog.
- Delete the SharePoint List: navigate to your SharePoint site, open the Products list, click the gear icon and select List settings, then select Delete this list and confirm with OK.
- Delete the Document Library: navigate to your SharePoint site, open the ProductImages library, click the gear icon and select Library settings, then select Delete this document library and confirm with OK.
Nice Work!
Nice Work!
You just built a full product editing interface that eliminates double-entry between PowerPoint and Excel. Your finalisation team now has a single source of truth with visual product images, structured data entry, and draft saves all in one place.
Here's what you learned:
- Built a SharePoint data layer with 40+ columns across 5 field groups and a Document Library configured with metadata columns to organise product images by record and type.
- Developed a visual Canvas App editing screen using a two-panel container layout with the product image displayed prominently alongside grouped field sections for data entry.
- Implemented image upload via Power Automate and wired up draft save functionality using the Patch function with error handling and user feedback.
- Secret Mission: Added field validation rules, unsaved changes detection, and a navigation warning popup to prevent data loss.
Ready to quiz yourself?