# 9. View Stack

To complete our "Add New Item" screen, we want to add a button that saves the item and takes the user back to the **main** view. Before we do that, a word about the **View Stack** in JourneyApps:

### The View Stack

Imagine that each view on the mobile device is a sheet of paper. For each view that the user opens (by executing a `navigate.link()` action), a sheet is added on top of the others. Together the sheets are known as the **View Stack**. Only the top sheet of the stack is ever displayed to the user. Whenever the user goes back (by executing a `dismiss` or `discard` action, or by using the built in back button), it would be as if the top sheet is removed and the user sees the sheet that was underneath it.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-7ccd8882d644339aa1c8a4ce5b7d22905a391aaf%2Fview-stack-explanation.png?alt=media)

For instance, if the user has the *Main View* open and then goes to the *Add New Item* view in our punch List app, there will be two views on the stack: the *Main View* at the bottom and *Add New Item* on top of it.

### Dismissing, Discarding & The Back Button

When a user goes back to a previous screen in the View Stack, this is referred to as **Dismissing** or **Discarding** the current view and is done programmatically by invoking the `dismiss` or `discard` *navigation* actions. A user can also press the back button (built-in on Android devices, or in the title bar on iOS devices and on Desktop) to go back to the previous view in the stack.

So, what's the difference? The difference is that the `dismiss` action will automatically save and persist any unsaved changes that have been made to view variables to the database, whereas the `discard` action and using *the back button* will discard those same unsaved changes. Note that changes made to *JS variables* always need to be saved explicitly and will not be included in the automatic save of the `dismiss` action.

We'll now make use of these concepts in the "Add New Item" view of our punch List app — when the user presses a button to save the new item, we need to go back to the Main View.

### Finish Up "Add New Item"

We have added the `input-components` that will allow our users to capture the information about the new punch list item, but now we need to give them a way to save the new item and go back to the previous view. To do this we will add a button and hook it up with a **JS** function.

So, in your `add_new.view.xml` file, underneath the `text-input` component, add a standard `button`, give it a label, like "Save Item", and point it to a **JS** function called `saveItem`. Like so ...

```xml
<!-- Variables go here: -->
<var name="item" type="item" />

<!-- Components go here: -->
<capture-photo bind="item.photo" required="false" />
<text-input bind="item.comments" required="false" />

<button label="Save Item" on-press="saveItem" validate="false" style="solid" />
```

Now, in your `add_new.js` file you need to define the `saveItem` function. We want this function to save the unsaved changes (save the data that the user has entered) and then take us back to the `main` view. Broadly speaking you have 2 options.

**Option 1** Use a `dismiss` action which will automatically persist and save the unsaved changes you have made to the view variables on the view in question and then remove the current view from the stack (taking us back to the previous view - the main). In our case, that would save changes you have made to your `view.item` object. The function will look like this.

```javascript
function saveItem() {
    dismiss(); // This will save unsaved changed to view variables and remove the current view from the stack
}
```

**Option 2** Explicitly save the unsaved changes and then use a `discard` action to remove the current view from the stack. In our case, that means we need to save changes to the `view.item` object. The function will look like this.

```javascript
function saveItem() {
    view.item.save();
    discard(); // This will will discard unsaved changes and remove the current view from the stack
}
```

At this point, your code for the *Add New Item* view should like this.

**XML**

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Add New Punch List Item">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="item" type="item" />

    <!-- Components go here: -->
    <capture-photo bind="item.photo" required="false" />
    <text-input bind="item.comments" required="false" />

    <button label="Save Item" on-press="saveItem" validate="false" style="solid" />
</view>
```

**JavaScript (Option 1)**

```javascript
// This function is called when the app navigates to this view (using a link)
function init() {
    // initialize any data here that should be available when the view is shown
    view.item = DB.item.create();
    view.item.status = "Open";
}

// This function is called when the user returns to this view from another view
function resume(from) {
    // from.back       (true/false) if true, the user pressed the "Back" button to return to this view
    // from.dismissed  (true/false) if true, the app dismissed to return to this view
    // from.path       contains the path of the view that the user returned from
    // if any data needs to be refreshed when the user returns to this view, you can do that here:
}

function saveItem() {
    dismiss(); // This will save unsaved changed to view variables and remove the current view from the stack
}
```

**JavaScript (Option 2)**

```javascript
// This function is called when the app navigates to this view (using a link)
function init() {
    // initialize any data here that should be available when the view is shown
    view.item = DB.item.create();
    view.item.status = "Open";
}

// This function is called when the user returns to this view from another view
function resume(from) {
    // from.back       (true/false) if true, the user pressed the "Back" button to return to this view
    // from.dismissed  (true/false) if true, the app dismissed to return to this view
    // from.path       contains the path of the view that the user returned from
    // if any data needs to be refreshed when the user returns to this view, you can do that here:
}

function saveItem() {
    view.item.save();
    discard(); // This will will discard unsaved changes and remove the current view from the stack
}
```

### Test the App on Device

Let's test our app and see that it works as expected.

Firstly, you should see your "Add New Item" button that's been added to the Main View. Clicking on it will take the user to the "Add New Item" screen where you can capture a new punch item.

Note: If your app has not updated on one or more of your devices, ensure you have a network connection and hit the `Sync` spinner button at the top right corner of the app and wait for the *Application updated* banner/message to appear on your screen.

Once you've saved the item, you're taken back to the Main View where your new item now appears in the list:

{% tabs %}
{% tab title="Desktop" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-c8d92b4d6f7fe0b6a719f9ac1f76d71b59a7197e%2Fdesktop-pl-add-new-item.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-f8b1860d13696f59c112cf5cd507d588bf2d4ea1%2Fdesktop-pl-main-button.png?alt=media)
{% endtab %}

{% tab title="Mobile" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-d0d6e0663b56376e89e6e7f6a167270e605015b5%2Fmobile-pl-add-new-item.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-939d8e4d4bea84781f58883612533449ff0483d5%2Fmobile-pl-main-button.png?alt=media)
{% endtab %}
{% endtabs %}

### View the Data in the Cloud

Let's go and look at the data we just created in the Cloud. To get there we need to go to our *data browser* for our app, which can be accessed from the Data Browser shortcut in OXIDE next to our Workspaces Tabs. Once opened, view your Items table and you'll see that your newly added item(s) was synchronized from the device to the cloud, and it happened automatically in the background:

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-3be71d7513196701a0fb12b298354b441476251d%2Foxide-pl-databrowser-highlight.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-aefcc4705fca5d5ba343401ed7f7d0a871a22d40%2Fbackend-items-synced.png?alt=media)

### Advanced Navigation

In the last two sections we covered the basics of *simple navigation* in JourneyApps. It can be summed up by saying you use `link` actions to navigate *forwards* to other views, and you use `discard` or `dismiss` actions to navigate backwards to previous views.

JourneyApps also supports more advanced methods of navigation and provides you with all the tools you need to actively manage how your users navigate through your application. For more details on *simple* and *advanced* navigation as well understanding more about the *view stack*, it is recommend that you read the [View Navigation](https://docs.journeyapps.com/reference/get-started/journeyapps-fundamentals/view-navigation) and [View Stack](https://docs.journeyapps.com/reference/build/js-ts-apis/journey/viewstack) documentation.
