LogoLogo
What's NewDeveloper CommunitySupportStatus
  • 🚀Get Started
    • What is JourneyApps Platform?
    • Tutorial: Build your First App
      • 1. Introduction
      • 2. Create a new App
      • 3. OXIDE IDE Overview
      • 4. Hello World app
      • 5. The Data Model
      • 6. View Components
      • 7. Queries and Data Sync
      • 8. Simple Navigation
      • 9. View Stack
      • 10. Input Validation
      • 11. View Parameters
      • 12. Data Manipulation
      • 13. Responsive Apps
      • 14. Styling
      • 15. Lists
      • 16. GPS Capturing
      • 17. Relationships
      • 18. Multiple User Roles
      • 19. Deployment and Users
      • 20. Version Control
      • 21. CSV and APIs
      • 22. Conclusion
    • JourneyApps Platform Fundamentals
      • Creating a New App
        • Git-enabled Apps
      • What are Views?
      • What is the Data Model?
      • JourneyApps Syntax Basics
      • Access the Database (DB)
        • Manipulate DB Objects
        • Query DB Objects
      • View Navigation
        • Deep Linking
      • CloudCode Overview
      • OXIDE (Online IDE)
  • 💻Build your App
    • JourneyApps Syntax
      • Syntax Basics
      • Access the DB
      • View Navigation
      • Async & Await
      • TypeScript Apps (Beta)
        • runtime-build package
        • TypeScript App Troubleshooting
      • What's New in V4
        • Updating to the V4 API
    • Configure your Data Model
      • What is the data model?
      • Reference: model
        • field
        • belongs-to
        • has-many
        • index
      • Data Rules
        • Data Buckets
        • Sync Rules - Limit data synced to devices
        • Data ACLs - Limit access to data
        • Real-world example for Data Rules
        • ❔FAQs
        • Migrate to Data Rules
      • App Indexes
      • Webhooks
    • UI Components
      • All UI Components
        • actionSheet
        • Attachments
        • button
        • button-group
        • capture-coordinates
          • marker
          • marker-query
        • capture-file
        • capture-photo
        • capture-signature
        • card
          • accent
          • action
        • columns
          • column
        • component
        • context-menu
          • divider
          • item
        • CSV
        • date-input
        • datetime-input
        • dialog
          • body
        • display-3d-model
          • 📖display-3d-model Guides
            • Guide 1: Initialize and layout a 3D model in a view
            • Guide 2: Control playback position
            • Guide 3: Troubleshooting controls
        • display-coordinates
        • display-file
        • display-image
        • display-photo
        • display-signature
        • heading
        • html
          • HTML Advanced Topics
          • ❔HTML FAQs
          • 📖Guide: HTML & JourneyApps iFrame Client
        • icons
        • info
        • info-table
          • row
        • journey.photos (capture multiple photos)
        • JourneyPrinter (print PDFs)
        • grid
          • cell
          • 📖grid Examples
        • list
          • list-item
            • accent
            • asset
            • pills
              • pill
            • action
        • multiple-choice-checklist
        • navigation (Navigation drawer)
          • general-section
            • item
          • section
            • item
              • item
          • ❔navigation FAQs
        • notification
        • object-dropdown
        • object-list
          • action
        • object-repeat
        • object-table
          • action
          • column
            • action
            • edit-boolean
            • edit-date
            • edit-datetime
            • edit-integer
            • edit-number
            • edit-select
            • edit-text
            • edit-time
            • edit-typeahead
              • action
            • header-action
          • column-group
          • empty-action
          • 📖object-table Guides
            • Actions
            • Cell callouts
            • Column groups
            • Columns
            • Controlled object-table
            • Controls
            • Copy & paste data
            • Edit cells
            • Filters
            • Frozen columns
            • Fullscreen object-table
            • Mode
            • State
            • Styles
        • optionList
        • PhotonSync (transfer data offline)
        • power-bi
          • 📖Guide: PowerBI Embedding
        • scan-barcode
        • shortcut
        • sidebar
        • single-choice-dropdown
        • single-choice-radio
        • template
        • text-input
        • time-input
        • toggle
        • view
      • JS/TS Events
      • Show / Hide UI Components
      • View Templates
      • XML Fields (Attributes)
        • align-content
        • align-controls
        • align-label
        • bind
        • clear-button-visibility
        • control-order
        • disabled
        • error-message
        • icon-position
        • id
        • hide-if
        • modifier-text
        • label
        • label-case
        • label-color
        • on-change
        • on-press
        • placeholder
        • required
        • show-if
    • JS / TS APIs
      • Attachment
      • Bluetooth (Beta)
      • Broadcast
      • component
      • CSV
      • DB
      • HardwareBarcode
      • journey
        • journey.config
        • journey.container
        • journey.device
        • journey.diagnostics
        • journey.dialog
        • journey.files
        • journey.hardware
        • journey.photos
        • journey.runtime
        • journey.sensors
        • journey.viewStack
      • JourneyPrinter
      • KeyboardBarcode
      • LocalDB
      • NFC
      • OnlineDB
      • PhotonSync
      • SerialPort
      • ShortcutManager
      • TCPSocket
      • user
    • Extend your App with Custom Code
      • App packages
        • App packages overview
        • PDF report package
        • TypeScript library & unit tests
        • Manage External Dependencies
      • Custom HTML
    • Style & Customize your App
      • Style & configure UI components
        • Overview
        • Understand extendable themes
        • Use themes on a view
        • Theme specific components on a view
        • Examples
        • Debugging
        • ❔FAQs
      • Change your App Font
      • Custom Branding
        • Custom Container Features
        • Special Requirements for iOS Containers
    • Integrate your App
      • Backend integrations with CloudCode
      • Barcode Scanning
        • Barcode Scanning using Keyboard Emulation
        • Hardware Barcode Scanning
        • scan-barcode
      • Bluetooth Low Energy (BLE)
      • Broadcast API
      • HTTP requests (Fetch API)
      • JourneyApps Print (Android)
      • Maps and navigation
      • NFC
      • Opening external links/apps
      • Serial Port
      • TCP Sockets
    • Design Intuitive Apps
      • UX Guidelines
      • Write Effective Copy
  • 📱App Features
    • RealWear® Voice Control
      • Automatic Voice Commands
        • Automatic Voice Commands - Advanced
      • Manual Voice Commands
    • App, Runtime and Container Updates
    • Batch Operations (App)
    • Call JS/TS Functions from XML
    • Capture GPS Locations
    • Push Notifications
    • Translations
    • XML Format Strings
    • Webhooks (External)
  • 🌐CloudCode
    • CloudCode Overview
    • Trigger a CloudCode Task
      • Trigger CC with a Schedule
      • Trigger CC via a Webhook
      • Trigger CC from an App
      • Trigger CC from Another Task
      • Trigger CC via HTTP
    • Attachments in CloudCode
    • Timezones
    • Advanced CloudCode Topics
      • Access Multiple DBs in CloudCode Tasks
      • Batch API (CloudCode)
      • CloudCode Dependencies
      • Configure HTTPS in CloudCode
      • Deployment environment variables
      • Local CloudCode Development
      • PDF Reports using CloudCode
      • Shared CloudCode Tasks
      • Translations in CloudCode
  • 📥Backend API
    • Introduction
    • API Reference
      • Retrieve All Objects
      • Query Objects
      • Sort Results
      • Limit and Skip
      • Count Objects
      • Create a New Object
      • Retrieve a Single Object
      • Update a Single Object
      • Delete a Single Object
      • Batch Operations (v4 API)
      • Oplog API
      • Retrieve the App Data Model
      • Manage App Users and Sessions
      • Field Representation
      • Error Responses
    • API Limits
    • Update to the V4 API
  • ⚙️Technical
    • Data Synchronization Priority
    • Device Diagnostics
    • JSON1 Query Engine
    • Improve App Performance
    • Security Measures
    • Supported Platforms
      • Web Container
      • Windows Installer
    • Domain Whitelist
  • 🖥️OXIDE
    • Get started with OXIDE
      • OXIDE Overview
      • Components of OXIDE
    • Configure Testing Deployments
    • Edit and Manage Files
      • How to Navigate to a Function
      • Manage External Dependencies
    • Create and Manage App Containers
    • Debugging & Troubleshooting
      • Common Troubleshooting Pointers
      • App Diagnostics Reports
      • Build Logs
    • OXIDE Workspaces
      • OXIDE Trees
  • ❕Deprecated Features
    • Deprecated Features and Components
