OpenClinica/enketo-express-oc

Signature item handling

Closed this issue · 15 comments

An item with the bind::oc:external value ‘signature’, will have one possible response. When this response is checked, it must:

  1. Evaluate the form for errors as if the Complete button has been clicked. If there are errors, display the standard message blocking the user from completing the form
  2. If the form is valid, make a call that the item has been checked

On the OC side this causes a dialog to appear, which can be cancelled, if that occurs OC may notify enketo the user is returning to the form, in this case when the user is returned to the form enketo unchecks the checkbox item. Ideally this should trigger any logic associated with that item.

question type "acknowledge"? -> https://xlsform.org/en/#question-types - no a select_multiple with only 1 option

If I remember correctly, the rationale for using a form question (instead of UI around the form) is to be able to use form logic that refers to this question.

Can the user uncheck the box? - This scenario shouldn't be able to occur...

Do not submit data if the oc:external value is "signature".

  • Enketo checks whether it is a single-option select_multiple
  • Add validation in Enketo Validate -> moved to OpenClinica/enketo-oc#71
  • post message
  • receive 2 messages (and 1 timeout)
  • enable widget in default config
  • test in iframe

Work in master.

If Enketo doesn't receive a 'receive and modal opened' message within a certain time, it should show something to the user and perhaps uncheck the question?

Another message if the user closes the modal without signing, do the same? - yes

This is ready for testing in master.

Configuration:

  • a new widget was added to default-config.json. If you are not overwriting the widgets value in your Enketo installation you shouldn't have to do anything to enable this new widget

events:

  • {enketoEvent: 'signature-request'}: Enketo sends this to the parentWindow to trigger the signature dialog
  • {event: 'signature-request-received'}: OC sends back to Enketo to indicate the message was received and a dialog is shown
  • {event: 'signature-request-failed'}: OC sends back to Enketo to indicate that something went wrong (e.g. user clicked close on dialog)

Have a look at the two error messages here so they can be tweaked: c72476d#diff-47b07faa9b1b997bbcc969615c844fcd6bfe00b47523030fa082f8e08205584b

For reference this is what I used to test receiving and sending messages in the parentWindow:

window.addEventListener('message', receiveMessage, false);
    function receiveMessage(event){
      const data = JSON.parse(event.data);
      // TODO in real life, check origin! if (event.origin !== "http://enk.to:8080") return;
      console.log('data received from iframe', data);
      console.log('origin of message', event.origin);
      console.log('source of message', event.source);
      if (data.enketoEvent === 'signature-request'){
        document.querySelector( 'iframe' ).contentWindow.postMessage(
            JSON.stringify({
                event: 'signature-request-received'
            }),
            location.href
        );
      }
    }

Hi Martijn,

Our developer has been working on this on our end and we are running into an issue where the error modal indicating no response was received after the signature item is checked displays 100% of the time. To aid in troubleshooting we were wondering if you could take a look and see if there's anything obviously wrong. Here is an image of the code in our UI to check for this:
image

@malcjackson, I'm guessing there may be multiple iframes on the page you are developing. In that case document.querySelector('iframe') will only select the first iframe which may not be the one containing the Enketo Form.

If that's not the issue, can you confirm if you receive the signature-request message from the Enketo form?

Thanks @MartijnR , the developer checked and has this response: "There are not multiple iframes on the page. I tried even giving a unique id to iframe, and then posting message "signature-request-received" to that iframe but that didn't work also"

Thanks.

  1. Can you confirm that you receive the signature-request message from the Enketo form?
  2. Just to be sure, the message you are seeing in the modal is "Signature service is currently not available. The question has been unchecked.", right?
  3. Is there an error message shown in the browser console, e.g. like "message received from untrusted source"?

Thanks @MartijnR

  1. We are receiving it
  2. That is correct
  3. There is an error in the console but it appears when the form is opened, before the item is checked. Nothing new appears in the console after the item is checked:
    image

Here is the network tab after clicking the item, nothing sticks out here:
image

Thank you!

I think the issue is with the second argument (targetOrigin) of postMessage (on the OC side). You could quickly confirm that by changing location.href to '*' (see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).

If that fixes it we need to change the unsafe '*' to the specific targetOrigin which should be the URL of the Enketo form. You may have to play around with that URL a bit (query params?, path?, fragment identifier?)

  • look into why timeout is not cleared when signature-request-failed is received from OC

It seems better to explicitly clear it there, even though in reality 'signature-request-failed' would always be preceded by 'signature-request-received' and be cleared there.

I'll update this and will also update the logging for further dev troubleshooting on your end.

@MartijnR @pbowen-oc in the case of {event: 'signature-request-failed'}, could we update this to not show a message, and simply uncheck the box?

Alternatively, is there an approach we can take on our end (e.g. make a different response) that would result in the box getting unchecked, but no additional dialog appearing?

Looks good in testing