So this week I started on created web components. The first resource that I wanted to target was Appointment resource. As it contained the most components that will be reused in other components. To get some more insight on the resource. I also went through the examples at the FHIR test server. I looked at the appointment resource. ie: http://hapi.fhir.org/baseDstu3/Appointment/1966105/_history/1
{
"resourceType": "Appointment",
"id": "1966105",
"meta": {
"versionId": "1",
"lastUpdated": "2019-06-22T23:20:15.284+00:00"
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><div>Routine checkup</div><div>Dr Dave</div></div>"
},
"status": "pending",
"description": "Routine checkup",
"start": "2019-06-29T16:20:15-07:00",
"end": "2019-06-29T16:35:15-07:00",
"minutesDuration": 15,
"participant": [
{
"actor": {
"display": "Dr Dave"
},
"status": "accepted"
},
{
"actor": {
"reference": "Patient/1966031"
},
"status": "accepted"
}
]
}
So looking at the example and the FHIR documentation for the appointment resource. I see that I will need the following components that I need to build for the.
- fhir-instant: Instant is similar to datetime which we have already used. But it is different in a way that it also contains the time and AM/PM. So it used when we need exact time. Which in our case. We need for the start and end of the appointment.
- fhir-positiveInt: In the resource we have minutes duration. Which tells the number of minutes the appointment will take. And this number has to be positive.
- fhir-appointment-status: This is a code component. Which will contain the select options for the status. Which can be either: Proposed, pending, booked, arrived, fulfilled, cancelled, noshow, entered in error, checked-in, waitlist.
- fhir-reference: This again is a type component. Which will be used in a lot of resource. It contains the display name and the reference url of the resource which we are targeting.
- fhir-appointment-participant: This component contains the participants of the appointment. It also contains the reference resource that we created earlier as “actor”
- fhir-create-appointment: This component will combine all components and post the result.
So as I was going to create the appointment resource. I created a git branch for this. After creating each component I committed the changes.
fhir-instant: commit
For the instant. We can use the datetime-local type for our inputs. And then return its value.
<div id="instantDiv">
${instant !== 'false'
? html`
<mwc-formfield class="instant" alignEnd>
<input
id="date"
type="datetime-local"
value="${this.value}"
on-input="${e => (this.value = e.target.value)}"
/>
</mwc-formfield>
`
: ''}
</div>


fhir-positiveint: commit
For the positive int. I am using the type number with min value as 0. So that we can only add positive values.
<div id="positiveIntDiv">
${positiveInt !== 'false'
? html`
<mwc-formfield class="positiveInt" alignEnd">
<input
id="positiveInt"
type="number"
min="0"
value="${this.value}"
on-input="${e => (this.value = e.target.value)}"
/>
</mwc-formfield>
`
: ''}
</div>

fhir-appointment-status: commit
For the appointment status. We are using the select component. As in MWC the mwc-select is not available and is under development.
<div id="appointmentStatus">
${typeField !== 'false'
? html`
<label>Status:</label>
<select
class="typeField"
value="${this.value}"
on-change="${e => (this.value = e.target.value)}"
>
<option value="proposed">Proposed</option>
<option value="pending">Pending</option>
<option value="booked">Booked</option>
<option value="arrived">Arrived</option>
<option value="fullfilled">Fulfilled</option>
<option value="cancelled">Cancelled</option>
<option value="noshow">No Show</option>
<option value="entered-in-error">Arrived</option>
<option value="checked-in">Checked in</option>
<option value="waitlist">Waitlist</option>
</select>
`
: ''}
</div>

fhir-reference: commit
For the reference we are using 2 input fields. Display and the Reference. Which points to the resource document.
<div id="referenceDiv">
${reference !== 'false'
? html`
<label>Reference</label>
<mwc-textfield
outlined
class="reference"
value="${this.value.reference}"
on-input="${e =>
(this.value.reference = e.target._input.value)}"
></mwc-textfield>
`
: ''}
${display !== 'false'
? html`
<label>Display</label>
<mwc-textfield
outlined
class="display"
value="${this.value.display}"
on-input="${e => (this.value.display = e.target._input.value)}"
></mwc-textfield
><br />
`
: ''}
</div>
fhir-appointment-participant: commit
The participant in appointment contains the reference as an actor. As well as its status. So we are importing the reference components here and add the status as a select option.
<div id="participantDiv">
${status !== 'false'
? html`
<label>Status:</label>
<select
class="status"
value="${this.value.status}"
on-change="${e => (this.value.status = e.target.value)}"
>
<option value="accepted">Accepted</option>
<option value="declined">Declined</option>
<option value="tentative">Tentative</option>
<option value="needs-action">Needs Action</option>
</select>
`
: ''}
${reference !== 'false'
? html`
<fhir-reference
class="reference"
value="${this.value.actor}"
on-input="${e => (this.value.actor = e.target.value)}"
></fhir-reference>
`
: ''}
</div>

fhir-create-appointment: commit
And the create appointment basically just imports all the required components and posts them.
_render({ url }) {
return html`
<fhir-appointment-status id="appointmentStatus"></fhir-appointment-status>
<p>Start:</p>
<fhir-instant id="start"></fhir-instant>
<p>End:</p>
<fhir-instant id="end"></fhir-instant>
<p>Minutes Duration:</p>
<fhir-positiveint id="minutes"></fhir-positiveint>
<p>Participant:</p>
<fhir-appointment-participant
id="participant"
></fhir-appointment-participant>
<br />
<mwc-button id="button" raised on-click=${() => this.doPost()}
>Submit</mwc-button
>
<iron-ajax
bubbles
method="POST"
id="ajax"
url="${url}"
on-response="handleResponse"
></iron-ajax>
`;
}
doPost() {
var status = this.shadowRoot.getElementById('appointmentStatus').value;
var start = this.shadowRoot.getElementById('start').value;
var end = this.shadowRoot.getElementById('end').value;
var minutes = this.shadowRoot.getElementById('minutes').value;
var participant = this.shadowRoot.getElementById('participant').value;
this.shadowRoot.getElementById('ajax').contentType = 'application/json';
this.shadowRoot.getElementById('ajax').body = {
resourceType: 'appointment',
status: status,
start: start,
end: end,
minutesDuration: minutes,
participant: participant
};
this.shadowRoot.getElementById('ajax').generateRequest();
}

Some of the components are not in material design. Like the select component. As we are using mwc and they are still under progress. Several issues have been created on gitlab regarding this. #24 #29 #32 #40 . Hopefully we will soon have more mwc components so we can use them.
Next up: In the next month. I am hoping to create all components for the required resources and add their demos in the index.html. So that in the last month. I am only left with testing and add the demos in the proof of concept application.