Skip to main content

Build a Career Development Plan App in Power Apps — Part 6: Build the Response Screen

· 30 min read
Jagdish Kumawat
Founder @ Dewiride

A plan only matters once people act on it. This part builds the screen where they do: each competency on My plan opens a screen where the person writes how they show it and sends it to their manager. The same screen shows what happened next: waiting for review, a comment to act on when it's declined, and a locked response once it's approved.

This is Part 6 of a 14-part series.

  1. Part 1: Plan the App and Set Up the Demo Organization
  2. Part 2: Create the SharePoint Site and Lists
  3. Part 3: Create the Solution, Environment Variables and Canvas App
  4. Part 4: Build the Home Screen
  5. Part 5: Build the My Plan Screen
  6. Part 6: Build the Response Screen (you are here)
  7. Part 7: Share the App and Build the My Team Screens
  8. Part 8: Build the Review Screen for Manager Approvals
  9. Part 9: Let Managers Manage Competencies
  10. Part 10: Test Every Role, Joiners and Leavers (coming soon)
  11. Part 11: Build a Setup Flow That Creates the SharePoint Lists (coming soon)
  12. Part 12: Run the Solution Checker and Export the Solutions (coming soon)
  13. Part 13: Install the App in a New Environment (coming soon)
  14. Part 14: Recap, Production Checklist and Next Steps (coming soon)

Part 5 built My plan, a list of the competencies for the person's job title, each with a status badge that always said Not started. Now each row opens a screen with a text box and a Send button, and the badges start to change. The screen saves to the CompetencyResponses list from Part 2 with a single Patch, which creates the item the first time and updates it after that. As before, each generic task has its own short guide, and this part gives the exact values for this app.

What You'll Build​

The Response screen for a response the manager declined, with the manager's comment and a Send again button:

The My response screen for Customer skill, Level Intermediate: a red Declined badge, a yellow note that the profile has no manager, Your manager declined this on Tuesday, October 27, 2026, a bold comment from the manager, the response in a text box, 247 of 4,000 characters and a Send again button

How the pieces connect:

  • Every plan row opens the Response screen, with a button for keyboard users.
  • The screen loads the person's saved response for that competency and level, if there is one.
  • One Patch creates the response the first time and updates it afterwards.
  • Four states: Not started, Waiting for review (still editable), Declined (comment shown, send again) and Approved (read-only).
  • A 4,000-character limit with a live count, a disabled button until there's text, and a clear message if someone else changed the response first.

Prerequisites​

Step 1: Add the Response Limit to App.Formulas​

Responses are capped at 4,000 characters. The number is used twice, by the text box and by the character count, so it gets a name below Part 5's formulas (How to Use Named Formulas in Power Apps):

App → Formulas (added)
ResponseMaxLength = 4000;

The expanded formula bar of App.Formulas ending with StatusPending, StatusApproved and StatusDeclined, and the new line ResponseMaxLength = 4000; selected

Step 2: Add the Response Screen and Its Layout​

Add a blank screen named Response Screen (How to Add a New Screen in Power Apps). Its controls end in RS. This is the structure Steps 2 to 9 build:

Response Screen layout
Response Screen
└── conMainRS vertical container, the whole screen
├── conHeaderRS copied from My Plan: Back button and title
│ ├── btnBackRS
│ └── lblTitleRS
└── conBodyRS vertical container for the content
├── lblCompetencyRS
├── lblLevelRS
├── bdgStatusRS
├── spnLoadingRS
├── lblNoManagerRS
├── lblInfoRS
├── lblCommentRS
├── txtResponseRS
├── lblCountRS
└── btnSendRS

Insert a vertical container on the screen, rename it conMainRS, and give it the same values as Part 5's conMainMPS: X 0, Y 0, Width Parent.Width, Height Parent.Height, LayoutAlignItems LayoutAlignItems.Stretch, all four paddings 0, DropShadow DropShadow.None and all four radius properties 0.

Copy conHeaderMPS from the My Plan screen and paste it on conMainRS (How to Copy and Paste Controls Between Screens). Rename the pasted controls conHeaderRS, btnBackRS and lblTitleRS (How to Rename a Screen or Control), then set:

lblTitleRS → Text
"My response"
btnBackRS → AccessibleLabel
"Back to My plan"

The Back button keeps its OnSelect, Back().

Then insert a second vertical container inside conMainRS, below the header, named conBodyRS:

PropertyValue
LayoutAlignItemsLayoutAlignItems.Stretch
LayoutGap16
PaddingTop, PaddingBottom, PaddingLeft, PaddingRight24
DropShadowDropShadow.None
RadiusTopLeft, RadiusTopRight, RadiusBottomLeft, RadiusBottomRight0
FillPortions1
AlignInContainerAlignInContainer.Stretch
LayoutOverflowYLayoutOverflow.Scroll

These match conBodyMPS, except the last: this screen holds more, so on a small phone the body scrolls instead of cutting off the Send button.

The empty Response Screen on the canvas with the teal header, a Back button and the title My response, and Tree view showing conMainRS with conHeaderRS (btnBackRS and lblTitleRS) and conBodyRS

Step 3: Give Yourself a Plan to Test With​

You'll test this screen in Studio as yourself. In the demo organization, the admin is the Managing Director, whose job title has no competencies (Part 2), so My plan is empty and there's nothing to open. For testing, point MyJobTitle at a job title that has a plan. In App.Formulas, change one line:

App → Formulas (testing only)
MyJobTitle = "Sales Engineer";

The expanded formula bar of App.Formulas with the line MyJobTitle = "Sales Engineer"; selected

Preview from the Home screen and select My plan: the two Sales Engineer competencies appear.

The My Plan screen in preview with the intro The competencies for your job title, Sales Engineer, and where each one stands, and two rows: Customer skill, Level: Intermediate, Not started, and Leadership, Level: Beginner, Not started

warning

This is for testing only. Step 12 puts the real formula back, MyJobTitle = Trim(MyProfile.jobTitle);. Responses you send while testing are real items in CompetencyResponses, saved under your name.

Step 4: Make Each Plan Row Open the Response Screen​

Follow How to Open Another Screen When a Gallery Row Is Selected. On the My Plan screen, set two properties of galMyPlanMPS:

galMyPlanMPS → Selectable
true
galMyPlanMPS → OnSelect
Navigate('Response Screen', ScreenTransition.None, {locPlanItem: ThisItem})

locPlanItem carries the selected competency to the Response screen: its name, level and ID.

The formula bar with the OnSelect property of galMyPlanMPS set to a Navigate to 'Response Screen' that passes ThisItem as locPlanItem, and the gallery rows with Open buttons

Then add a button to the row for keyboard users: select lblCompetencyMPS, so the button goes into the row, and insert Input → Button. Its OnSelect is already Select(Parent), which runs the gallery's OnSelect (How to Use the Select Function).

PropertyValue
NamebtnOpenMPS
Text"Open"
AccessibleLabel"Open " & ThisItem.Competency
AppearanceButtonAppearance.Secondary
Width, Height96, 40
XParent.TemplateWidth - Self.Width - 16
Y(Parent.TemplateHeight - Self.Height) / 2

Make room for it by setting the Width of lblCompetencyMPS and lblLevelMPS to Parent.TemplateWidth - 144.

The formula bar with the OnSelect property of btnOpenMPS set to Select(Parent), and the Open button selected at the right of the first row

The screen opens now, but it's still empty. The next steps fill it.

note

Part 9 makes Open a chevron icon on phones, and the labels' Width Parent.TemplateWidth - btnOpenMPS.Width - 48, so names fit on 360-pixel screens (Fixed: Text and Buttons Cut Off on Narrow Phones).

Step 5: Load the Response When the Screen Opens​

Select Response Screen and set its OnVisible (How to Run a Formula When a Screen Opens). Here it is in four parts.

Start loading, and clear any leftover saving flag:

Response Screen → OnVisible (1 of 4)
UpdateContext({locIsLoading: true, locIsSaving: false});

Find the person's response to this competency at this level with LookUp (How to Find a Record in Power Apps with LookUp). It's blank if they haven't answered yet:

Response Screen → OnVisible (2 of 4)
UpdateContext(
{
locResponse: LookUp(
CompetencyResponses,
EmployeeId = MyProfile.id &&
RoleCompetencyId = locPlanItem.ID &&
Level = locPlanItem.Level.Value
)
}
);

All three conditions are = on text and number columns, so SharePoint does the search, starting from the indexed EmployeeId (What Is Delegation in Power Apps?). Studio showed no delegation warning. Matching on the level too means that if a manager later changes the level, the person starts a new response instead of reusing an old approval.

Work out the status text once, with the same words as My Plan's badges (How to Use the Switch Function):

Response Screen → OnVisible (3 of 4)
UpdateContext(
{
locStatusText: Switch(
locResponse.Status.Value,
StatusPending, "Waiting for review",
StatusApproved, "Approved",
StatusDeclined, "Declined",
"Not started"
)
}
);

Reset the text box to the saved response, then finish loading:

Response Screen → OnVisible (4 of 4)
Reset(txtResponseRS);
UpdateContext({locIsLoading: false})

Without the Reset, the box kept text that had been typed but never saved when the screen opened again, because a text box only refreshes itself when its Default changes (Fixed: Text Input Shows Old, Unsaved Text). Write the reset in now even though txtResponseRS comes in Step 8; Studio flags it until the control exists.

The complete formula:

Response Screen → OnVisible
UpdateContext({locIsLoading: true, locIsSaving: false});
UpdateContext(
{
locResponse: LookUp(
CompetencyResponses,
EmployeeId = MyProfile.id &&
RoleCompetencyId = locPlanItem.ID &&
Level = locPlanItem.Level.Value
)
}
);
UpdateContext(
{
locStatusText: Switch(
locResponse.Status.Value,
StatusPending, "Waiting for review",
StatusApproved, "Approved",
StatusDeclined, "Declined",
"Not started"
)
}
);
Reset(txtResponseRS);
UpdateContext({locIsLoading: false})
note

Part 8 moves this formula into a Refresh button in the header, with Refresh on the list first, so the screen also shows a manager's decision made while it was open.

Step 6: Show the Competency, Level and Status​

Insert these into conBodyRS, in this order: two Text controls, a Badge and a Spinner (How to Add a Text Control, How to Add a Badge Control, How to Add a Loading Spinner).

ControlPropertyValue
lblCompetencyRSTextlocPlanItem.Competency
Size, FontWeight20, FontWeight.Semibold
AutoHeighttrue
AccessibleLabelSelf.Text
lblLevelRSText"Level: " & locPlanItem.Level.Value
AutoHeight, AccessibleLabeltrue, Self.Text
bdgStatusRSContentlocStatusText
IntentSwitch(locStatusText, "Waiting for review", BadgeIntent.Caution, "Approved", BadgeIntent.Positive, "Declined", BadgeIntent.Critical, BadgeIntent.Informative)
AccessibleLabel"Status: " & locStatusText
AlignInContainerAlignInContainer.Start
Width, Height160, 28
Visible!locIsLoading
spnLoadingRSLabel"Loading your response"
VisiblelocIsLoading

AlignInContainer Start keeps the badge its own size; in a container that stretches its children, it would otherwise run the full width.

Step 7: Add the Messages​

Three Text controls explain where things stand.

lblNoManagerRS warns people who have no manager in Microsoft 365, the same case the Home screen points out (Part 4). They can still send; the response waits for whoever becomes their manager:

lblNoManagerRS → Text
"Your Microsoft 365 profile has no manager, so nobody can review this yet. You can still send it, and your manager will see it once your IT admin adds one."
PropertyValue
VisibleIsBlank(MyManager)
FillRGBA(255, 244, 206, 1)
PaddingTop, PaddingBottom, PaddingLeft, PaddingRight12
AutoHeight, AccessibleLabeltrue, Self.Text

lblInfoRS says what the status means and what to do, with dates in words (How to Format a Date with Text):

lblInfoRS → Text
Switch(
locResponse.Status.Value,
StatusPending, "You sent this on " & Text(locResponse.SubmittedOn, DateTimeFormat.LongDate) & ". Your manager hasn't reviewed it yet, so you can still change it.",
StatusApproved, "Your manager approved this on " & Text(locResponse.ReviewedOn, DateTimeFormat.LongDate) & ". Approved responses can't be changed.",
StatusDeclined, "Your manager declined this on " & Text(locResponse.ReviewedOn, DateTimeFormat.LongDate) & ". Update your response and send it again.",
"Describe how you show this competency at the " & locPlanItem.Level.Value & " level, then send it to your manager for review."
)

Its AutoHeight is true, Visible !locIsLoading and AccessibleLabel Self.Text.

lblCommentRS shows the manager's comment, in FontWeight FontWeight.Semibold, with AutoHeight true and AccessibleLabel Self.Text:

lblCommentRS → Text
"Comment from your manager: " & locResponse.ManagerComment
lblCommentRS → Visible
!locIsLoading && !IsBlank(locResponse.ManagerComment)

Step 8: Add the Response Box and the Character Count​

Insert Input → Text input into conBodyRS and name it txtResponseRS (How to Add a Multi-Line Text Input):

PropertyValue
TypeTextInputType.Multiline
DefaultlocResponse.Response
MaxLengthResponseMaxLength
Placeholder"Write your response"
Height240
AccessibleLabel"Your response for " & locPlanItem.Competency
Visible!locIsLoading

Its DisplayMode makes it read-only once the response is approved, and greys it out while saving (How to Make a Control Read-Only with DisplayMode):

txtResponseRS → DisplayMode
If(
locResponse.Status.Value = StatusApproved, DisplayMode.View,
locIsSaving, DisplayMode.Disabled,
DisplayMode.Edit
)

Under it, a Text control lblCountRS counts the characters (How to Limit Text Length and Show a Character Count), with AccessibleLabel Self.Text:

lblCountRS → Text
Len(txtResponseRS.Text) & " of " & Text(ResponseMaxLength, "#,##0") & " characters"
lblCountRS → Visible
!locIsLoading && locResponse.Status.Value <> StatusApproved

Step 9: Send the Response with One Patch​

Insert Input → Button into conBodyRS, name it btnSendRS, and set its look first:

PropertyValue
TextIf(locIsSaving, "Sending...", IsBlank(locResponse), "Send to manager", locResponse.Status.Value = StatusDeclined, "Send again", "Update response")
Icon"Send"
AccessibleLabelSelf.Text
AlignInContainerAlignInContainer.Start
Width, Height200, 40
Visible!locIsLoading && locResponse.Status.Value <> StatusApproved
DisplayModeIf(locIsSaving || IsBlank(Trim(txtResponseRS.Text)), DisplayMode.Disabled, DisplayMode.Edit)

The button's words follow the state, it disappears once a response is approved, and it stays disabled while the box is empty or a save is running (How to Disable a Button Until a Text Box Has Text).

Now its OnSelect. Follow How to Create or Update a SharePoint List Item with Patch; these are this app's values.

The base record: Defaults(CompetencyResponses) when there's no response yet, so Patch creates one; otherwise the loaded locResponse, so it updates that item (Defaults).

