Debugging HTML Form Entry module to upload Images in the OpenMRS 2.x UI

@surangak @harsha89 @burke @dkayiwa @mogoodrich

@darius Sorry for the brief question. Here is a detailed version of what I have done

What I have done? I have analyzed how the old form submit works by monitoring the HTTP traffic of the web page. I have also done the same for the new UI. All form uploads are done using a http POST request with multipart/form-data enctype. But in the case of the new UI, all POST parameters except ones which contain files are being sent to the server. I then analyzed the reason for this.

How HTML form submit works. On the old UI, HTML form submit worked using just a plain HTTP POST request. But in the new UI this is handled using Javascript (on the htmlform.js script). Where multiple pre submit checks are performed and then the form data are submitted to the server using an Ajax request. Internally the formdata is serialized using the form.serialize() method provided by jQuery (https://api.jquery.com/serialize/) and sent to the server using an Ajax POST request also using jQuery.

Why Ajax is not working? In the new UI, the form.serialize() method that is being used does not work for “file” input types. Hence when I monitor requests made by the page when submitting the form I see that only other input types (“text” for example) are sent to the server but not the “file” types. Hence file uploading fails.

Suggestions Use the new XHR2 specification(http://www.html5rocks.com/en/tutorials/file/xhr2/) which supports file uploading via ajax requests. I tried this by replacing the ajax request in the htmlform.js file - but it seems that the Spring backend does not support this type of requests yet? (I have yet to verify that). And the server gives a HTML 500 error with the following stack trace. http://pastebin.com/C9jh8t5y

How to replicate this

1 ) I edited the htmlForm.js file inthe HTMLFormentryUI module in OpenMRS and re build it. replace the htmlForm.js file with the file here : https://github.com/surangak/HguSriLanka/blob/master/htmlForm.js in HTMLFormEntryUI module (Try with 1.5 version since that is the latest version in the latest standalone )

  1. Copy the hgu omod file to mdoules folder ( it has the jquery.form.js file required to the ajax calls) https://github.com/surangak/HguSriLanka/tree/master/hgu/omod/target

  2. Create an HTML form using this form : https://github.com/surangak/HguSriLanka/blob/master/upload.html

  3. Try uploading an image using the new UI of OpenMRS

then u will realize it would not work.

Please suggest me how to tackle this issue.

Thank you

@akshika47, thanks for taking the effort to pull this all together. It makes it a lot easier to digest and reply to. There are still a couple things you need to specify:

  1. What is the relevant edit that you made to htmlForm.js? Sharing the specific change, or a pointer to the specific line of code, will let someone see what is happening; nobody wants to read an entire file and guess what your changes are.
  2. What is the POST that is happening, for which the pastebin error happens? What URL did you post to? What was the data you posted?

Hi @darius thank you very much for looking in to this matter :slight_smile:

1 ) Changes are done to this file HguSriLanka/htmlForm.js at master · surangak/HguSriLanka · GitHub

and below are the changes.

Eariler Code :

    jq.post(form.attr('action'), form.serialize(), function(result) {
                if (result.success) {
                    if (result.goToUrl) {
                        emr.navigateTo({ applicationUrl: result.goToUrl });
                    } else {
                        goToReturnUrl(result.encounterId);
                    }
                } else {
                    enableSubmitButton();
                    for (key in result.errors) {
                        showError(key, result.errors[key]);
                    }
                    for (key in result.errors) {
                        jq(document).scrollTop(jq('#' + key).offset().top - 100);
                        break;
                    }
        
                  }
            }, 'json')
            .error(function(jqXHR, textStatus, errorThrown) {
               
                emr.errorAlert('Unexpected error, please contact your System Administrator: ' + textStatus);
            });

Current Code :

 $.ajax({
                url: form.attr('action'),
                data: new FormData(form.get(0)),
                type : "POST",
                contentType: false,
                processData: false,
                success :  function(result) {
                    if (result.success) {
                        if (result.goToUrl) {
                            emr.navigateTo({ applicationUrl: result.goToUrl });
                        } else {
                            goToReturnUrl(result.encounterId);
                        }
                    } else {
                        enableSubmitButton();
                        for (key in result.errors) {
                            showError(key, result.errors[key]);
                        }
                        for (key in result.errors) {
                            jq(document).scrollTop(jq('#' + key).offset().top - 100);
                            break;
                        }

                    }
                },
                error : function(jqXHR, textStatus, errorThrown) {
               
                    emr.errorAlert('Unexpected error, please contact your System Administrator: ' + textStatus);
                }
            });

2 ) Stack Trace : An Internal Error has Occurredjava.lang.RuntimeExceptionDon't know how to - Pastebin.com Return URL : /openmrs-standalone/coreapps/patientdashboard/patientDashboard.page?patientId=153&encounterId=1251&encounterId =1252&encounterId=1253&encounterId=1254&visitId=529&

This is the screen shot of the POST request of the image upload before the change in the htmlForm.js in the old UI

This is the screen shot of the POST request of the image upload before the change in the htmlForm.js in the new UI

This is the screen shot of the POST request of the image upload after the change in the htmlForm.js in the old UI

This is the screen shot of the POST request of the image upload after the change in the htmlForm.js in the new UI

Here are some screen shots in the failing case

SS of Params :

SS of Headers

SS of HTML

Hi @darius,

Did you manage to find a solution? are these details enough to come to a conclusion? :slight_smile:

Thank you in advance :smiley:

@akshika47, I have not had a chance to look at this, and won’t really.

My recommendation would be that you run under a debugger, put a breakpoint on FragmentActionController:252 (in the uiframework module) and explore what is going wrong there.

Peeking at the uiframework code I wonder if the problem is that your request doesn’t say Accept: application/json (see here).

@akshika47 use the latest snapshot version of the uiframework module and test again. Then tell us what happens.