cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
mr-dang
Level 10

Interactive Tour: How did you do it?

Following up with @Audrie-MSFT ATTN: Ian Smiley Happy

There's an interactive tour of PowerApps available in the learn section of web.powerapps.com:

https://aka.ms/kskkr9

 

I like it a lot and I'm interested in building apps that teach how to make PowerApps. Can you share how it was made?

 

 

powerapps interactive tour.png

 

powerapps guided tour.png

 

 

 

Microsoft Employee
@8bitclassroom
1 ACCEPTED SOLUTION

Accepted Solutions
PowerApps Staff C_Ian_Davis
PowerApps Staff

Re: Interactive Tour: How did you do it?

Hi mr-dang:

 

Been trying to think of the best way to answer this, trying to be both succinct AND giving you something you can actually tear into in your own apps. I think the best way to tackle this is by first providing definitions to key variables / collections in the app, then giving a big picture overview and then tackling some of the more functional pieces of the app. So without further ado:

 

Key Variables: 

  • UserProgress, number: THE variable which the core functionality of the app is based around. Increments approximately every time a user completes an actionable event (AKA completing the task defined in the wizard/helper at the bottom)
  • ControlSelectedrecord: defines the name (Label1) & type (Label) of control on the mock canvas the user has currently selected. This drives the logic for setting the control name on the right-hand property pane, as well as the drag handle location, and which item is highlighted in the left-hand control tree view. It is set whether the user selects the control on the mock canvas or on the mock control tree.
  • GallLayoutnumber: 0 or 1, binds the gallery controls to a particular layout. If user selects "Image, title, and subtitle", GallLayout is set to 0 (default), if they select "Title, subtitle and body", it's set to 1. The X, Y, Width, Height, and Visibility properties of the gallery controls are all bound to this variable
  • GallTitleText, text: Defines what field the gallery title is pointing to in the collection it's using as its datasource 
  • GallSubtText, textDefines what field the gallery subtitle is pointing to in the collection it's using as its datasource
  • GallBodyText, text: Defines what field the gallery body is pointing to in the collection it's using as its datasource
  • GallScreenName & FormScreenNametext: Unlike all the other controls, when the user selects the screens on the mock canvas, the name field in ControlSelected is updated to whatever these variables are set to. Before the user names the screens, these default to Screen1 & Screen 2 respectively. Afterwards, it's whatever the user likes.
  • SubMenuSelect, text: Throughout the app, there's a few examples of menus the user navigates through (Ex: selecting a data source, selecting a new screen). In order to keep track of which menu should be visible, this variable is set to the corresponding text term every time a user clicks on a particular sub menu. It is cleared when the user clicks anywhere in the canvas (if it's empty, no sub menu is shown).
  • FormLayout, number: similar to GallLayout, binds the form control to a particular layout.
  • DetailName, text: defines what the form should display after the user has navigated to it from the gallery screen. If they select an item in the gallery, DetailName is set to an identifier for that row of the collection. The form then pulls that row and displays all its info in the proper cards and will update that row instead of creating a new one. If they select the '+' icon, DetailName is set to "New" and the form creates a new entry in the collection

Key Collection (fields defined in nested bullet):

  • TimeOffTable: The collection used to mock the excel data source
    • Employee, StartDate, EndDate, etc
    • SampleHeading, SampleText (was easier to just keep these in the same collection as the user-generated data)
  • Tutorial - embedded excel table: The table which stores all the text for the tutorial
    • TutText, ProgUser (identical to UserProgress, used to do a lookup so the right text is displayed at the right time)
  • GalleryScreenTree: The gallery screen's tree view is overlaid with a gallery whose Items property points to this collection
    • ControlType, ControlName --> similar to ControlSelected, the Fill property is bound to a LookUp which compares ControlSelected.Name to ControlSelected and changes the fill accordingly to indicate the control is selected/not
    • ActionHighlight: at what UserProgress the row needs to be highlighted to indicate the next step in the tutorial (quite often empty)
  • NavColors: Defines the potential nav colors the user can change the RectQuickActionBar to in that portion of the tutorial

Summary:

