Question

I am working with an older JSP application. There is a custom build dojo which we are using for the modalDialog. The user enters the application and types information into the form. When a new student needs to be added they enter a modal dialog box where they can add a edit a list populated from the database. Once changes are made they can save, (saved to database before modal dialog close.) providing they pass the validation.

When the original form is completed they submit the form for additional validation. The user was bypassing the validation on the edit students page by closing the modal dialog without saving. I pulled the updated information (dojo.xhrGet) and stored it in hidden elements so that updated/un-altered student information could be validated on submit.

The div is populated with hidden html input elements and they validate just fine. That is unless the user hits submit before viewing/adding/altering the information within the modalDialog page and they receive the errors preventing submit. If they then return to the modal dialog they are unable to submit, the checkboxes do not validate as true or checked on either page after the first failed submit. We can add/edit students to/on a list and for the list of students one minimum needs "must sign" selected.

I have searched around for a while but have not found anything that is really the same issue I am having.

Stack overflow title "Update form fields with dojo.xhrGet causes dijit.checkbox to be readonly" Attempted to change to dojo.place() and this did not change anything.

I looked at the checkboxes since that is what seems to be catching the validation errors. They are selected and yet they validate as false. Stack overflow title "My checkbox will not check when clicked"

I found another that seems like a similar problem, without code examples I am not sure how to move forward with changing my own code. Stack overflow title "Struts2 Validation - Repopulate Children when validation fails"

When submit fails validation it does not load the div element returned from dojo.xhrGet. Form fails validation of Boolean.

I included only the relevant section of validation on the modal dialog as regards the student :

<script type="text/javascript">

function validateForm()
{
   //Other non-relevant validation for this page removed from example.

    var errors = [];
    var form = dojo.byId("studentForm");

    <s:if test="work.isTeam">   
        var index = 0;
        var hasStudent = false;
        var hasPermission = false;

        while (true)
        {
            if (!dojo.byId("student" + index + ".name"))
            {
                break;
            } 
            else
            {
                hasStudent = true;
                if (form.elements.namedItem("student" + index + ".mustSign").checked == "true")
                {
                    hasPermission = true;
                }
            }
            index++;
        }
        if (!hasStudent)
        {
            errors[errors.length]="At least 1 student is required.";
        }
        if (!hasPermission)
        {
            errors[errors.length]="At least 1 student must be able to sign.";
        }
    </s:if>
}
<script>

The main form script to open the modal Dialog and the refreshStudents() function called on Submit.

<td align="center">
    <input type="button" name="Checkin" value="Complete" onclick="dojo.byId('completing').value='true'; refreshStudents(); validateForm();"/>
</td>

The validation is nearly identical for the main page. The only difference is that we collect the value of must sign since it is a text element returned from dojo.xhrGet

<script type="text/javascript">

    function editStudents()
     {
        try 
        {
            turnOffDojo();

            var classId = dojo.byId("classId").value;
            var url = "<s:url action='ShowStudents' namespace='/files' includeParams='none'/>?classId=" + classId;
            openModalDialog("StudentsDialog", url, "students", 550, 300);

        }
        catch (Exception)
        {
            createDojoAlert("Edit students (error)", Exception);
        }
    }

    function refreshStudents() 
    {
        <s:if test="work.isTeam">           
            var loopTR = document.createElement("TR");
            loopTR.innerHTML="Loading Data..."; 

            dojo.byId("studentsDiv").innerHTML="";
            dojo.byId("studentsDiv").appendChild(loopTR);

            var classId = dojo.byId("classId").value;
            var url = "<s:url action='LoadStudents' namespace='/files' includeParams='none'/>?classId=" + classId;

            dojo.xhrGet({
                preventCache: true,
                url: url,
                load: function(result) 
                {
                    try 
                    {
                        loopTR.innerHTML="";
                        dojo.byId("studentsDiv").innerHTML= result;
                    }
                    catch (Exception) 
                    {
                        createDojoAlert("Refresh students (catch block)","<li>Error: " + Exception + "</li>");
                    }
                },
                error: function(error) 
                { 
                    createDojoAlert("Refresh students (dojo error)","<li>Error: " + error + "</li>");
                }
            });
        </s:if >
    }

<script>
Was it helpful?

Solution

Updates are as follows:

Dom cleanup --Removal of the use of innerHTML usage in refreshStudents() as it could cause issues with getElementById(). Reference(Why is "element.innerHTML+=" bad code?) Removal of un-necessary variables. Added handleAs so that the page knows how to process the response and set a timeout.

Update to HTML to call refreshStudents() only when work is relevant for team work. In instances where team work is relevant, Call validateForm() only after successful response from refreshStudents(). If team work is not relevant for the type of work then validateForm().

function refreshStudentsAndValidate() 
{
    <s:if test="work.isTeam">           
        dojo.byId("studentsDiv").innerHTML="";

        var classId = dojo.byId("classId").value;
        var url = "<s:url action='LoadStudents' namespace='/files' includeParams='none'/>?classId=" + classId;

        dojo.xhrGet({
            url: url,
            handleAs: "text",
            timeout: 10000, //Time in milliseconds (10 secs)
            load: function(result) 
            {
                try 
                {
                    dojo.html.set(dojo.byId("studentsDiv"), result);
                    // now call validation...
                    validateForm();
                }
                catch (Exception) 
                {
                    createDojoAlert("Refresh students (catch block)","<li>Error: " + Exception + "</li>");
                }
            },
            error: function(error) 
            { 
                createDojoAlert("Refresh students (dojo error)","<li>Error: " + error + "</li>");
            }
        });
    </s:if >
}

Updates to HTML as follows, use of struts2:

<td align="center">
    <input type="button" class="button" name="Checkin" value="Complete" onclick="dojo.byId('completing').value='true'; <s:if test="work.isTeam"> refreshStudentsAndValidate();</s:if><s:else> validateForm(); </s:else>" />
</td>

In summary, the root cause was the refreshStudents() function. Due to the use of dojo.xhrGet making an asynchronous request the page was not receiving the response before the validation code was executed. Because we only need to check the students for cases where the work is team related the struts2 if/else was added for use of the appropriate function when the user presses the button to complete the work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top