User Picker isn't saving my selection

I added a User Picker to my Interface. 

I have defined "Selected Users" as ri!selectedUsers (which is an array of type User)

I have defined "Save Into" as ri!selectedUsers

When I select user, the selection is not saved in the component. I have seen some advice regarding a!save, and using load and local variables, but I am missing something and can't seem to find it explicitly explained in videos or the documentation.

Any suggestions?

Thanks,

Rob

  Discussion posts and replies are publicly visible

Parents
  • I have attached the code below...

    Important part:

    a!pickerFieldUsers(
    label: "First Officer",
    labelPosition: "ABOVE",
    maxselections: 1,
    groupfilter: cons!TA_ALL_USERS,
    value: ri!selectedUser,
    saveInto: ri!selectedUser,
    validations: {}
    )

    And the rule input looks like this (an array of User):

    The behaviour is that the UI lets me enter a User name, but when I select it, it flashes in the "First Officer" field then disappears.

    It is a little weird, but I am probably just missing something simple....

    ============================

    a!formLayout(
    label: "Flight",
    contents: {
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!dateField(
    label: "Date",
    labelPosition: if(
    ri!readOnly,
    "ADJACENT",
    "ABOVE"
    ),
    value: ri!flight.date,
    saveInto: ri!flight.date,
    readOnly: ri!readOnly
    ),
    a!textField(
    label: "Captain",
    labelPosition: if(
    ri!readOnly,
    "ADJACENT",
    "ABOVE"
    ),
    value: ri!flight.captain,
    saveInto: ri!flight.captain,
    readOnly: ri!readOnly,
    validations: if(
    len(
    ri!flight.captain
    ) > 255,
    "Value may not be longer than 255 characters. You have entered " & len(
    ri!flight.captain
    ) & " characters.",
    null
    )
    ),
    a!textField(
    label: "Special Instructions",
    labelPosition: if(
    ri!readOnly,
    "ADJACENT",
    "ABOVE"
    ),
    value: ri!flight.specialInstructions,
    saveInto: ri!flight.specialInstructions,
    readOnly: ri!readOnly,
    validations: if(
    len(
    ri!flight.specialInstructions
    ) > 255,
    "Value may not be longer than 255 characters. You have entered " & len(
    ri!flight.specialInstructions
    ) & " characters.",
    null
    )
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Customer",
    labelPosition: if(
    ri!readOnly,
    "ADJACENT",
    "ABOVE"
    ),
    value: ri!flight.customer,
    saveInto: ri!flight.customer,
    readOnly: ri!readOnly,
    validations: if(
    len(
    ri!flight.customer
    ) > 255,
    "Value may not be longer than 255 characters. You have entered " & len(
    ri!flight.customer
    ) & " characters.",
    null
    )
    ),
    a!pickerFieldUsers(
    label: "First Officer",
    labelPosition: "ABOVE",
    maxselections: 1,
    groupfilter: cons!TA_ALL_USERS,
    value: ri!selectedUser,
    saveInto: ri!selectedUser,
    validations: {}
    )
    }
    )
    }
    ),
    {
    a!localVariables(
    local!employees: {
    {id: 1, name: "Elizabeth Ward", dept: "Engineering", role: "Senior Engineer", team: "Front-End Components", pto: 15, startDate: today()-500},
    {id: 2, name: "Michael Johnson", dept: "Finance", role: "Payroll Manager", team: "Accounts Payable", pto: 2, startDate: today()-100},
    {id: 3, name: "John Smith", dept: "Engineering", role: "Quality Engineer", team: "User Acceptance Testing", pto: 5, startDate: today()-1000},
    {id: 4, name: "Diana Hellstrom", dept: "Engineering", role: "UX Designer", team: "User Experience", pto: 49, startDate: today()-1200},
    {id: 5, name: "Francois Morin", dept: "Sales", role: "Account Executive", team: "Commercial North America", pto: 15, startDate: today()-700},
    {id: 6, name: "Maya Kapoor", dept: "Sales", role: "Regional Director", team: "Front-End Components", pto: 15, startDate: today()-1400},
    {id: 7, name: "Anthony Wu", dept: "Human Resources", role: "Benefits Coordinator", team: "Accounts Payable", pto: 2, startDate: today()-300}
    },
    /* This variable is used to pass the full row of data on the selected item to the part of the interface showing the details of the selected item. */
    /* Here we are pre-selecting a row by indexing into the sample data; however, the data for the pre-selected row would typically be passed in as a *
    * rule input or generated with a query. */
    local!selectedEmployee: local!employees[4],
    {
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!sectionLayout(
    label: "Legs",
    contents: {
    a!gridField(
    /* Replace the dummy data with a query, rule, or function that returns a datasubset and uses fv!pagingInfo as the paging configuration. */
    data: todatasubset(
    local!employees,
    fv!pagingInfo
    ),
    columns: {
    a!gridColumn(
    label: "Name",
    value: fv!row.name
    ),
    a!gridColumn(
    label: "Department",
    value: fv!row.dept
    )
    },
    pageSize: 7,
    selectable: true,
    selectionStyle: "ROW_HIGHLIGHT",
    selectionValue: index(local!selectedEmployee, "id", {}),
    selectionSaveInto: {
    /* This save replaces the value of the previously selected item with that of the newly selected item, ensuring only one item can be selected at once.*/
    a!save(
    local!selectedEmployee,
    if(
    length(fv!selectedRows) > 0,
    fv!selectedRows[length(fv!selectedRows)],
    null
    )
    )
    },
    shadeAlternateRows: false,
    rowHeader: 1
    )
    }
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!sectionLayout(
    label: "Leg Details",
    contents: {
    a!richTextDisplayField(
    value: a!richTextItem(
    text: "No employee selected.",
    color: "SECONDARY",
    size: "MEDIUM",
    style: "EMPHASIS"
    ),
    showWhen: isnull(local!selectedEmployee)
    ),
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!textField(
    label: "Name",
    value: local!selectedEmployee.name,
    readOnly: true
    ),
    a!textField(
    label: "Department",
    value: local!selectedEmployee.dept,
    readOnly: true
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Role",
    value: local!selectedEmployee.role,
    readOnly: true
    ),
    a!textField(
    label: "Start Date",
    value: text(local!selectedEmployee.startDate, "MMM dd, yyyy"),
    readOnly: true
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Team",
    value: local!selectedEmployee.team,
    readOnly: true
    ),
    a!textField(
    label: "Available PTO",
    value: local!selectedEmployee.pto & " days",
    readOnly: true
    )
    }
    )
    },
    showWhen: not(isnull(local!selectedEmployee))
    )
    }
    )
    }
    )
    }
    )
    }
    )
    }
    },
    buttons: a!buttonLayout(
    primaryButtons: {
    a!buttonWidget(
    label: "Submit",
    submit: true,
    style: "PRIMARY"
    )
    },
    secondaryButtons: {
    a!buttonWidget(
    label: "Cancel",
    value: true,
    saveInto: ri!cancel,
    submit: true,
    style: "NORMAL",
    validate: false
    )
    },
    showWhen: or(
    isnull(
    ri!readOnly
    ),
    not(
    ri!readOnly
    )
    )
    )
    )

  • 0
    Certified Lead Developer
    in reply to robertd0002

    As a preliminary piece of advice: when entering a comment, use the menu "Insert -> Code" to insert a Code box which will both retain your formatting as well as not making your comment 5 pages long.  You should be able to do this also if you edit an existing comment.  I'll take a glance at your code as soon as I can and see if I can spot anything. 

    Meanwhile it might help you to reduce the case to something absurdly simple and get that working at least - I banged out the following code in the last minute which works just fine for me:

    a!pickerFieldUsers(
      value: ri!selectedUsers,
      saveInto: ri!selectedUsers,
      maxSelections: 3
    )

    and the expected result, which works fine:

  • Thanks for that. Interestingly, the User Picker works when I test it in the designer, just not when I launch the Interface from the process. When I launch the interface from the process, after I select the User, the field is emptied again immediately.

    It seems like some sort of event is clearing out the selection.

    Does that make any sense?

  • 0
    Certified Lead Developer
    in reply to robertd0002

    Shoot, I was actually about to ask you before whether it was only breaking in a process, but I forgot to.

    So, yes this is expected behavior when the Task setup is incomplete.  When saving a variable into a ri! variable in a SAIL form used on a task in a process, the rule input on the User Input Task node MUST map to an ACP (ac!) variable defined in that task.  You might think it would just save a "temporary" copy on the SAIL form without this, but it doesn't.  I'd be pretty surprised if this wasn't the root of your issue.

  • That makes sense. Thanks! I'll read up on the ac! variable and see if I can sort it out.

  • +1
    Certified Lead Developer
    in reply to robertd0002

    It's fairly straightforward luckily - basically you create an input variable on the user input task's Data tab matching the type you need (list of users in your case), then switch over to the "Forms" tab and find the rule input and set it to the newly-created ACP.

  • I tested it out this morning and it works perfectly. Thanks. 

Reply Children
No Data