Dynamic View Header

I have a table called users, containing user_id and name. I have another table called payrates, which has columns user_id (a ref to Users), pay rate and effective date.

From my user_Detail view for a user, I have an inline action to navigate to the payrates table using LINKTOFILTEREDVIEW(“Pay rates table”,[User_ID] = [_THISROW].[User_ID])

My Pay Rates Table view is of type Deck and shows the effective dates and pay rates for that user. In the header for that view, I would like to display the user name. Something like: ANY(SELECT(Users[UserName], [User_ID] = [_THISROW].[User_ID])) However, there is an error which says “Unable to find column ‘_THISROW’” and a warning which says “This formula is not evaluated in the context of a row, so column values are not available.”

Can anyone think of any clever workarounds please?

You cannot display the user in the app’s title bar. The title bar has no awareness of the content in the displayed view.

By “header”, I think you might mean the View Display Name??

I will assume your app is configured such that users are required to be authenticated and you are capturing the User’s email address in your Users table?

If so, then use the USEREMAIL() function. Change your expression to this:

ANY(SELECT(Users[UserName], [User_Email] = USEREMAIL()))

I hope this helps!

3 Likes

Hi - yes, I am referring to the View ‘Display Name;’

Thanks for the suggestion. However, I want to display the name of the user that I have selected from the list of users, not the name of the authenticated user.

I’m wondering if it is possible to somehow save the user name in the user_Detail view, and then recover that name when in the Pay Rates Table view.

1 Like

Oh, I see! First, you are aware on the Detail view that there is a “Header” property on the View? Right?? You can configure that to show the UserName at the top of the View. It would look something like this:

If that is not what you are after and you REALLY want the name to show in the View Display Name, then you will need to “store” the selected User Name.

I typically do this in a Variables table where I would have columns for User(the app user), Name, Value and anything else I want to “remember”. User is so each app user has their OWN Variable row as they are suing the app. In this use case I might set Name = “Selected User” and Value = “John Baer”.

You would then need to create a custom Group action as the Row Selected action (if selecting from a table or deck view). The Group actions would first insert into the Variables table and then a second action would navigate to the view.

Now the Detail View’s Display Name property can use an expression like this:

”Details for “
& ANY(SELECT(Variables[Value],
AND([User] = USEREMAIL(),
[Name] = “Selected User”)))

The only thing to deal with is REMOVING entry made in the Variables table. I would, at a minimum, add the Grouped Actions mentioned above a DELETE action that first removes any previous “Selected User” entries for this app user. You can add DELETE actions elsewhere in the app if the Variables Table row entry interferes with any other functionality you might build.

I assume you again mean to use the Name in the Pay Rate Table View Display Name. You can use the same Variables table. HOWEVER, you need to be able to control HOW an app user navigates to this Pay Rates Table View. Meaning, if you are showing rates only for a specific user based on a prior row selection, then you want to make sure the app user follows a certain flow so they are FORCED to select the user (e.g. they always go through a Table View or Deck View first) and then you can assume the Variables table has the correct Name to use.

I hope this helps!!

1 Like

Thank you. I have got that working now, BUT because the values are stored to the Variables table, there is a one or two second period of time where the incorrect name shows on the view (while the data is being updated in the database).

Is there the concept of storing the value in a Virtual Column (on the assumption that this would be faster)?

There should not be a delay. How have you implemented it? Are you using an action to add to a table inside of the app?

The app operates on a local data copy. It is my understanding, and experience, that any adds should be immediately available on any subsequent expressions.

I have never tried updating a View Display Name in this manner so maybe that behaves different somehow? I’ll give it a try at my end!

My recollection is view display names are handled like virtual columns and are only updated on sync.

1 Like

I just implemented an example in a test app. The Display Name is updating as fast as I can tap back and forth.

In my previous post, if it wasn’t clear, you should be implementing ONLY with actions on the app UI side. You are creating a custom “Row Selected” action Group and replacing the default Row Selected activity in the Table View where you select the row. The action group will 1) Delete any previous “Selected User” entries 2) Add a new “Selected User” entry 3) Navigate to the Detail View

The action is required to control the order of operations to make certain the intended value is there for the View to use.

Update the Detail View(s) Display Name to pull in the current selected user value based on USEREMAIL() and the Name = “Selected Row” to add to the View Header.

Please let us know if there is anything not clear!

2 Likes

Apologies for the delay in responding - I’ve not had a chance to look at this until now.

Here is the detail of my setup…

I have a Users Detail view, allowing the columns of that table to be edited.
One of the columns is a Text column, with an app formula of “Tap Here”
I have created a Group action attached to that column, which executes two actions:

  1. Sets the temp user id in my Params table - Data: add a new row to another table using values from this row.
    The key column is set to “Temp_user_id” and the value column is set to [_THISROW_BEFORE].[User_ID]
    Interestingly, I have noticed that it does not add a new row, it simply updates the existing row.
  2. Navigates to the new view, using LINKTOFILTEREDVIEW (“Newtable”, [User_ID] = [_THISROW].[User_ID]

In the new view the display is set to: ANY(SELECT(Newtable[User Name], [User_ID]=ANY(SELECT(Params[Value], [Key]=“Temp_user_id”))))

It works, but the view initially shows the last value, and takes around three or four seconds to update to the correct value.
I am using Google Sheets as the data source.

Thanks for your help.

I’m not following the flow well. Can you show the details of how you have the flow implemented?

1 Like

I feel I have to ask the obvious question that is being ignored here :grin:

Why don’t you just add the ref field that was created on your user’s table to your User Detail view? That way, their payment rates deck view would display inline automatically for each user you choose? You’d have all the information you needed from both tables…

Did I miss something?

1 Like

Hi both - thanks for your suggestions.

Here is more detail about my app…

I have a table called Users, containing id, name and status. It also contains a List of Related Payrates and a Text column called PayrateLink set to “Tap Here”
I have another table called payrates, containing user id, rate and wef (effective from date). The user id is a ref to the Users table.

I have a view of type deck to show all the users.
When I click on a user, I display the Users_Detail view to show the details for that user.

I have a Group action associated with the PayrateLink field. This carries out two actions:

  1. Assigns the current user to the Params table.
  2. Navigates to the Payrates table view, using LINKTOFILTEREDVIEW(). The Payrates table view is a reference view of type deck, and shows the list of payrates and wef.

The Payrates table view shows the list of payrates and dates, but does not show the user. I would like to display the user in the view header, so that there is no confusion. For example, if a payrate is deleted, it is possible that the wrong rate is deleted, because the user is not displayed.

I have also tried to include the Related Payrates in the Users_Detail view (see screenshot). However, if I click on View, I go to the same Payrates table view as above, which does not show the user name (see second screenshot). I need to be able to delete a rate, and the Payrates table view is currently the only way to do this.

(In this screenshot, the formula for displaying the view header has been deleted).

You can easily add the Delete action for a payrate inline with that payrates data.

On your view that lists the date and payrate, add another column….maybe the id of the record. Then, go to the Actions associated with the Payrates table and find the Delete action. Modify it so that it becomes an Inline action and attach it to the ID column.

Now, a Delete action will appear on each of the payrate lines in your subview.

You could even make the Delete button Show or Hide depending on whether the user was an admin or not if you wanted…

1 Like

I can’t seem to get that to work on my view. Does it work on a deck view?

But in any case, is there a way to stop the user clicking on View in the first screenshot, which would then take them to the view in the second screenshot which does not show the user name?

I think it might be good to get on a video call and walk through this. Is that something you’d be interested in doing? If so, please send me a private message and we can arrange it!!

Thanks for the offer. Let me build a completely cut down demo app that I can share with you so that you can see the exact problem. Will take me a couple of days.

Thanks.

Here is my demo app: AppSheet

If you switch between Alan, Bert and Charlie and tap on ‘tap here to edit payrates’ you will see the delay in the correct name appearing in the view header.

Interestingly, when I tried this in a desktop browser, the display name updated instantly. The problem is only on a mobile app, or in the ‘development version’ of the app (the view of the app in the browser when editing it), that the problem appears.

Thanks for your help.

I’ll send an editor link if you let me know how I can do this privately.

Try using Lookup and end it with the result of [YourKeyColumn]

Apologies - I’m not sure that I understand. Could you elaborate please?