Custom form submit gives "Not Found The requested URL /interface/forms/DM2FU/save.php was not found on this server."

I am trying to figure out how to create custom forms, and I am not having much luck. I thought I would just rename the ‘soap_form’ (copy the directory and change ‘soap’ to ‘dm2fu’ everywhere in the source. The original ‘soap’ file works well (I use it from time to time).

I tried that, and the first issue I encountered was on 6.0.0(3) running on AWS Ubuntu 18.04 LTS. The forms administration page would not recognize that my new directory (custom form) was there. I made sure that the ownership was apache:apache and that the appropriate file permissions were set. Only two forms appeared in the unregistered list, and my new form was not one of them. I have quite a few forms that I have tried from contrib, so there are many registered to begin with (maybe 40 and several disabled).

No worries, I simply added my new form to the registry table with disabled, etc, flags set. I was then able to see the new custom form, do the DB table creation, and enable the form. Adding the form to an encounter also seemed to go well, until I "submit"ed my form. That’s when I encountered the following error instead of the collapsed list of forms of the encounter that I was expecting:

Not Found
The requested URL /interface/forms/DM2FU/save.php was not found on this server.

That file is there. I made sure that the ownership was apache:apache and that the appropriate file permissions were set. You can examine all the files here: GitHub - ralflukner/dm2_fu_form: OpenEMR Diabetes Mellitus Type 2 follow-up form

Not easily discouraged, I tried a recent development openemr (6.1.0) on Ubuntu 20.04 focal (minimal). This time, the unregistered form showed up as expected, I was able to register it, create the DB table, and activate the form without any need to go directly into database tables (such as registry). My error was slightly different (no mention of the file).

Not Found
The requested URL was not found on this server.

On the development server, I also tried copying and renaming example2 from contrib/forms. Same result. I even tried implementing example2 “as is” (no renaming), and that gave the same Not Found … URL error. Now I’m wondering if I need to tackle an Xdebug session, but before I go down that road … any suggestions?
–RBL

Compare the code for the two scripts with the save button. You are missing the emr root prefix. The url should be something like emr/interface/… Global variable maybe called something web_root or webroot(?).
Best

$GLOBALS[‘web_root’] . /interface/forms/DM2FU/save.php;

1 Like

My form files are identical to the working SOAP form files except for the comments and the names are changed to reflect the different names of my form. I’m not sure why the SOAP form works and my new custom form fails. I also encountered the URL Not Found error on a 6.1.0 dev system when I put the untouched contrib/example2 form directory into the interface/forms/ directory. Thus, it does not appear to be an issue only with my custom forms.

In the meantime, I will modify existing working forms and try to get Xdebug working to further troubleshoot this until I can figure out how to add my own forms without encountering the URL Not Found

Also, the HTML Template looks correct. 6.0.0(3) production complains that the following URL cannot be found, which is really odd:
/interface/forms/DM2FU/save.php

I did not have any trouble when I tried making a new form based on the care plan form (which does not use the form class and “c form class.” I will explore the non-object-oriented design forms and see if I can get a copy of an existing one of those to do my bidding for a diabetes type 2 follow-up visit form.

It is pretty clear that a number of forms (such as the bronchitis form, for example) no longer work. I will try to find forms that do work and try to emulate those for my new custom form.

<html>
<head>
<title>{xlt t='DM2FU'}</title>
{headerTemplate}
</head>
<body>
    <div class="container mt-3">
        <div class="row">
            <div class="col-12">
                <h2>{xlt t='DM2FU'}</h2>
                <form name="DM2FU" method="post" action="{$FORM_ACTION}/interface/forms/DM2FU/save.php" onsubmit="return top.restoreSession()">
                    <input type="hidden" name="csrf_token_form" value="{$CSRF_TOKEN_FORM|attr}" />
                    <fieldset>
                        <legend>{xlt t='Subjective'}</legend>
                        <div class="container">
                            <div class="form-group" >
                                <textarea name="subjective" class="form-control" cols="60" rows="6" onkeyup="top.isDM2FUEdit = true;">{$data->get_subjective()|text}</textarea>
                            </div>
                        </div>
                    </fieldset>
                    <fieldset>
                        <legend>{xlt t='Objective'}</legend>
                        <div class="container">
                            <div class="form-group">
                                <textarea name="objective" class="form-control" cols="60" rows="6" onkeyup="top.isDM2FUEdit = true;">{$data->get_objective()|text}</textarea>
                            </div>
                        </div>
                    </fieldset>
                    <fieldset>
                        <legend>{xlt t='Assessment'}</legend>
                        <div class="container">
                            <div class="form-group">
                                <textarea name="assessment" class="form-control" cols="60" rows="6" onkeyup="top.isDM2FUEdit = true;">{$data->get_assessment()|text}</textarea>
                            </div>
                        </div>
                    </fieldset>
                    <fieldset>
                        <legend>{xlt t='Plan'}</legend>
                        <div class="container">
                            <div class="form-group">
                                <textarea name="plan" class="form-control" cols="60" rows="6" onkeyup="top.isDM2FUEdit = true;">{$data->get_plan()|text}</textarea>
                            </div>
                        </div>
                    </fieldset>
                    <div class="form-group">
                        <div class="btn-group" role="group">
                            <button type="submit" class="btn btn-primary btn-save" name="Submit">{xlt t='Save'}</button>
                            <button type="button" class="btn btn-secondary btn-cancel" id="btnClose">{xlt t='Cancel'}</button>
                        </div>
                        <input type="hidden" name="id" value="{$data->get_id()|attr}" />
                        <input type="hidden" name="activity" value="{$data->get_activity()|attr}" />
                        <input type="hidden" name="pid" value="{$data->get_pid()|attr}" />
                        <input type="hidden" name="process" value="true" />
                    </div>
                </form>
            </div>
        </div>
    </div>
    {literal}
    <script>
        const close = function() {
            if (top.isDM2FUEdit === true) {
                dlgopen('', '', 450, 125, '', '<div class="text-danger">{/literal}{xla t='Warning'}{literal}</div>', {
                    type: 'Alert',
                    html: '<p>{/literal}{xla t='Do you want to close the tabs?'}{literal}</p>',
                    buttons: [
                        {text: '{/literal}{xla t='Cancel'}{literal}', close: true, style: 'default btn-sm'},
                        {text: '{/literal}{xla t='Close'}{literal}', close: true, style: 'danger btn-sm', click: closeDM2FU},
                    ],
                    allowDrag: false,
                    allowResize: false,
                });
            } else {
                top.restoreSession();
                location.href = 'javascript:parent.closeTab(window.name, false)';
            }
        }

        const closeDM2FU = function() {
            top.isDM2FUEdit = false;
            top.restoreSession();
            location.href = 'javascript:parent.closeTab(window.name, false)';
        }
        $('#btnClose').click(close);
    </script>
    {/literal}
</body>
</html>

I figured out the problem. The form name appears in UPPERCASE and lowercase in various locations. I was careless with the replacement case, and this caused the new custom form to stop working. I started with a copy of the soap form again and then made sure I replaced SOAP with DM2_FU_01 and soap with dm2_fu_01 and the form then worked perfectly.