Adding Prompts - Part 1
Our appointments MPage is coming together nicely, however our end users expect more. Users need the ability to further control the output of their MPage through the use of input prompts, and they need to be able to repeat these prompts on a daily basis without having to fill in the values every time.
Once we complete the next steps, our MPage will have prompts for the appointment date range, appointment type, resource, location and schedule state. These prompts will be placed in the same toolbar as our preference save button and will be saved along with our column preferences and be unique to each user.
-
Open appointment-data.service.ts and add a new public variable called prompts. I have
this directly below the definition of my columnConfig object.
public prompts = { dateType: '30', fromDate: new Date(), toDate: new Date(), appointmentType: [], resource: [], location: [], schState: [] }
The prompts object has a number of variables and empty arrays that will store the content of the prompts we are about to create. For now, know that the dateType: '30' is indicating that we will be defaulting our MPage with a 30 day look-ahead for appointments. The two date values (fromDate and toDate) are set to the current date. -
Open toolbar.component.ts and add a new public variable called dateTypes as shown
below.
public dateTypes = [ {key: '30', value: '30 Days'}, {key: '60', value: '60 Days'}, {key: '120', value: '120 Days'}, {key: 'DATE', value: 'Date Range'}, {key: 'ALL', value: 'All Dates'} ];
The dateTypes variable will be used by our drop-down select control to present the users with the available options they have for date selection. This code can be added to as needed later if you feel like offering additional options such as 365 Days or 5 Years. -
Open toolbar.component.html and add the following three prompts. The first prompt
uses the Clinical Office mpage-select component and the other two prompts are mpage-calendar components. Each
of these will be bound to the appropriate variable inside our prompts object we created in our data service.
<mat-toolbar> <!-- Date Range --> <mpage-select label="Date Range" [(ngModel)]="appointmentDS.prompts.dateType" [values]="dateTypes"></mpage-select> <mpage-calendar label="From Date" [(ngModel)]="appointmentDS.prompts.fromDate"></mpage-calendar> <mpage-calendar label="To Date" [(ngModel)]="appointmentDS.prompts.toDate"></mpage-calendar> <button mat-icon-button title="Save user preferences" (click)="appointmentDS.savePreferences()"> <mat-icon>save</mat-icon> </button> </mat-toolbar>
In each of the new lines added above we are assigning a text label to the component with the label property and binding our prompts variable with the [(ngModel)] directive. In addition to this, the mpage-select statement is also linking our dateTypes variable to the component to provide the list of options the end user can see. - Take a look at your MPage in the browser. You should see something similar to the following screenshot. There are two immediate problems you will notice. First, the font size in the toolbar is huge. The second problem you will see is that even though "30 Days" is chosen as the Date Range value, you still see the "From Date" and "To Date" prompts. These should only be visible when Date Range has been chosen in the select.
-
The toolbar font size issue is easily corrected with a little CSS. Add a CSS class called "toolbar" in the
mat-toolbar element found in the toolbar.component.html file.
<mat-toolbar class="toolbar">
-
Open the styles.scss file and add a new CSS class called .toolbar.
// * Import theme from theme generator *// @import "theme"; .toolbar { font-size: 0.8rem; }
If you view your page now, the font size in the toolbar should be easier on the eyes. -
We can prevent the two calendar values from displaying by using the ng-container element built into Angular. This element is extremely helpful as it allows you the ability to control the flow of your code without adding additional content to the DOM.
We will wrap our two calendar controls inside a ng-container element and perform a check against our dateType variable inside our prompts object to ensure it is equal to "DATE". If it is equal to "DATE", the two calendar objects will appear.
Modify toolbar.component.html so it appears as follows.
<mat-toolbar class="toolbar"> <!-- Date Range --> <mpage-select label="Date Range" [(ngModel)]="appointmentDS.prompts.dateType" [values]="dateTypes"></mpage-select> <ng-container *ngIf="appointmentDS.prompts.dateType === 'DATE'"> <mpage-calendar label="From Date" [(ngModel)]="appointmentDS.prompts.fromDate"></mpage-calendar> <mpage-calendar label="To Date" [(ngModel)]="appointmentDS.prompts.toDate"></mpage-calendar> </ng-container> <button mat-icon-button title="Save user preferences" (click)="appointmentDS.savePreferences()"> <mat-icon>save</mat-icon> </button> </mat-toolbar>
When you view your MPage and test the different values you should see the prompt layout change. -
The appointment type and resource prompts are nearly identical, so they will be discussed together. Both prompts make use of the mpage-select component we used in our "Date Range" prompt however instead of assigning a predefined list of values we are going to point to a Cerner code set.
Both the appointment type and resource code sets (14230 and 14231) will likely contain a great number of possible values and for the sake of performance and prompt usability the mpage-select control will cap the number of values that can be loaded at once. To make it possible to use a code set with many values, we are going to turn on the searchable parameter to allow text searching of values. We also want the ability to allow the user to choose all types or select multiple values from each list. This will be done with the allOption and multiple parameters.
Add the following code to toolbar.component.html directly between the closing ng-container element and the button element.
<!-- Appointment Type --> <mpage-select label="Appointment Type" [(ngModel)]="appointmentDS.prompts.appointmentType" [codeSet]="14230" [multiple]="true" [searchable]="true" [allOption]="true"></mpage-select> <!-- Resource --> <mpage-select label="Resource" [(ngModel)]="appointmentDS.prompts.resource" [codeSet]="14231" [multiple]="true" [searchable]="true" [allOption]="true"></mpage-select>
- View your MPage, you should see the two new prompts. Open one of them to see the default view which shows a search box, a checkbox labelled "All Values" and a disabled checkbox indicating that the limit of 100 items has been exceeded. If you perform a search, qualified values appear in the list to allow selection.
-
Our next prompt is the "Location" prompt. For this, we will be using the mpage-tree component which provides us with a drill-down tree of values. The mpage-tree component defaults to using the location hierarchy in Cerner, however custom CCL scripts can be used to represent other data.
For our purposes we will be sticking with the default behaviour meaning we simply have to assign a title and bind it to a variable.
Add the following prompt code to your HTML immediately after the prompt for resource.
<!-- Location --> <mpage-tree label="Location" [(ngModel)]="appointmentDS.prompts.location"></mpage-tree>
-
View your MPage and try navigating the location tree. In its default state you can navigate down to the bed level however for our purposes we want to restrict the tree to prevent users from navigating any lower than the nurse unit level. This is easily done by passing a value to the scriptParams property in the mpage-tree component.
Change your mpage-tree statement to add a maxViewLevel parameter to scriptParams as follows:
<mpage-tree label="Location" [(ngModel)]="appointmentDS.prompts.location" scriptParams='"maxViewLevel":"UNIT"'></mpage-tree>
Note: Some larger hospital systems may have hundreds or thousands of facilities in Cerner which may have a small performance impact in the mpage-tree component. The site used to build this training material is such a site with over 800 facilities resulting in a small 2-second delay in rendering the initial tree list. For this site, we remedied this issue by creating a custom code set that links the facilities to a smaller group called hospital organizations. This required creating a new CCL script for the tree which presents these hospital organizations first allowing drill-down to the facilities in Cerner.
-
The last prompt is the "Sch State" prompt. This prompt will use the mpage-select component and point to code set
14233. As with the appointment type and resource prompts, we want to allow multiple selections and all options
to be chosen.
<!-- Sch State --> <mpage-select label="Sch State" [(ngModel)]="appointmentDS.prompts.schState" [codeSet]="14233" [multiple]="true" [allOption]="true"></mpage-select>
-
View your MPage. It should look like the screenshot below.
Overall it looks pretty good except all of our prompts are the same width as each other. The "Date Range" and the two date prompts are too long and the rest of the prompts are too short.
-
We can use CSS to change the appearance of each field. For the three date prompts, add a CSS class property called "prompt-date" as shown below.
<!-- Date Range --> <mpage-select label="Date Range" [(ngModel)]="appointmentDS.prompts.dateType" [values]="dateTypes" class="prompt-date"></mpage-select> <ng-container *ngIf="appointmentDS.prompts.dateType === 'DATE'"> <mpage-calendar label="From Date" [(ngModel)]="appointmentDS.prompts.fromDate" class="prompt-date"></mpage-calendar> <mpage-calendar label="To Date" [(ngModel)]="appointmentDS.prompts.toDate" class="prompt-date"></mpage-calendar> </ng-container>
Add a new class called "prompt" to each of the other components.
<!-- Appointment Type --> <mpage-select label="Appointment Type" [(ngModel)]="appointmentDS.prompts.appointmentType" [codeSet]="14230" [multiple]="true" [searchable]="true" [allOption]="true" class="prompt"></mpage-select> <!-- Resource --> <mpage-select label="Resource" [(ngModel)]="appointmentDS.prompts.resource" [codeSet]="14231" [multiple]="true" [searchable]="true" [allOption]="true" class="prompt"></mpage-select> <!-- Location --> <mpage-tree label="Location" [(ngModel)]="appointmentDS.prompts.location" scriptParams='"maxViewLevel":"UNIT"' class="prompt"></mpage-tree> <!-- Sch State --> <mpage-select label="Sch State" [(ngModel)]="appointmentDS.prompts.schState" [codeSet]="14233" [multiple]="true" [allOption]="true" class="prompt"></mpage-select>
-
Before we create our two new CSS classes, we are going to add a new empty span element between our "Sch State"
component and the button component that will be used to fill the empty space between our prompts and the save
button. Add the following between the "Sch State" mpage-select component and the button element.
<!-- Space between prompts and save button --> <span class="space-between"></span>
-
Open your styles.scss file and modify the content to match the code listed below.
// * Import theme from theme generator *// @import "theme"; .toolbar { font-size: 0.8rem; } .space-between { flex: 1 1 auto; } .prompt, .prompt-date { padding-right: 8px; } .prompt { width: 13rem; } .prompt-date { width: 7rem; }
The space-between class tells your page to fill any remaining horizontal space. This creates a responsive layout where anything to the right of the space-between span we created is pushed to the far right side of the screen.
The prompt and prompt-date classes each have an 8 pixel padding at the right of the component followed by definitions of the sizes (13rem and 7rem). I recommend using rem as a unit of measure as it scales with the zoom level users set in their browser where pixels never change.
- View your MPage. Your prompts should look much better now.