How can I make my forms compatible with HTML forms after been submitted

I have a few forms I’m using in an OWA that I will like for them to appear in the backend as html forms after been submitted. Below is an example of such forms

When the user submits that, a REST call is made to /hivtestresult which adds an entry to the hiv_test_result table. I want to be able to access this submitted data like all submitted data done through the html form entry module. What OpenMRS tables do I need to modify to achieve this. I know every form submission creates an obs for all the fields in the form but I’m not sure if just creating obs will do the trick.

cc @dkayiwa @darius @wyclif

So I noticed every form submission creates an encounter. So when saving my data, I created an encounter with encounter type used by the html forms. I also set the form id to the html form created with html form entry module. And on post, I could see an encounter on the patient dashboard with the encounter details as though it was created from an html form. Now what’s left is figuring out how to handle other form fields that are not part of encounter details.

I was able to achieve this. I was able to POST data to an html form via an open web app. The reason I needed to be able to POST html forms via REST was because my open web app is behind a service worker which makes it available while offline. While handling offline registration patients was straightforward, form entry was not. But I was able to make it work. So now I can do form entry even while client is offline and it will sync with server when it’s back online and it will seem like it was saved from the html form entry module.

To achieve this,

  1. I created the forms with the html form entry module and took note of the ID of the concepts used in the obs fields

  1. Create Java and REST api for form entries in a custom module. E.g CultureResult.java and CultureResultResource

and when saving my resouce, I create an encounter which is attached to my previously created html form. An obs that is linked the encounter. Save both encounter and obs. And on visiting the patient dashboard from legacyui, I could see my submitted data as though It was done using the html form created with the form entry module.

Below is the form replica in my webapp

Entering the form makes a POST to /cultureresult with this json data

{
    "patient": "uuid",
    "encounterDate": "date",
    "encounterLocation": "location",
    "result": "text entered in field"
}

And on the backend, I created an encounter and obs linked to my html form using

final Encounter encounter = new Encounter();
encounter.setPatient(cultureResult.getPatient());
encounter.setEncounterDatetime(cultureResult.getEncounterDate());
encounter.setProvider(config.getEncounterRoleForForms(), cultureResult.getEncounterProvider());
encounter.setEncounterType(config.getEncounterTypeForForms());
encounter.setLocation(cultureResult.getEncounterLocation());
encounter.setCreator(Context.getAuthenticatedUser());
encounter.setDateCreated(new Date());
encounter.setForm(Context.getFormService().getForm(1));
Encounter saved = Context.getEncounterService().saveEncounter(encounter);
	
 final Concept conceptForResult = Context.getConceptService().getConcept(3);
 final Obs obs = new Obs();
 obs.setConcept(conceptForResult);
 obs.setPerson(cultureResult.getPatient().getPerson());
 obs.setEncounter(saved);
 obs.setValueText(cultureResult.getResult());
 obs.setCreator(Context.getAuthenticatedUser());
 obs.setDateCreated(new Date());
 obs.setObsDatetime(new Date());
 Context.getObsService().saveObs(obs, "");
 cultureResult.setEncounter(saved);
 return saveCultureResult(cultureResult);

Visiting the patient dashboard I could see an entry for an encounter created

Viewing the entry works too

Thanks @ivange94 for sharing the so nicely detailed solution. It will be a very valuable resource to whoever gets the same challenge and lands on this post. :slight_smile:

1 Like

@ivange94, just something that crossed my mind.

we could override the default submit functionality of the forms to save the serialized form when we are offline, and when we are back online, we could have a service which would send these serialized forms to the HFE module mimicking a form submit. The HFE will see it as a normal form submission and all the intricacies will be taken care of by the HFE module.

1 Like

@piyush9620 Note: offline is not within the scope of the GSoC project. To get offline working, I had to be able manipulate HTML forms via REST that is why I added this link on the GSoC project page resources. It’s so you see how I used REST with HFE but not that the project involves handling form submissions offline.

it is just an idea so that someone in the near future can make use of it, if they come across a problem similar to this thread and if they find it worthy. nothing to do with the GSOC project.

FYI, I did not understand the point.

i read above that you needed to be able to submit data via html forms even when offline. i see that how the problem is currently handled is via creating a rest endpoint which is used to sync the data later when online. i understand that the HTML form REST project can help with the same.

But i just had an idea to store the serialized forms when offline and later mimic the process of form submission which would eliminate the need of a separate REST endpoint for each form, and you could sync data from all the offline forms directly and all will be taken care of by HFE module as it is always.

basically i suggest also storing the complete “HTML form” in its serialized form locally. what i believe currenlty done is, when we are offline, we are parsing the HTML form then and there itself, and storing all the data from that form locally but not storing the whole serialized html form itself. Storing the whole serialized form will help us create a pseudo form submit action later when we are online. this pseudo form submit will help us submit the forms as usual.

Well you just stated the problem. Not a solution.

i am sorry if i couldn’t make myself clear. @ivange94 i just edited my above comment. plz let me know if it is not clear.

No form parsing is happening. When you make a request to save a form, a JSON is sent to the server. If the server is unavailable, this json is stored in the browser and when the server comes back online, the request is made using this json as the data.

TBH, I don’t know what you mean by this. Who does the serialization and how?

Your edit got me more confused.

Have you worked with the openmrs HFE and know how forms are been saved? When you talk of serializing the form is that done by the browser? Plus an html form is not an object, how do you intend to do the serialization and where do you save this serialized form?

This can definitely be solved without using REST. I just don’t get the picture you are trying to paint.

Please see the first answer here, it is a very good example.

Here is the code from the link above.

var datastring = $("#contactForm").serialize();

$.ajax({

type: "POST",
url: "your url.php",
data: datastring,
dataType: "json",
success: function(data) {
  // do something
},
error: function() {
    //do something
}

});

Here we are submitting the form using an ajax call and the data that we send is the serialized form. So i figured, if we are offline, what we could do on form submissions is just store the serialized version of the form in an array in javascript in the browser. later when are online, we could create such ajax calls having data from the array (which contain serialized forms which we stored) one after the other to mimic form submissions.

1 Like