How to use "manualFields" with a "field/personAddressWithHierarchy"

Hi all, @darius and @mogoodrich

This is the follow up on an issue that I had left pending in ‘How to customise the Patient Registration page?’ We are using the "field/personAddressWithHierarchy" widget successfully with the Address Hierachy module. However we just cannot seem to be able to add a free text field in the "contactInfo" section.

There is no documentation on this and I could only find two examples:

My latest trial is below but the free "houseNumber" text field just doesn’t show up:

"legend": "Person.address",
"fields": [
    {
        "type": "personAddress",
        "label": "registrationapp.patient.address.question",
        "widget": {
            "providerName": "registrationapp",
            "fragmentId": "field/personAddressWithHierarchy",
            "config": {
            	"manualFields": ["houseNumber"],
                "fieldMappings": {"houseNumber": "obs.CIEL:161011"}
            }
        }
    }
]

I am not sure what to do from there, any other tips would be greatly welcome! Thanks guys.

(1) I wanted to debug that file from PIH/openmrs-module-mirebalais to see what exact JSON is generated, but the project doesn’t build. It seems to refer to snapshot versions of various resources that are not (yet) on the public repo. After solving the Maven dependency issues and falling back to the nearest lower available versions I stumbled upon compilation erros upon mvn install-ing.

Hi Dmitri,

I don’t have an answer, but I would recommend that rather than falling back to previous versions, you fall forward to the newer versions and see if that helps. Typically, when our modules still refer to SNAPSHOT dependencies and they don’t exist in maven it is because that SNAPSHOT was released and there is a non SNAPSHOT version available, so you should just use that instead.

We don’t tend to always notice missing snapshot dependencies locally since these are never deleted from local .m2 repositories automatically. So anyone (including a CI server) that has been building against a snapshot along the way will not notice these missing dependencies when they later occur for others.

Does anyone have any techniques they use to deal with this?

Thanks, Mike

@mseaton Hi Mike,

The reason why I went for the lower version is simply because the non-SNAPSHOT version was never there for any of the missing dependencies on OpenMRS’s public repo.

So you suggest that I git clone/mvn install the latest of those and copy the JARs into my local repo? Possibly I may adapt PIH/openmrs-module-mirebalais’s POM in order to match those newer versions then. Or is there a way for me to make change this POM so that this just happens?

@mogoodrich Hi Mark,

Nevertheless, you are the closest to being able to tell me what is wrong with my JSON snippet. Debugging PIH/openmrs-module-mirebalais is just a way to see what JSON is generated by the Java code there. I will look into that tomorrow but perhaps something will come to your mind straight away.

Thanks everyone.

@mseaton

  • I cloned and built the problem dependencies, and this was enough to having them copied into my local .m2 and stop Maven complaining about them, as you suggested. For the record, there were dependencies issues in Module Shared Test Resources and in Module OMOD.

  • Nevertheless, I had to change this to the latest version: <webservicesRestVersion>2.13-SNAPSHOT</webservicesRestVersion> (The POM is requiring 2.12-SNAPSHOT and 2.13-SNAPSHOT would not satisfy this.)

  • I stumbled on compilation errors regarding global variables defined in PIH/pihcore and PIH/mirebalaisreports modules.

  • I cloned-built PIH/pihcore and, although the build failed (!), this cleared the compilation errors coming from a resource inside that project. Go figure…

  • Clone-building PIH/mirebalaisreports solved a bunch of other compilation errors.

  • But… I had to edit ReportSetup.java so that MirebalaisReportsProperties.FULL_DATA_EXPORT_SCHEDULED_REPORT_REQUEST_UUID was not referenced anymore (I just replaced it with an empty String.)

And now… PIH/openmrs-module-mirebalais has successfully built! I will try to use the module tomorrow and, hopefully, figure out the answer to my original question.

But if anyone wants to step in, please do since all the above is merely a workaround.

Just skimming the first message, I think you need to give one of the addressN fields as manualFields.

Here’s the one example I see in openmrs’s github:

And it seems to be similar in a PIH page:

I really tried to “copy” whatever was done at PIH:

"providerName": "registrationapp",
"fragmentId": "field/personAddressWithHierarchy",
"config": {
	"shortcutFor": "address1",
	"manualFields": ["address2"],
	"fieldMappings": {"address1": "obs.LFHC:2001", "address2": "obs.LFHC:2002"}
}