The columns: the competency, job title and level are saved as they are now, so the response still makes sense if the plan changes later (Part 2's design). The status goes back to Pending on every send, as a Choice record (Write to a Choice Column). Sending again after a decline clears the manager's comment and review date (Clear a Column with Blank), and SubmittedOn records the moment (Now).

The result: IfError reports a failure, with a plain message when someone else changed the response first; otherwise Notify confirms and Back returns to the plan (IfError, Notify).

The whole formula:

A code window titled btnSendRS → OnSelect: it sets locIsSaving to true, then IfError wraps a Patch to CompetencyResponses that uses Defaults for a new response or locResponse for an existing one and sets the competency, employee, job title, level, trimmed response, status Pending, a blank manager comment and review date and SubmittedOn Now; on an error it clears locIsSaving and shows a conflict or failure notification, and on success it clears locIsSaving, shows a success notification and goes back

btnSendRS → OnSelect
UpdateContext({locIsSaving: true});
IfError(
Patch(
CompetencyResponses,
If(IsBlank(locResponse), Defaults(CompetencyResponses), locResponse),
{
Competency: locPlanItem.Competency,
EmployeeId: MyProfile.id,
EmployeeName: MyProfile.displayName,
EmployeeEmail: Coalesce(MyProfile.mail, MyProfile.userPrincipalName),
JobTitle: MyJobTitle,
RoleCompetencyId: locPlanItem.ID,
Level: locPlanItem.Level.Value,
Response: Trim(txtResponseRS.Text),
Status: {Value: StatusPending},
ManagerComment: Blank(),
SubmittedOn: Now(),
ReviewedOn: Blank()
}
),
UpdateContext({locIsSaving: false});
Notify(
If(
FirstError.Kind = ErrorKind.Conflict,
"This response changed while you were editing it. Go back, open it again and make your change.",
"Your response wasn't sent. " & FirstError.Message
),
NotificationType.Error
),
UpdateContext({locIsSaving: false});
Notify("Your response was sent to your manager.", NotificationType.Success);
Back()
)

EmployeeEmail uses Coalesce because some accounts have no mail value; the user principal name stands in (How to Replace Blank Values with Coalesce). The list's hidden Title column isn't required, so the formula leaves it out.

The finished screen in Studio, before any data is loaded:

The Response Screen in design view: an empty title, Level:, an AB badge placeholder, the yellow no-manager note, the instruction line, the text box with Write your response, 0 of 4,000 characters and a greyed-out Send to manager button, next to Tree view listing all ten body controls

Step 10: Send a First Response​

Select Home Screen, preview, select My plan, then Open on Customer skill. A new response looks like this:

The My response screen in preview for Customer skill: Level Intermediate, a grey Not started badge, the yellow no-manager note, Describe how you show this competency at the Intermediate level, then send it to your manager for review, an empty box, 0 of 4,000 characters and a disabled Send to manager button

The admin sees the yellow note because they have no manager; people with a manager don't. Type a response. The count follows each key and the button turns on:

The same screen with a paragraph about weekly check-in calls with large accounts, 247 of 4,000 characters, and the Send to manager button enabled

Select Send to manager. A green banner confirms it, the app goes back to My plan, and the badge already says Waiting for review:

The My plan screen after sending, with the Customer skill row showing a yellow Waiting for review badge and Leadership still Not started

Going back runs My Plan's OnVisible again, and its query returned the new item straight away: the app's own Patch updates its copy of the list. Changes other people make are different. A running app doesn't pick those up by itself, so Part 8 adds Refresh to every screen (Fixed: Power Apps Doesn't Show Changes Other People Made).

In SharePoint, CompetencyResponses now has its first item, with every column the formula set:

The CompetencyResponses list with one item: Customer skill, a masked EmployeeId, Admin User, admin@example.com, Sales Engineer, 1, Intermediate, the response text, a Pending status and SubmittedOn 10/27/2026

Open it again: the date in words, the saved text, and Update response instead of Send to manager:

The My response screen with a Waiting for review badge, You sent this on Tuesday, October 27, 2026. Your manager hasn't reviewed it yet, so you can still change it., the saved response in the box, 247 of 4,000 characters and an Update response button

That's the whole round trip for one response: written, sent, saved and opened again.

Step 11: Test the Manager's Decisions​

Managers get their own Review screen in Part 8. Until then, play the manager in SharePoint: open CompetencyResponses, edit the item, and change its Status, ManagerComment and ReviewedOn (How to Edit an Item in a SharePoint List).

A declined response​

Set Status to Declined, add a comment and a review date, and Save:

The SharePoint edit form with Status Declined, the ManagerComment Good example. Add what changed for the customer after the fix, then send it again., SubmittedOn 10/27/2026 10:35 AM and ReviewedOn 10/27/2026 10:50 AM

Back in the app, open My plan again. In my test, it showed a red Declined badge. An edit made in SharePoint is a change from outside the app, which a running app isn't guaranteed to show until it refreshes its data; Part 8 adds that. If your badge hasn't changed, refresh CompetencyResponses in Studio's Data pane (... → Refresh) and open My plan again:

The My plan screen with Customer skill showing a red Declined badge

Open it: the decline date, the comment in bold, the text still editable, and Send again (the picture at the top of this part). Add the result the manager asked for and send it again. The banner confirms it, and the badge is back to Waiting for review:

A green banner reading Your response was sent to your manager., above the My plan screen with Customer skill back to Waiting for review

The item's version history shows what the send did: version 2.0 is the decline, and version 3.0 the new send, with the comment and review date cleared:

Version history: version 3.0 with the new Response, Status Pending, an empty ManagerComment, SubmittedOn 10/27/2026 10:42 AM and an empty ReviewedOn, below version 2.0 with Status Declined, the comment and ReviewedOn

An approved response​

Set Status to Approved with a review date. My plan shows a green badge:

The My plan screen with Customer skill showing a green Approved badge

And the response is read-only, with no count and no button:

The My response screen with a green Approved badge, Your manager approved this on Tuesday, October 27, 2026. Approved responses can't be changed., and the response in a read-only box

A change made at the same time​

What if the manager approves while the employee is still editing? Test it: set the item back to Pending in SharePoint, open it in the app, then approve it in SharePoint while the app still shows the old copy. Change the text in the app and select Update response:

A red banner reading This response changed while you were editing it. Go back, open it again and make your change., above the My response header

SharePoint refused the update, because the item had changed since the app read it, and the item stayed Approved. Without that check the employee's edit would have quietly undone the approval. The raw error and why it happens are in Fixed: "Network Error When Using Patch Function: ETAG Mismatch".

On a phone​

At a phone size (Phones → Apple iPhone 12, 13, 14, How to Test on Phone and Tablet Sizes), the messages wrap and everything fits:

The Response screen in an iPhone frame for Leadership, Level Beginner, Not started, with the wrapped no-manager note and instruction, the text box, 0 of 4,000 characters and the Send to manager button

Step 12: Put Your Job Title Back, Check and Save​

Put the real formula back in App.Formulas:

App → Formulas (restore)
MyJobTitle = Trim(MyProfile.jobTitle);

Preview again: the Home screen says Job title: Managing Director and My plan shows the empty state from Part 5. Your test response stays in CompetencyResponses; the app doesn't show it to anyone, because it doesn't match your real job title. Delete it from the list if you'd rather not keep it.

Open the App checker and select Recheck all. Formulas, Runtime, Performance and Data source are clear. Accessibility (4) lists the two headings, lblTitleMPS and lblTitleRS, each with Focus isn't showing and Missing tab stop:

The App checker's Accessibility page: Errors (4), Focus isn't showing (2) on lblTitleMPS and lblTitleRS, and Missing tab stop (2) on the same two controls

They stay for the reason Part 5 explains: a heading that does nothing keeps TabIndex -1, as Microsoft's guidance says, and making it a tab stop would make screen readers call it a button. The new screen's heading was copied from My Plan, so it carries the same two items.

Select Save. Don't publish yet: Part 7 publishes the app and shares it.

The complete App.Formulas after this part:

App → Formulas
AppTitle = "Career Development Plan";
MyProfile = Office365Users.MyProfileV2({'$select': "id,displayName,givenName,mail,userPrincipalName,jobTitle"});
MyJobTitle = Trim(MyProfile.jobTitle);
MyManager = IfError(
Office365Users.ManagerV2(
MyProfile.id,
{'$select': "id,displayName,mail,jobTitle"}
),
Blank()
);
MyDirectReports = Sort(
Filter(
Office365Users.DirectReportsV2(
MyProfile.id,
{'$select': "id,displayName,mail,userPrincipalName,jobTitle,accountEnabled"}
).value,
accountEnabled
),
displayName
);
IsManager = !IsEmpty(MyDirectReports);
StatusPending = "Pending";
StatusApproved = "Approved";
StatusDeclined = "Declined";
ResponseMaxLength = 4000;

Common Mistakes​

MistakeWhat happensDo this instead
Passing Self.Selected to the Response screenIncompatible type on the galleryPass ThisItem
Inserting the Open button with the gallery selectedIt lands next to the gallerySelect lblCompetencyMPS first
No Reset in OnVisibleUnsent text shows when a response is opened againReset(txtResponseRS) after loading
Status: "Pending"The Choice column needs a recordStatus: {Value: StatusPending}
Leaving out ManagerComment and ReviewedOnA resent response keeps the old declineSet them to Blank()
Forgetting to restore MyJobTitleEveryone sees the Sales Engineer planPut Trim(MyProfile.jobTitle) back

Troubleshooting​

SymptomLikely causeFix
Incompatible type … context variable types are incompatibleSelf.Selected stored in a variableFixed: "Incompatible Type"
Unexpected characters on a controlA stray character, such as an extra bracketFixed: "Unexpected Characters"
Can't rename. This name is already being usedAnother control has that nameFixed: "Can't Rename"
Network error when using Patch function: … ETAG mismatchThe item changed after the app read itFixed: ETAG Mismatch
The box shows text that was never savedNo Reset when the screen opensFixed: Text Input Shows Old Text
The screen is empty in StudioIt was opened from the tree, so locPlanItem is blankPreview from the Home screen
My plan has no rows to openYour job title has no competenciesStep 3

FAQ​

Why does the admin see the no-manager note?​

Because the admin is at the top of the demo organization, with no manager. Everyone else has one, so they don't see it. The response can still be sent; it waits for whoever becomes the manager.

Why does sending again set the status back to Pending?​

A changed response needs a fresh review. That's also why the manager's old comment and review date are cleared.

Can people change a response after sending it?​

Yes, until the manager decides. Waiting for review responses can be updated; approved ones are locked.

Why not use an Edit form and SubmitForm?​

Patch fits a custom screen like this one: it sets exactly the columns the app needs, including snapshots the person never types. Microsoft's guidance suggests Patch for a custom save experience without a form control.

Is the read-only state secure?​

It's the app's rule, not a permission. People with access to the list could still edit it there. Part 1 explains the security model: SharePoint permissions protect the data.

Conclusion​

The app now records responses. Each competency on My plan opens the Response Screen, which:

  • loads the person's saved response for that competency and level;
  • saves it with one Patch that creates or updates the item, always as Pending;
  • shows the manager's decision: a comment to act on, or a read-only approved response;
  • counts characters, disables Send until there's text, and explains conflicts and failures in plain words.

← Previous: Part 5: Build the My Plan Screen

Next → Part 7: Share the App and Build the My Team Screens. You'll publish the app, share it with the team, and build the screens where managers see their direct reports.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.