Overview of modern combo box vs SharePoint people picker

Overview of modern combo box vs SharePoint people picker

The modern ComboBox in Power Apps can display Person/Group values, but it often fails to reliably write (Patch/SubmitForm) back to SharePoint People Picker columns. The root issues are data shape mismatches, property naming differences, and limited support for the expanded user object that SharePoint expects. The classic ComboBox handles the expanded user record more consistently.

What SharePoint expects for person/group fields

  • Expanded user record: SharePoint Person/Group columns use the SPListExpandedUser shape.
    • Typical properties in the record:
      • Claims: i:0#.f|membership|user@domain.com
      • DisplayName: Friendly name
      • Email: User email
      • Sometimes: Department, JobTitle, Picture
  • Items source must be Choices():
    • Choices([@List].’PersonColumn’) returns records in the correct expanded format.
    • These records already contain Claims, DisplayName, Email.
  • Single vs multi-select:
    • Single person column: Update expects a single record.
    • Multi-person column: Update expects a table (collection) of records.

Why the modern combo box often doesn’t work

  • Label-only binding: Modern ComboBox can display DisplayName, but selection may not produce the full SPListExpandedUser record.
  • Property mismatches: The selected item may expose properties like Mail instead of Email, or miss Claims entirely, causing Patch errors.
  • DefaultSelectedItems quirks: Modern control may require a table (even for single select), and Parent.Default might be a single record—leading to type warnings or silent failures.
  • Search behavior: Modern control often expects a flat dataset; SharePoint Choices returns expanded records. Searching can feel slow or inconsistent.
  • Write-back limitations: SubmitForm/Patch can fail if Update returns a minimal record (e.g., only DisplayName) rather than the full expanded user object.
  • Multi-select handling: Modern ComboBox sometimes returns SelectedItems without the Claims property, breaking multi-person saves.

Step-by-step: reliable approach with classic combo box

1) Items

  • Use Choices on the Person column
    • This guarantees the correct expanded shape.
  • Items formula
    • For CaseManagerAssignment (single person):
      • Items = Choices([@Case].’CaseManagerAssignment’)
  • Search fields
    • Limit to properties that exist on the expanded user record.
      • SearchFields = [“DisplayName”]

2) DefaultSelectedItems

  • Use Parent.Default
    • Parent.Default is the current value of the data card bound to the Person column.
  • Formula
    • DefaultSelectedItems = Parent.Default
  • If you ever see a type error and need to force a table:
    • DefaultSelectedItems = If(!IsBlank(Parent.Default), [Parent.Default])

3) SelectMultiple

  • Single-select column
    • SelectMultiple = false
  • Multi-select column
    • SelectMultiple = true
    • Ensure Update returns SelectedItems (table) instead of Selected (record).

4) Update (critical)

  • Single-select (recommended)
    • Update = DCValue_AffectedUser.Selected
    • This passes the expanded user record as-is.
  • Single-select (manual build if needed)
    • Update = { ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”, Claims: DCValue_AffectedUser.Selected.Claims, DisplayName: DCValue_AffectedUser.Selected.DisplayName, Email: DCValue_AffectedUser.Selected.Email }
  • Multi-select
    • Update = DCValue_AffectedUser.SelectedItems
    • Or map each item to ensure Claims, DisplayName, Email if your dataset is inconsistent.

5) DisplayMode

  • Keep it simple
    • DisplayMode = Parent.DisplayMode
    • This respects form New/Edit/View without hard-coding a form name.

6) Layout and error placement

  • Position below label
    • X = 24
    • Y = DataCardKey.Y + DataCardKey.Height + 4
    • Width = Parent.Width – 48
    • Height = 32
  • Error message
    • Y = DCValue_AffectedUser.Y + DCValue_AffectedUser.Height

Full reusable code: classic ComboBox for single person column

Use this template for any single-select SharePoint Person column inside a data card.

yaml

– <Person_DataCard>:

    Control: TypedDataCard@1.0.7

    Variant: ComboBoxEdit

    Properties:

      DataField: =”<PersonColumnName>”

      Default: =ThisItem.<PersonColumnName>

      DisplayName: =DataSourceInfo([@<ListName>], DataSourceInfo.DisplayName, ‘<PersonColumnName>’)

      Required: =false

      Update: =DCValue_Person.Selected

      Width: =370

      X: =4

      Y: =2

    Children:

      – DataCardKey:

          Control: Text@0.0.51

          Properties:

            Height: =22

            Text: =”<Friendly label>”

            Weight: =’TextCanvas.Weight’.Semibold

            Width: =Parent.Width – 48

            X: =24

            Y: =10

      – DCValue_Person:

          Control: Classic/ComboBox@2.4.0

          Properties:

            DefaultSelectedItems: =Parent.Default

            Items: =Choices([@<ListName>].'<PersonColumnName>’)

            DisplayFields: =[“DisplayName”,”Email”]

            SearchFields: =[“DisplayName”]

            SelectMultiple: =false

            DisplayMode: =Parent.DisplayMode

            Width: =Parent.Width – 48

            Height: =32

            X: =24

            Y: =DataCardKey.Y + DataCardKey.Height + 4

      – ErrorMessage:

          Control: Text@0.0.51

          Properties:

            Text: =Parent.Error

            Visible: =And(!IsBlank(Parent.Error), Parent.DisplayMode=DisplayMode.Edit)

            Width: =Parent.Width – 48

            Height: =30

            X: =24

            Y: =DCValue_Person.Y + DCValue_Person.Height

If your environment requires manual construction:

powerfx

Update = {

    ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”,

    Claims: DCValue_Person.Selected.Claims,

    DisplayName: DCValue_Person.Selected.DisplayName,

    Email: DCValue_Person.Selected.Email

}

Full reusable code: classic ComboBox for multi-person column

yaml

– <People_DataCard>:

    Control: TypedDataCard@1.0.7

    Variant: ComboBoxEdit

    Properties:

      DataField: =”<PeopleColumnName>”

      Default: =ThisItem.<PeopleColumnName>

      DisplayName: =DataSourceInfo([@<ListName>], DataSourceInfo.DisplayName, ‘<PeopleColumnName>’)

      Required: =false

      Update: =DCValue_People.SelectedItems

      Width: =370

      X: =4

      Y: =2

    Children:

      – DataCardKey:

          Control: Text@0.0.51

          Properties:

            Height: =22

            Text: =”<Friendly label>”

            Weight: =’TextCanvas.Weight’.Semibold

            Width: =Parent.Width – 48

            X: =24

            Y: =10

      – DCValue_People:

          Control: Classic/ComboBox@2.4.0

          Properties:

            DefaultSelectedItems: =Parent.Default

            Items: =Choices([@<ListName>].'<PeopleColumnName>’)

            DisplayFields: =[“DisplayName”,”Email”]

            SearchFields: =[“DisplayName”]

            SelectMultiple: =true

            DisplayMode: =Parent.DisplayMode

            Width: =Parent.Width – 48

            Height: =32

            X: =24

            Y: =DataCardKey.Y + DataCardKey.Height + 4

      – ErrorMessage:

          Control: Text@0.0.51

          Properties:

            Text: =Parent.Error

            Visible: =And(!IsBlank(Parent.Error), Parent.DisplayMode=DisplayMode.Edit)

            Width: =Parent.Width – 48

            Height: =30

            X: =24

            Y: =DCValue_People.Y + DCValue_People.Height

If you need to ensure Claims/Email/DisplayName for each:

powerfx

Update = ForAll(

    DCValue_People.SelectedItems,

    {

        ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”,

        Claims: Claims,

        DisplayName: DisplayName,

        Email: Email

    }

)

Practical tips and limitations of the modern combo box

  • Use classic ComboBox for Person columns when reliability matters; modern control can display but inconsistently writes back.
  • Avoid Office365Users for Items when binding to a SharePoint Person column. It returns a different shape (User objects), not the expanded SharePoint record.
  • DefaultSelectedItems must be a table for modern controls in some cases, even for single select; classic handles Parent.Default more gracefully.
  • Do not manually concatenate Claims unless necessary. Prefer using the Claims value returned by Choices().
  • Performance: Choices() queries people via SharePoint’s directory; heavy environments can feel slower—keep SearchFields minimal and avoid large TOP queries.
  • Multi-tenant/guest users: Guest accounts must exist in the site’s user directory; otherwise, Choices may not return them, and Patch will fail.

Direct application to your current card (CaseManagerAssignment)

Use these final formulas in your current setup:

  • DCValue_AffectedUser.Items

Items = Choices([@Case].’CaseManagerAssignment’)

  • DCValue_AffectedUser.DefaultSelectedItems

DefaultSelectedItems = Parent.Default

  • DCValue_AffectedUser.SelectMultiple

SelectMultiple = false

  • DataCard.Update

Update = DCValue_AffectedUser.Selected

  • ErrorMessage210.Y

Y = DCValue_AffectedUser.Y + DCValue_AffectedUser.Height

  • DCValue_AffectedUser.DisplayMode

DisplayMode = Parent.DisplayMode

If you see a type mismatch in DefaultSelectedItems, use:

DefaultSelectedItems = If(!IsBlank(Parent.Default), [Parent.Default])

 

Existing complete code

– CaseManagerAssignment_DataCard1:

    Control: TypedDataCard@1.0.7

    Variant: ComboBoxEdit

    Properties:

      DataField: =”CaseManagerAssignment”

      Default: =ThisItem.CaseManagerAssignment

      DisplayName: =DataSourceInfo([@Case],DataSourceInfo.DisplayName,’CaseManagerAssignment’)

      Required: =false

      Update: |-

        ={

            ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”,

            Claims: DCValue_AffectedUser.Selected.Claims,

            DisplayName: DCValue_AffectedUser.Selected.DisplayName,

            Email: DCValue_AffectedUser.Selected.Email

        }



        //DataCardValue198.Selected

        /*{

            ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”,

            Claims: DataCardValue198.Selected,

            DisplayName: DataCardValue198.Selected.DisplayName,

            Email:DataCardValue198.Selected.Mail

        }

        */

 

        /*{

            ‘@odata.type’: “#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser”,

            Claims: “i:0#.f|membership|” & DataCardValue198.Selected.Mail,

            DisplayName: DataCardValue198.Selected.DisplayName,

            Email: DataCardValue198.Selected.UserPrincipalName

        }

        */

      Width: =370

      X: =4

      Y: =2

    Children:

      – DataCardKey210:

          Control: Text@0.0.51

          MetadataKey: FieldName

          Properties:

            Height: =22

            Text: =”Case Manager Assignment”

            Weight: =’TextCanvas.Weight’.Semibold

            Width: =Parent.Width – 48

            Wrap: =false

            X: =24

            Y: =10

      – DataCardValue198:

          Control: ComboBox@0.0.51

          MetadataKey: FieldValue

          Properties:

            AccessibleLabel: =Parent.DisplayName

            DefaultSelectedItems: |+

              =//Office365Users.SearchUserV2({searchTerm:ThisItem.CaseManagerAssignment.Email,top:1}).value

              //Office365Users.SearchUserV2({searchTerm:ThisItem.CaseManagerAssignment.Email,top:1}).value

 

              //Parent.Default

              //DCValue_AffectedUser.SelectedItems

              If(!IsBlank(Parent.Default), [Parent.Default])

 

            DisplayMode: |+

              =//Parent.DisplayMode

              DisplayMode.Disabled

            InputTextPlaceholder: |-

              =”🔎 Search for User”

            Items: |-

              =Choices([@Case].CaseManagerAssignment)

 

              /*

              Office365Users.SearchUserV2(

                  {

                      searchTerm: Self.SearchText,

                      top: 999,

                      isSearchTermRequired: false

                  }

              ).value*/

              //Choices([@Case].’CaseManagerAssignment’)

 

              /*Office365Users.SearchUserV2(

                  {

                      searchTerm: Self.SearchText,

                      top: 999,

                      isSearchTermRequired: false

                  }

              ).value

              */

            Required: =Parent.Required

            TriggerOutput: =’ComboboxCanvas.TriggerOutput’.Delayed

            ValidationState: =If(IsBlank(Parent.Error), “None”, “Error”)

            Visible: =false

            Width: =Parent.Width – 48

            X: =24

            Y: =DataCardKey210.Y + DataCardKey210.Height + 4

          Children:

            – DisplayName2:

                Control: ComboBoxDataField@1.5.0

                Variant: textualColumn

                IsLocked: true

                Properties:

                  FieldDisplayName: =”DisplayName”

                  FieldName: =”DisplayName”

                  FieldType: =”s”

                  Order: =1

      – ErrorMessage210:

          Control: Text@0.0.51

          MetadataKey: ErrorMessage

          Properties:

            Height: =30

            Text: =Parent.Error

            Visible: =And(!IsBlank(Parent.Error), Parent.DisplayMode=DisplayMode.Edit)

            Width: =Parent.Width – 48

            X: =24

            Y: =DataCardValue198.Y + DataCardValue198.Height

      – StarVisible210:

          Control: Text@0.0.51

          MetadataKey: FieldRequired

          Properties:

            Align: =’TextCanvas.Align’.Center

            Height: =20

            Text: =”*”

            Visible: =And(Parent.Required, Parent.DisplayMode=DisplayMode.Edit)

            Width: =30

            Y: =DataCardKey210.Y

      – DCValue_AffectedUser:

          Control: Classic/ComboBox@2.4.0

          Properties:

            BorderColor: =RGBA(214, 221, 224, 1)

            BorderThickness: =1

            ChevronBackground: =Color.White

            ChevronDisabledBackground: =Color.WhiteSmoke

            ChevronDisabledFill: =Color.WhiteSmoke

            ChevronFill: =Color.WhiteSmoke

            ChevronHoverBackground: =Color.WhiteSmoke

            ChevronHoverFill: =Color.WhiteSmoke

            DefaultSelectedItems: |-

              =Parent.Default

              /*If(

                  !IsBlank(Parent.Default),

                  Table({

                      Claims: Parent.Default.Claims,

                      DisplayName: Parent.Default.DisplayName,

                      Email: Parent.Default.Email

                  })

              )

 

              */

            DisabledBorderColor: =Color.Transparent

            DisplayFields: =[“DisplayName”,”Claims”,”Email”]

            DisplayMode: |-

              =/* Switch(‘Create Form Part 2’.Mode, FormMode.Edit, If(IsRoleViewAndEdit || ThisItem.CreatedBy.Email = fxCurrentUserEmail, DisplayMode.Edit, DisplayMode.Disabled), FormMode.New, Parent.DisplayMode, FormMode.View, Parent.DisplayMode )*/

              Parent.DisplayMode

            FocusedBorderThickness: =0

            Font: =Font.’Segoe UI’

            Height: =32

            HoverColor: =Color.Black

            HoverFill: =ColorValue(“#407ec9”)

            InputTextPlaceholder: |-

              =”🔎 Search for User”

            Items: |-

              =Choices([@Case].’CaseManagerAssignment’)

              //Choices([@SIR].’Staff affected’)

            OnSelect: =Set(varShowBanner, false)

            PaddingLeft: =15

            PressedColor: =Color.White

            PressedFill: =Color.White

            SearchFields: =[“DisplayName”]

            SelectMultiple: =false

            SelectionColor: =Color.Black

            SelectionFill: =Color.White

            SelectionTagFill: =Color.WhiteSmoke

            Size: =11

            Width: =Parent.Width – 48

            X: =24

            Y: =DataCardKey210.Y + DataCardKey210.Height + 4

 

Control Reuseable

      – DCValue_AffectedUser:

          Control: Classic/ComboBox@2.4.0

          Properties:

            BorderColor: =RGBA(214, 221, 224, 1)

            BorderThickness: =1

            ChevronBackground: =Color.White

            ChevronDisabledBackground: =Color.WhiteSmoke

            ChevronDisabledFill: =Color.WhiteSmoke

            ChevronFill: =Color.WhiteSmoke

            ChevronHoverBackground: =Color.WhiteSmoke

            ChevronHoverFill: =Color.WhiteSmoke

            DefaultSelectedItems: |-

              =Parent.Default

              /*If(

                  !IsBlank(Parent.Default),

                  Table({

                      Claims: Parent.Default.Claims,

                      DisplayName: Parent.Default.DisplayName,

                      Email: Parent.Default.Email

                  })

              )

 

              */

            DisabledBorderColor: =Color.Transparent

            DisplayFields: =[“DisplayName”,”Claims”,”Email”]

            DisplayMode: |-

              =/* Switch(‘Create Form Part 2’.Mode, FormMode.Edit, If(IsRoleViewAndEdit || ThisItem.CreatedBy.Email = fxCurrentUserEmail, DisplayMode.Edit, DisplayMode.Disabled), FormMode.New, Parent.DisplayMode, FormMode.View, Parent.DisplayMode )*/

              Parent.DisplayMode

            FocusedBorderThickness: =0

            Font: =Font.’Segoe UI’

            Height: =32

            HoverColor: =Color.Black

            HoverFill: =ColorValue(“#407ec9”)

            InputTextPlaceholder: |-

              =”🔎 Search for User”

            Items: |-

              =Choices([@Case].’CaseManagerAssignment’)

              //Choices([@SIR].’Staff affected’)

            OnSelect: =Set(varShowBanner, false)

            PaddingLeft: =15

            PressedColor: =Color.White

            PressedFill: =Color.White

            SearchFields: =[“DisplayName”]

            SelectMultiple: =false

            SelectionColor: =Color.Black

            SelectionFill: =Color.White

            SelectionTagFill: =Color.WhiteSmoke

            Size: =11

            Width: =Parent.Width – 48

            X: =24

            Y: =DataCardKey210.Y + DataCardKey210.Height + 4

 

 

 

Share this post :
Scroll to Top