I added address1 and address2 in my address template, and created the ad-hoc ‘Text’ concepts.

And anyway, if map the address fields in question:

Then of course they show up but are not dealt any differently than the ‘usual’ fields of the address hierarchy, in fact nothing special happens (and their dropdowns are empty as expected).

If I don’t map them, which I thought is what you meant:

Then I get an exception when loading the page:

Caused by: org.openmrs.ui.framework.ViewException: *** In view 'field/personAddressWithHierarchy', NullPointerException: null.
Passed from controller: 
  sessionContext -> org.openmrs.module.appui.UiSessionContext@65153105
  featureToggles -> org.openmrs.module.appframework.feature.FeatureToggleProperties@4cd69477
  levels -> [country, province, district, village, address1, address2]
  addressTemplate -> org.openmrs.layout.web.address.AddressTemplate@1bad380a
  initialValue -> null
  patient -> Patient#null
  primaryIdentifierType -> OpenMRS ID
  appId -> lfhcforms.registrationapp.registerPatient
  formStructure -> org.openmrs.module.registrationapp.model.NavigableFormStructure@74cd802f
  nameTemplate -> org.openmrs.layout.web.name.NameTemplate@2370495a
  includeRegistrationDateSection -> true
  allowUnknownPatients -> false
  allowManualIdentifier -> false
  patientDashboardLink -> null
  enableOverrideOfAddressPortlet -> true
  breadcrumbOverride -> 
  ui -> org.openmrs.ui.framework.fragment.FragmentUiUtils@5245731b
  context -> org.openmrs.api.context.Context@4d881bcf
  contextPath -> openmrs
  session -> org.openmrs.ui.framework.session.Session@3b8ad987
  param -> {appId=[Ljava.lang.String;@22d9dacd}
  out -> java.io.PrintWriter@cabda9b
  config -> {id=fr5519, classes=null, formFieldName=null, addressTemplate=org.openmrs.layout.web.address.AddressTemplate@1bad380a, left=true, label=What is the patient's address?}

I am not sure what null object it is unhappy about, and hence what may be missing. I guess this happens in RegisterPatientPageController. I can’t debug this right now but if all the above rings a bell to anyone, please please…

Sorry, @mksrom, I have been away on vacation and am just catching up on this now. I think you are close.

First, to clarify, is what you are trying to achieve is to allow one or more manually-entered field at the lowest level of the hierarchy? This is the use case for manual fields.

What you are doing should work… you do have to map all address fields (so your first screenshot of “Address Hierarchy Levels” is correct). Then both these fields need to be listed in the manualField config parameter:

manualFields: ["address1","address2"]

Remove the “shortcutFor” and “fieldMappings” config parameters for now, as they are for other functionality unrelated to setting manual fields. You shouldn’t need to create new concepts either… fieldMappings are used only when you want to store an address in a obs data structure instead of the built-in person address data structure.

Looking back at your original example, I think the only thing you need to do is add houseNumber to your hierarchy, map it to an address field (like “address1”) and then reference that address field (not houseNumber) in “manualFields”. Also remove “fieldMappings”.

Take care, Mark

Make that @mksd… too many similar usernames… :slight_smile:

Hi Mark, sorry I was travelling and could only get back to this topic now.

I’m afraid this doesn’t work:

"providerName": "registrationapp",
"fragmentId": "field/personAddressWithHierarchy",
"config": {
   "manualFields": ["address1"]
}

I also tried to name it address1 (rather than houseNumber) to no avail.

I mean, whatever I do, as soon as I map the level, I can see that it’s being treated like the other fields. Except that there is nothing in the dropdown menu (because there are 0 entries). But nothing different is really happening to that address hierarchy level.


Could that be that something special has to be done within the address template then? When defining the address field in there? This is mine:

<org.openmrs.layout.web.address.AddressTemplate>
	<nameMappings class="properties">
		<property name="countyDistrict" value="Location.district" />
		<property name="address1" value="Location.address1" />
		<property name="country" value="Location.country" />
		<property name="stateProvince" value="Location.stateProvince" />
		<property name="cityVillage" value="Location.cityVillage" />
	</nameMappings>
	<sizeMappings class="properties">
		<property name="countyDistrict" value="40" />
		<property name="address1" value="40" />
		<property name="country" value="20" />
		<property name="stateProvince" value="40" />
		<property name="cityVillage" value="40" />
	</sizeMappings>
	<elementDefaults class="properties">
		<property name="country" value="Laos" />
	</elementDefaults>
	<lineByLineFormat>
		<string>cityVillage</string>
		<string>countyDistrict</string>
		<string>stateProvince</string>
		<string>country</string>
	</lineByLineFormat>
</org.openmrs.layout.web.address.AddressTemplate>

Ugh. Nothing looks wrong to me. I don’t suppose the code is up anywhere where I can take a look.

If not, could you send me the generated html?

Take care, Mark

Hi Mark,

You can access our repo, we have tried to put together a “typical” 2.x implementation (which is essentially just a HFE forms provider in the end): https://github.com/mekomsolutions/openmrs-module-lfhcforms

  • The address template is saved through the module’s activators.
  • The address hierarchy is here: api/src/main/resources/addressHierarchy.csv but you would need to import it manually for now (note that the delimiter is a comma) :

Thanks so much for offering to help here, this tiny feature is actually quite needed in the context of our implementation.

Hmm… yeah, taking a quick look at the code nothing seems amiss. I don’t suppose you have a staging environment up anywhere that I could have access to?

If not, can you open up the registration page and cut and paste generated html into a pastebin and send me the link?

Hi Mark,

Well we are working on our CI but it is not ready yet, so no :worried:

Here is the complete HTML paste: http://paste.ubuntu.com/12877748/

Hopefully something will be obvious to you. Thanks again!

Hmmm… should have thought of asking you this earlier, but, what version of the Registration App module are you using?

Sorry Mark, I was travelling again… Back on it:

I was on version 1.2 and I can see that PIH/openmrs-module-mirebalais is on version 1.4-SNAPSHOT. Therefore I upgraded (which also required to upgrade Reporting to version 0.9.6 and Registration Core to version 1.3-SNAPSHOT) and it still doesn’t work.

Here is the updated HTML: http://paste.ubuntu.com/12892909/

Ugh again. Still not sure exactly what the issue is, but I’m thinking this could be a bug, plain and simple, that hasn’t been picked up before.

Looking at the generated HTML, the code isn’t picking up the “config” parameters of that the PersonAddressHierarchyWidget uses… I think there’ s bug here when loading in the JSON… can you enter a ticket for this?

Thanks, Mark

Ok will do.

But first I wanted to debug a little and I inspected config instance in

UiUtils.includeFragment(String providerName, String fragmentId, Map<String, Object> config)

when it is called with fragmentId set at "field/personAddressWithHierarchy" that is when registerPatient.page gets loaded. Clearly it is missing what should be filled in the [relevant section of registerPatient.gsp][1]:

if (field.widget.config) {
 field.widget.config.fields.each {
        configOptions[it.key] = cleanup(it.value);
    }
}

I may be wrong but it seems to me that the code just above is where the widget’s config is read. This is the JSON right now:

"legend": "Person.address",
"fields": [
  {
  ...
  "widget": {
    ...
    "config": {
      "manualFields": ["address1"]
    }
  }
}

… it looks like the .fields property could be missing, because of the way it is being fetched in the GSP snippet: field.widget.config.fields.each . Therefore I tried the config below:

"config": {
  "fields": [
    {
      "manualFields": ["address1"]
    }
  ]
}

And that still does not work… [1]: https://github.com/openmrs/openmrs-module-registrationapp/blob/master/omod/src/main/webapp/pages/registerPatient.gsp#L239-L243

@mksd, I don’t know if you’re to the point of considering a temporary work-around until this “bug” gets fixed so you can have manual fields. In my current implementation (which can’t wait anymore) I setup a Person Attribute for the “manual” address field, and added it to the section. When the “bug” gets fixed, we’ll just run some SQL to pull the manual fields from the Person Attribute, and into the appropriate address field. Something like… http://pastebin.com/yJsF4bQk

Hi James,

Thanks for sharing this. This is not such a ‘most needed’ feature for us anymore. Don’t get me wrong, we would like to get this fixed, in which case we would then use it, but it is medium-low important. Therefore we would not deploy a workaround that then would have to be corrected via SQL. As much as I know that it could (and most likely will) work, the relative secondary nature of this need for us is not worth the risk/hassle. We would rather wait.

Thanks anyway, and for keeping the subject on the headlines :wink: