Navigation and Context in Siena

In Siena, to navigate from Screen1 to Screen2, you need to add a button to Screen1, touch the OnSelect property of the button and select Screen2. this automatically adds a function: Navigate(Screen2, ScreenTransition!Fade).

But, sometimes more sophisticated navigation is needed:

  • Always navigate from Screen1 to Screen2, but show different things on Screen2, depending on what the user has done on Screen1
  • Navigate from Screen1 to Screen2 or Screen3 or Screen4, depending on some condition

This kind of navigation becomes really easy once you use the concept of "context" in Siena.

Let’s consider the two screen app below. Screen1 has three images of device form factor, the user selects one of them and navigates to Screen2 that shows just the selected types of devices. The data in this example comes from a table named Machines which has 3 columns: Name, Price and FormFactor.

This interesting navigation works by using the optional context parameter of the Navigate function. These are the steps (using the tablet's image as an example):

  • Select the tablet's image and add navigation to Screen2
  • Now edit the automatically added Navigation expression to add context, so the expression becomes: Navigate(Screen2, ScreenTransition!Fade, {DeviceType:”Tablet”} )

A context is defined using a record. The syntax of a record starts with an opening curly bracket followed by a comma-separated list of key/value pairs and it finishes with a closing curly bracket. For example: {DeviceType:”Laptop”, Brand:”Microsoft”, SelectionIndex:0}).

Let’s repeat the same operation for the two other images while changing the value of DeviceType:

  • Navigate(Sreen2, ScreenTransition!Fade, {DeviceType: "AllInOne"} )
  • Navigate(Screen2, ScreenTransition!Fade, {DeviceType: "Laptop"} )

Screen2 can now reference the context named DeviceType. So, the gallery showing the devices can be filtered using the following expression:

  • Filter(Machines, FormFactor = DeviceType)

And, that's it!

Let's next look at another navigation pattern. In the app below, there are three screens altogether. The user can browse through a catalog of dresses on the DressScreen, and shoes on the ShoeScreen.

There is a single DetailScreen that shows details of the selected item. The interesting part is that the DetailScreen needs to know what to show, i.e. did the user navigate from dresses or shoes.

In this example, the data is coming from a single table named Clothes that contains 3 columns: Name, Description, Price and ImageUrl.

To achieve this, the DressScreen and ShoeScreen pass the selected item to the DetailScreen via the context. Here is the expression for the OnSelect behavior of the DressScreen's gallery:

  • Navigate(DetailScreen, ScreenTransition!Fade, {DetailItem: ThisItem} )

A similar expression is needed for navigating from the ShoeScreen's gallery.

The DetailScreen shows the information for DetailItem, e.g. DetailItem!ImageUrl or DetailedItem!Description.

So, just by passing the selected item in the context during navigate, you only need one screen to show product details, no matter how many different product selection screens.

Conditional Navigation

Anytime you have a navigation expression, you can add conditions. Let’s imagine a 3 screen app. The user should navigate to Screen2 with a fade transition if the value of a slider is greater than 50, otherwise navigate to screen3 with a cover transition. To get this effect, add a slider and a button to Screen1, and set the OnSelect property of the button to the following:

  • If(Slider1!Value>50, Navigate(Screen2, ScreenTransition!Fade), Navigate(Screen3, ScreenTransition!Cover))