As stated above, everything falls out of the UserProgress variable. The app itself is mostly just condensed screen shots of the studio whose Visibility, X, Y, Width, and Height properties are bound to the value of UserProgress. All menus are just screenshots overlaid with textboxes to mimic the hover / select effects you get in the editor. The app is completely linear. If you imagine UserProgress as a decision tree, that tree is, well, a straight line... This linearity saves A LOT of headaches because there are no branching decisions which need to converge appropriately down the line. If there's wiggle room for user exploration, those pieces are generally unbounded from UserProgress and thus don't overcomplicate the app.

 

Points of Interactivity: Intro + Connect to Data + Browse Requests:

 

  1. Left Control tree
    1. Screenshot with a gallery overlaid. Gallery has data source GalleryScreenTree. A single textbox control inside the gallery, with it's OnHover property set to a slightly opaque dark grey, and its OnSelect property updating the ControlSelected variable accordingly. Its fill property is logically bound to the ControlSelected variable, something like: If (ControlSelected.Name == ThisItem.ControlName, Grey, NoFill)
  2. Center Gallery (on canvas)
    1. Datasource: TimeOffTable (always)
    2. Text controls Text property (title as example): If (UserProgress < some#, point to SampleTitle, point to whatever field matches GallTitleText).
    3. Layout: X,Y, Visibility properties of controls internal to the gallery are bound to GallLayout, itself set by the user clicking on the layout menu and selecting from the two options.
    4. Body1, Subtitle1, Image1/Title1 dropdowns: The OnChange property for these sets their respective variables which are what the gallery text controls reference to display the proper field from TimeOffTable 

Points of Interactivity: View Requests

  1. Screen Naming
    1. Just text input fields overlaid ontop of the screenshot of the left hand tree view. Their OnChange events set GallScreenName & FormScreenName to whatever the user typed
  2. Checking fields
    1. The fields are pretty lame, just a gallery of checkboxes. This part isn't true to the editor (and could've been done better with a smarter gallery which ordered its items on whether a box was checked) but gets the point across to new users
  3. Form interaction:
    1. The form is a form control, with custom cards pointing to the TimeOffTable. 
    2. The X & Y properties of the DataCardKeys and Values are bound to FormLayout which has them change accordingly depending on what layout the user selected
    3.  Same idea as #2 for the SnapToColumns feature, but this time it's the DataCard X, Y, Width, properties that are bound to a variable's value
  4. Formula Bar: focusing on the OnChange property of this guy since it's the most interactive property
    1. OnChange: several If checks which are looking for two things:
      1. Is UserProgress a value such that the user needs to input a formula? and 
      2. Is what they input equal to what should be there?
      3. If both of these evaluate to try when the user hits Enter, then UserProgress is incremented and they move on
  5. Navigate Icon (back to gallery screen): setting it's OnSelect property
    1. Before a certain UserProgress (the point where the user sets the action), OnSelect is set to false, otherwise (after they've gone thru the tutorial to set the OnSelect to do something), it's set to do two things:
      1. navigate to the form screen
      2. set DetailName to a unique identifier to that row of the data source, so the form displays the proper row's info

 

Points of Interactivity: Create Requests

  1. Adding a new 'time off request' to the data source
    1. This is pretty much defined in the variables section where I discuss what DetailName does, but the '+' icon's OnSelect property sets DetailName to "new" 
      1. The checkbox creates a new record in TimeOffTable with DetailName set to "new"
  2. Editing an old 'time off request'
    1. Same idea as above, but now DetailName is set to a row in the data source, so the checkbox's OnSelect property follows the update record flow instead of the above

Sharing apps: pretty much just screen shots whose visibility changes depending on UserProgress. Nothing interesting.

 

...That ended up being quite verbose but hopefully it helps. If there's something specific you want me to hit on more, feel free to let me know.

 

 

  

5 REPLIES 5
PowerApps Staff C_Ian_Davis
PowerApps Staff

Re: Interactive Tour: How did you do it?

Hi mr-dang:

 

Been trying to think of the best way to answer this, trying to be both succinct AND giving you something you can actually tear into in your own apps. I think the best way to tackle this is by first providing definitions to key variables / collections in the app, then giving a big picture overview and then tackling some of the more functional pieces of the app. So without further ado:

 

Key Variables: 

  • UserProgress, number: THE variable which the core functionality of the app is based around. Increments approximately every time a user completes an actionable event (AKA completing the task defined in the wizard/helper at the bottom)
  • ControlSelectedrecord: defines the name (Label1) & type (Label) of control on the mock canvas the user has currently selected. This drives the logic for setting the control name on the right-hand property pane, as well as the drag handle location, and which item is highlighted in the left-hand control tree view. It is set whether the user selects the control on the mock canvas or on the mock control tree.
  • GallLayoutnumber: 0 or 1, binds the gallery controls to a particular layout. If user selects "Image, title, and subtitle", GallLayout is set to 0 (default), if they select "Title, subtitle and body", it's set to 1. The X, Y, Width, Height, and Visibility properties of the gallery controls are all bound to this variable
  • GallTitleText, text: Defines what field the gallery title is pointing to in the collection it's using as its datasource 
  • GallSubtText, textDefines what field the gallery subtitle is pointing to in the collection it's using as its datasource
  • GallBodyText, text: Defines what field the gallery body is pointing to in the collection it's using as its datasource
  • GallScreenName & FormScreenNametext: Unlike all the other controls, when the user selects the screens on the mock canvas, the name field in ControlSelected is updated to whatever these variables are set to. Before the user names the screens, these default to Screen1 & Screen 2 respectively. Afterwards, it's whatever the user likes.
  • SubMenuSelect, text: Throughout the app, there's a few examples of menus the user navigates through (Ex: selecting a data source, selecting a new screen). In order to keep track of which menu should be visible, this variable is set to the corresponding text term every time a user clicks on a particular sub menu. It is cleared when the user clicks anywhere in the canvas (if it's empty, no sub menu is shown).
  • FormLayout, number: similar to GallLayout, binds the form control to a particular layout.
  • DetailName, text: defines what the form should display after the user has navigated to it from the gallery screen. If they select an item in the gallery, DetailName is set to an identifier for that row of the collection. The form then pulls that row and displays all its info in the proper cards and will update that row instead of creating a new one. If they select the '+' icon, DetailName is set to "New" and the form creates a new entry in the collection

Key Collection (fields defined in nested bullet):

  • TimeOffTable: The collection used to mock the excel data source
    • Employee, StartDate, EndDate, etc
    • SampleHeading, SampleText (was easier to just keep these in the same collection as the user-generated data)
  • Tutorial - embedded excel table: The table which stores all the text for the tutorial
    • TutText, ProgUser (identical to UserProgress, used to do a lookup so the right text is displayed at the right time)
  • GalleryScreenTree: The gallery screen's tree view is overlaid with a gallery whose Items property points to this collection
    • ControlType, ControlName --> similar to ControlSelected, the Fill property is bound to a LookUp which compares ControlSelected.Name to ControlSelected and changes the fill accordingly to indicate the control is selected/not
    • ActionHighlight: at what UserProgress the row needs to be highlighted to indicate the next step in the tutorial (quite often empty)
  • NavColors: Defines the potential nav colors the user can change the RectQuickActionBar to in that portion of the tutorial

Summary:

As stated above, everything falls out of the UserProgress variable. The app itself is mostly just condensed screen shots of the studio whose Visibility, X, Y, Width, and Height properties are bound to the value of UserProgress. All menus are just screenshots overlaid with textboxes to mimic the hover / select effects you get in the editor. The app is completely linear. If you imagine UserProgress as a decision tree, that tree is, well, a straight line... This linearity saves A LOT of headaches because there are no branching decisions which need to converge appropriately down the line. If there's wiggle room for user exploration, those pieces are generally unbounded from UserProgress and thus don't overcomplicate the app.

 

Points of Interactivity: Intro + Connect to Data + Browse Requests:

 

  1. Left Control tree
    1. Screenshot with a gallery overlaid. Gallery has data source GalleryScreenTree. A single textbox control inside the gallery, with it's OnHover property set to a slightly opaque dark grey, and its OnSelect property updating the ControlSelected variable accordingly. Its fill property is logically bound to the ControlSelected variable, something like: If (ControlSelected.Name == ThisItem.ControlName, Grey, NoFill)
  2. Center Gallery (on canvas)
    1. Datasource: TimeOffTable (always)
    2. Text controls Text property (title as example): If (UserProgress < some#, point to SampleTitle, point to whatever field matches GallTitleText).
    3. Layout: X,Y, Visibility properties of controls internal to the gallery are bound to GallLayout, itself set by the user clicking on the layout menu and selecting from the two options.
    4. Body1, Subtitle1, Image1/Title1 dropdowns: The OnChange property for these sets their respective variables which are what the gallery text controls reference to display the proper field from TimeOffTable 

Points of Interactivity: View Requests

  1. Screen Naming
    1. Just text input fields overlaid ontop of the screenshot of the left hand tree view. Their OnChange events set GallScreenName & FormScreenName to whatever the user typed
  2. Checking fields
    1. The fields are pretty lame, just a gallery of checkboxes. This part isn't true to the editor (and could've been done better with a smarter gallery which ordered its items on whether a box was checked) but gets the point across to new users
  3. Form interaction:
    1. The form is a form control, with custom cards pointing to the TimeOffTable. 
    2. The X & Y properties of the DataCardKeys and Values are bound to FormLayout which has them change accordingly depending on what layout the user selected
    3.  Same idea as #2 for the SnapToColumns feature, but this time it's the DataCard X, Y, Width, properties that are bound to a variable's value
  4. Formula Bar: focusing on the OnChange property of this guy since it's the most interactive property
    1. OnChange: several If checks which are looking for two things:
      1. Is UserProgress a value such that the user needs to input a formula? and 
      2. Is what they input equal to what should be there?
      3. If both of these evaluate to try when the user hits Enter, then UserProgress is incremented and they move on
  5. Navigate Icon (back to gallery screen): setting it's OnSelect property
    1. Before a certain UserProgress (the point where the user sets the action), OnSelect is set to false, otherwise (after they've gone thru the tutorial to set the OnSelect to do something), it's set to do two things:
      1. navigate to the form screen
      2. set DetailName to a unique identifier to that row of the data source, so the form displays the proper row's info

 

Points of Interactivity: Create Requests

  1. Adding a new 'time off request' to the data source
    1. This is pretty much defined in the variables section where I discuss what DetailName does, but the '+' icon's OnSelect property sets DetailName to "new" 
      1. The checkbox creates a new record in TimeOffTable with DetailName set to "new"
  2. Editing an old 'time off request'
    1. Same idea as above, but now DetailName is set to a row in the data source, so the checkbox's OnSelect property follows the update record flow instead of the above

Sharing apps: pretty much just screen shots whose visibility changes depending on UserProgress. Nothing interesting.

 

...That ended up being quite verbose but hopefully it helps. If there's something specific you want me to hit on more, feel free to let me know.

 

 

  

mr-dang
Level 10

Re: Interactive Tour: How did you do it?

Awesome! I will implement it little by little

Microsoft Employee
@8bitclassroom
mr-dang
Level 10

Re: Interactive Tour: How did you do it?

@C_Ian_Davis It must have taken you forever to get those screenshots and whew... I'm finding that this is a lot of work. Serious kudos for completing it!

Microsoft Employee
@8bitclassroom
PowerApps Staff C_Ian_Davis
PowerApps Staff

Re: Interactive Tour: How did you do it?

Haha. Yes. Quite a bit of work. Speaks to the power of powerapps though... That you can create a pretty accurate representation of the studio within a powerapp!

DChrisPhillips
Level: Powered On

Re: Interactive Tour: How did you do it?

@mr-dang,

 

You may want to look into e-learning authoring tools such as Adobe Captivate, Articulate, Camtasia, to name a few. They make the process of actually capturing the navigation through the application quite simple and produces video/screen captures for you. It's been almost 10 years since I've used Captivate (what was available to me at the time), but I've got to think these tools have gotten much more user-friendly and advanced along the way.

 

If you want to create quizzes/tests or potentially integrate your learning modules into a Learning Managment System (LMS) and publish SCORM, check out the aforementioned. 

 

Hope you find this useful.

 

Chris

 

https://scorm.com/scorm-explained/

https://www.ispringsolutions.com/blog/5-e-learning-authoring-tools/

 

Helpful resources

Announcements
firstImage

Watch Sessions On Demand!

Continue your learning in our online communities.

Power Platform 2019 release wave 2 plan

Power Platform 2019 release wave 2 plan

Features releasing from October 2019 through March 2020

FirstImage

Power Platform World Tour

Coming to a city near you

thirdimage

PowerApps Community User Group Member Badge

Fill out a quick form to claim your user group badge now!

FourthImage

Join PowerApps User Group!!

Connect, share, and learn with your peers year-round

SecondImage

Power Platform Summit North America

Register by September 5 to save $200

Users Online
Currently online: 215 members 4,943 guests
Please welcome our newest community members: