HFE: Conditions should have a pointer for the form_field it was created through

I don’t have a strong preference @mksd but think I agree I like the former more… if there’s no space limitations might as well be more explicit.

@mogoodrich, coming back to naming…

See here above how the form tag (or form control)'s namespace and path is decomposed:

{form namespace}^{form name}.{form version}/{control id}-{n}

The part that is explicitly specified when building forms is the control id, should we call it like that then? Any preferences?

<obs conceptId="CIEL:Systolic" formPath="systolic"/>
<obs conceptId="CIEL:Systolic" controlId="systolic"/>
<obs conceptId="CIEL:Systolic" tagId="systolic"/>

IMO formPath creates a confusion with the actual form namespace and path that in the end is the whole thing like: “HtmlFormEntry^Vitals.1.0/systolic-0”.

I think the most general choice, and that would also fit Bahmni Forms’ naming, would be controlId. What do people think? @burke?

Cc @luis.oliveira

I don’t like tagId… if the convention Bahmni started was controlId I guess I’d be okay with it, but I"m not sure why formPath is confusing. This:

form namespace and path = {form namespace}^{form name}.{form version}/{form path}-{n}

… seems clearer than introducing a whole new terminology “control ID”. (Though, of course, the fact that control ID has a precedent in Bahmni gives it value).

Another key point maybe I forgot to mention was I was seeing “formPath” is an actual path in the case of obs groups. As an example:

<obsgroup conceptId="CIEL:Blood Pressure"  formPath="blood_pressure">
       <obs conceptId="CIEL:Systolic" formPath="systolic"/>
       <obs conceptId="CIEL:Diastolic" formPath="diastolic"/>
</obsgroup>

would result in these paths for the three obs:

HtmlFormEntry^Vitals.1.0/blood_pressure-0
HtmlFormEntry^Vitals.1.0/blood_pressure^systolic-0
HtmlFormEntry^Vitals.1.0/blood_pressure^diastolic-0

That seems helpful, though I’m open to the argument that it’s more complicated than needed. This does still seem backwards-compatible with the Bahmni pattern.

Take care, Mark

Ah, actually, just as I write that, I think I see what you are getting at… you are viewing “formPath” in the “filePath” sense? ie it’s the full path to the form, note the path with within the form itself.

Would be interesting to research what the initial design thoughts were. @burke @mseaton any ideas?

controlId seems clear and seems like a good choice to me

If there’s a consensus around controlId, I’m fine with that…

Resurrecting this one as I’m working on https://issues.openmrs.org/browse/HTML-788 to bring this long-needed support of using a form path with Obs elements on HTML Forms.

I ran into a bit an issue when handling form paths with obs groups. I believe we came up with the following approach:

<obsgroup conceptId="CIEL:Blood Pressure"  formPath="blood_pressure">
       <obs conceptId="CIEL:Systolic" formPath="systolic"/>
       <obs conceptId="CIEL:Diastolic" formPath="diastolic"/>
</obsgroup>
HtmlFormEntry^Vitals.1.0/blood_pressure-0
HtmlFormEntry^Vitals.1.0/blood_pressure^systolic-0
HtmlFormEntry^Vitals.1.0/blood_pressure^diastolic-0

However, trying to set this path results in a Core exception because the “^” is not allowed because it is the separator between the form namespace and the path.

Digging deeper, it does seem like the correct pattern should actually be:

HtmlFormEntry^Vitals.1.0/blood_pressure-0
HtmlFormEntry^Vitals.1.0/blood_pressure/systolic-0
HtmlFormEntry^Vitals.1.0/blood_pressure/diastolic-0

So, probably my mistake in the design, but does this work for people? Does it clash with Bahmni at all? @mksd @angshuonline @ibacher @mseaton ?

@mogoodrich I think that you are suggesting that obs group members can be identified through looking at their form field path. For example

HtmlFormEntry^Vitals.1.0/blood_pressure/diastolic-0

would signify that ‘diastolic’ is in fact a first level obs group member inside the blood pressure encompassing group. My question would be to figure out if we need/want that, or if it is enough to just have unique field coordinates for a given piece of data? In which case this would suffice:

HtmlFormEntry^Vitals.1.0/blood_pressure_diastolic-0

In other terms we would just defer to the implementer to figure out unique field paths, full stop.

If we want that then sure we need to find a mechanism to describe nested fields, such as more and more forward slashes that describe that we dive in a nested structure deeper and deeper. But I’m fearing this is overcomplicating things and will make the interpretation of the field path complex and sometimes ambiguous.

@burke @ibacher @jdick?

@mksd I started re-reading the thread to remind myself how things work. Isn’t Mark’s proposal essentially equivalent to what Bahmni already does, e.g. using parentFormFieldPath (if any) to define form id.

In terms of Mark’s examples, I think this looks something like this:

HtmlFormEntry^Vitals.1.0/blood_pressure-0
HtmlFormEntry^Vitals.1.0/blood_pressure-0/systolic-0
HtmlFormEntry^Vitals.1.0/blood_pressure-0/diastolic-0
1 Like

Oh, very interesting @ibacher@angshuonline can you confirm this?

I was going to say in response to @mksd that maybe I was making things overly complicated and we don’t need nested support for now (it would make the coding easier, at least), but if Bahmni already supports nesting, I’d be inclined to support it (following the same format as Bahmni).

Indeed if there is a precedent in Bahmni let’s follow it :+1:

@mogoodrich is it ok to get this in as part of HTML-788 or the nesting aspect creates a lot of overhead?

I’ve been including the nested work in HTML-788, so definitely fine to include it. Though, for what it’s worth, I had to put that ticket on hold for a bit but hope to get back to it in the coming few weeks.

Maybe out of context :pray: , this reminded me that some work needs to be done on WS/REST module to support those fields ie. formFieldNamespace and formFieldPath.

Such a payload would fail with an NPE, this is because the WS module tries to dynamically load getters and setters for those props using reflection yet support was added by an interface and not a pure POJO

Has anyone tried this out? @dkayiwa @ibacher

  "person": "68ed6d7f-7f58-416d-b51b-c45490dd03bc",
  "obsDatetime": "2021-09-09T21:06:05.999Z",
  "concept": "159427AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "location": {
    "uuid": "ba685651-ed3b-4e63-9b35-78893060758a",
    "display": "Inpatient Ward"
  },
  "order": null,
  "groupMembers": [],
  "voided": false,
  "formFieldNamespace": "ohri-forms",
  "formFieldPath": "some-path",
  "value": "664AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
}

Error log: <!doctype html><html lang="en"><head> <title>HTTP Status 500 – Internal - Pastebin.com

I think the problem is quite a bit simpler than that: there are no setters for formFieldNamespace and formFieldPath, instead there is a setter for formField that takes both arguments. Interestingly, you’re pointing to the bug as arising from using an Obs where the same methods were added in 1.11, so apparently this bug has existed for a while?

We should definitely fix that. Is anyone aware of how we’ve handled similar cases (if any) previously?

2 Likes

I have addressed this here [RESTWS-849] Add setters for formFieldNamespace and formFieldPath - OpenMRS Issues and attached, on the ticket, a compiled module with the fix.

4 Likes

We use the formfield path to store the path of the control in a form. Note, Bahmni’s forms can have “add-more” (the same control can be used multiple times in a form) and the path stores the details. Also the path can store even the parent container details.

@binduak can you provide some more examples?

Thanks @angshuonline so, just to confirm, if you had a obsgroup with nested obs it would store form field paths something like the following?

@mogoodrich

We do not nest the parent info, as much as I know … @binduak can you correct?

Bahmni^[FormName].[version]/[control-id]-[repeat]

so, assuming I had a simple obsgroup “BP” with 3 members (systolic, diastolic, posture) … in obs when we save the form - it is saved as

Bahmni^VitalsForm.1/1-0
Bahmni^VitalsForm.1/2-0
Bahmni^VitalsForm.1/3-0
Bahmni^VitalsForm.1/4-0

@binduak can you elaborate on the “container controls” like section, table etc?

@angshuonline @binduak the code that @ibacher pointed to suggests that nesting is supported, see: HFE: Conditions should have a pointer for the form_field it was created through - #63 by ibacher

I think thats done only in case of a container control (section, table, obsgroup) - that can have multiple entries for the same concept/group. @binduak can you elaborate on this?