Powered by GitBook
On this page

Last updated 2 years ago

In this section we will complete our "Hello World" app and test it on a device.

An App Consists of a Data Model and Views

As you've seen in the page, building an app on JourneyApps involves the customization of two kinds of things:

  • : This describes the data that your app makes use of (in more technical terms: object models with their fields and relationships)

  • : This defines the layout and logic for the actual screens in your mobile app.

You will also have learned that customizing these two things are done using straightforward XML and JS.

In your Hello World app that you just created, you can access the Data Model and Views from the corresponding workspace in the Workspace Tabs.

Click on the Views workspace in the Workspace Tabs to access the views for your Hello World app. You should see something like this.

On the left of your screen you can see a Views panel listing all the views for your app. By default each app will have two views to begin with, one called "main" and one called "nav". The "main" view is the very first view that is rendered when the app is loaded, and the "nav" view is used to manage more advanced navigation (something for a later topic).

Each view is divided into two separate files, a .xml file, which is used to describe the layout of the view, and a .js file, which is used to describe the business logic for the view. By default, when you open a view to edit it both of these files will be opened for you, the xml in the left editor pane and the js in the right editor pane. This can be seen in the image above for the "main" view. OXIDE has opened the xml in the left editor pane and the js in the right editor pane.

Adding Components to Views

Let's go ahead and add some basic details to our Hello World app. For now we are just going to add some basic components, and we will add them to our "main" view. So, make sure you are on the "Views" workspace (to get here simply click on Views in the Workspace Tabs), then make sure you are on the "main" view (to do this select the "main" view from the Views panel on the left of the workspace).

We are going to add a heading and an info component to our "main" view xml to get us started.

In the "main" view xml, add a new line after <!-- Components go here: --> section, then type head and you should see something like this ...

What you see beneath your cursor is OXIDE's Auto-Complete functionality trying to help you. Hit return/enter to insert the highlighted auto-complete suggestion (in this case there was just one option). Now your code should look something like this ...

You will see that OXIDE has inserted the opening and closing tags for your heading component for you. All that is left to do is populate it with some text. Let's add the text 'Hello World' to the inside of the heading component. Now your code should look like this ...

Excellent, now let's do the same for an info component. We are going to add the component underneath the heading component, we are going to use auto-complete to let OXIDE insert the xml tags for us, and once it is there we are going to populate it with some text, in this case the text 'This is my first app'.

So, start by typing inf, then use your arrow keys to highlight the info component in the auto-complete suggestions, not the info-table component. Once the suggestion is highlighted hit return/enter, and finally add the text 'This is my first app' inside of the info component. Now your code should look like this ...

Great, now let's test your app to see what it looks like.

Testing Your App: Link a Mobile Device or Test on Desktop

An important concept in JourneyApps is that you should test your app continuously while you are building it. Therefore, immediately go to the Test app action (bottom right corner of OXIDE) of your Hello World app and follow the instructions to either:

  • Install the JourneyApps Container from the Play Store (Android) or App Store (iOS) and link your Hello World app to a mobile device.

The very first time you run 'Test app' you will be prompted to create a new app user, this is normal as no app user would exist for you yet. Simply hit continue and then you will be presented with instructions on how to test your app.

And if you are also following along on your mobile device, it should look something like this ...

Add an Input Component

Now let's make the app a bit more interactive by adding an input component. We want to complete our Hello World app by making it ask the user to enter their name, and then have a button that will make the app display a greeting when it is pressed.

In a full-blown JourneyApps application, we would use the Data Model as we'll show you later, but for now, to keep things really simple, we'll simply use a local variable to store user input. To add a local variable, type var on a new line under the <!-- Variables go here: --> section in your View XML and hit return/enter to auto-complete as usual.

We want to ask the user to enter their name, so type something like your_name for the name property, and then text for the type property. text indicates that we'll be storing text in this variable (we'll show you all the different data types later.)

Important: Note that the order in which you insert XML is important — we will cover each of these in more details later, but your XML needs to be specified in the following order: parameters, variables, components. If you see an error message such as "Elements must be in this order: parameters, variables, components" or "This element is not expected" , it means that something has been inserted in the incorrect order in the XML.

Next, we need to provide a way for the user to give us their input. In this case we just want to capture some text and so a text-input component will work well. We want to add a text-input component underneath the existing info component in the xml. So, add a new line after the info component and type text, highlight the text-input auto-complete suggestion and hit return/enter to insert the component.

By default the text-input component has a bind attribute and a required attribute, but we can specify some additional attributes as well. For now, just add a label attribute to the text-input component. The bind attribute tells the view where to store the input that the end users will enter into the component. bind needs to be set to a variable that is declared in the view. The label attribute is used to display a text label above the text-input component. Let's set the bind attribute to the name of the variable we declared, your_name, and the label attribute to 'Please enter your name'. Now your code should look like this ...

And your app should look like the this ...

Add a Button and Hook It Up With JavaScript

Finally, we are going to add a button, but this time we are going to use the visual editor. Open the command palette (ctrl+shift+p / cmd+shift+p), then type design and select the Open view in designer action. When prompted to select a View Model, choose the 'main' view. The visual editor should now be open.

Now, to add a new component using the visual editor, simply click on the + underneath the visualization of the text-input component, select the button component from the list, enter 'Press Me' as the Button Label when prompted and then hit 'Continue'.

Once added, go back to your main view xml by clicking on 'main' view in the View Panel on the left, this will open the main view xml in the left editor pane and the main view js in the right editor pane. Once there, you should see this, the visual editor has added a button component for you in the xml and also populated some of the xml attributes of the button component. You may have also noticed that the visual editor has created a new js function for you ...

Next up, let's add the necessary js code to return a dialog once the user presses our button. We are going to use a simple dialog JS component, and this component takes a string as an argument. Update your JS function to the following ...

All right, let's test it out! Open your app (either desktop or mobile), and see that it now looks and works like this ...

Hello World DONE!

Excellent, you have successfully completed your first JourneyApps 'Hello World' app. Below you will find the reference code for the 'main' view xml and js of this 'Hello World' app. If your app is not working like ours, or you broke it and cannot seem to fix it, simply copy and paste both the xml and the js over to your app and then try again.

Automatic Saving, Deployment & Testing on Mobile Device

Note that whenever you type something into OXIDE, it will automatically be saved. There is no need to save anything explicitly. Furthermore, you may have noticed that every time you make a change, there is a Deployment process that gets kicked off, indicated by the progress bar that appears over the Footer. This is the OXIDE auto-deploy feature and is enabled by default. You can also trigger a deployment manually by hitting ctrl+s / cmd+s (Note you can turn off the auto-deploy feature from the command palette, ctr+shift+p / cmd+shift+p. This is often useful if you have a poor internet connection or when you are working on large blocks of code at a time. If you do turn it off, just remember to hit ctrl+s / cmd+s to manually deploy your code before trying to test it).

Download and install the for Windows or MacOS and test the app on Desktop.

Ensure that you have downloaded and installed the for Desktop before proceeding. Once installed, click on the 'Or test on desktop' button in the Test app action (bottom right corner of OXIDE). If all went well the JourneyApps Container for desktop should launch and look something like this ...

This means that your app is automatically being deployed to the Testing Environment (recall the page) Your app will try to refresh itself automatically on the mobile or desktop device so that you can see the changes you're making (if it doesn't, press the "sync" button at the top right corner of the app).

What Kind of Device? All the applications that you develop on JourneyApps will work on iOS, Android, Windows, MacOS and Web right out of the box, without any additional development required. The applications are also responsive right out of the box, which means you can use the application on any form factor, phone, tablet, laptop and desktop. Write once, run everywhere. A list of supported platforms and minimum operating system version can be found .

Container App + Over-the-Air Customizations: As you've seen in the page, the JourneyApps Container that you install on your mobile or desktop device is simply an empty generic container. Once you link your device to an app, your app customizations are deployed to it over-the-air, and your app is dynamically rendered. This means that deploying new versions of your app to users is extremely easy and happens in an automated way.

<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->

    <!-- Component go here: -->
    <heading>Hello World</heading>
</view>
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

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

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

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

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="your_name" type="text" />
    
    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
    <text-input label="Please enter your name" bind="your_name" required="false" />

</view>
function buttonPress() {
    // TODO implement
    dialog("Hello there, " + view.your_name);
}
main.xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

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

    <!-- Component go here: -->
    <heading show-if="true" hide-if="false">Hello World</heading>
    <info>This is my first app</info>
    <text-input label="Please enter your name" bind="your_name" required="false" show-if="true" hide-if="false" />
    <button on-press="$:buttonPress()" label="Press Me" />

</view>
main.js
// 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
}

// 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 buttonPress() {
    // TODO implement
    dialog("Hello there, " + view.your_name);
}
  1. 🚀Get Started
  2. Tutorial: Build your First App

4. Hello World app

Previous3. OXIDE IDE OverviewNext5. The Data Model
  • An App Consists of a Data Model and Views
  • Adding Components to Views
  • Testing Your App: Link a Mobile Device or Test on Desktop
  • Add an Input Component
  • Add a Button and Hook It Up With JavaScript
  • Hello World DONE!
  • Automatic Saving, Deployment & Testing on Mobile Device
JourneyApps Container
JourneyApps Container
here
What is JourneyApps?
What is JourneyApps?
Data Model
Views
Environments and Staged Deployment section on the What is JourneyApps?