FSM Signature Pad on Work Order Task

Kelly Logan
Kilo Sage

The requirement is to have a signature used as proof of service, required to close a Work Order Task. 

We created a new UI Page, u_wot_accept_signature, along with UI Actions to call it and templates, all copied from the OOB Work Order versions. The primary issue is that in addition to the copied 'Accept' and 'Cancel' buttons, we want to have a 'Reject' button as well that diverts to a different state. 

 

The question is, how to address this in the HTML and Processing scripts, preferably without having to create a new version of /scripts/wo_signature_pad.jsx (because, frankly it is still unclear to me how to do that without setting up an entirely new development suite and starting the whole thing over). 

 

I believe the critical action is to set the HTML input 'btn_clicked' to the value "reject" so that this can be picked up in the Processing script. For the 'Accept' and 'Cancel' buttons, this is handled in /scripts/wo_signature_pad.jsx, but it seems like I should be able to duplicate this. Currently, the button seems unresponsive. Nothing seems to happen when I click it. 

 

Ideas, experience greatly appreciated. 

 

Here are details on where I am at now:

 

Here is a current HTML entry from the UI Page:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
    <g:evaluate var="jvar_color_red">
        var map = CSSPropertiesRepository.getSessionProperties();
        map["$color-red"];
    </g:evaluate>
    <j:if test="$[jvar_isMSIE8 || jvar_isMSIE7]">
        <g:requires name="scripts/flashcanvas.jsx" includes="true" />
    </j:if>
    <j:if test="${GlideMobileExtensions.getDeviceType() != 'doctype'}">
        <g:requires name="scripts/lib/jquery_includes.jsx" includes="true" />
    </j:if>
    <g:requires name="scripts/jquery.signaturepad.min.jsx" includes="true" />
    <g:requires name="scripts/wo_signature_pad.jsx" includes="true" />
    <!-- <g:include_script src="wo_signature_pad.jsdbx"/> -->
    <g:requires name="styles/jquery.signaturepad.cssx" includes="true" />
    <g:requires name="styles/heisenberg/heisenberg_all.cssx" includes="true" />
    <g:requires name="scripts/classes/ajax/GlideAjax.jsx" includes="true" />

    <g:ui_form>
        <j:set var="jvar_sys_id" value="${RP.getWindowProperties().get('sys_id')}" />
        <input type="hidden" id="sysparm_init_type" value="drawIt" />
        <input type="hidden" id="sysparm_retrieve_signature" value="false" />
        <input type="hidden" id="sysparm_line_top" value="100" />
        <input type="hidden" id="sysparm_signeename_required" value="true" />
        <input type="hidden" id="sysparm_draw_only" value="true" />
        <input type="hidden" id="document_id" name="document_id" value="${RP.getWindowProperties().get('document_id')}"></input>
        <input type="hidden" id="table_name" name="table_name" value="${RP.getWindowProperties().get('table_name')}"></input>
        <div class="sigPad">
            <j:if test="${sysparm_draw_only != 'true'}">
                <div class="typeItDesc">
                    <label for="name">${gs.getMessage('Name')}</label>
                    <input type="text" name="signed_name" id="signed_name" class="signed_name" />
                </div>
                <div class="drawItDesc" style="display:block;">
                    <label for="signee_name" aria-label="${gs.getMessage('Name, mandatory')}">${gs.getMessage('Name')}<span style="color: ${jvar_color_red};">*</span></label>
                    <input aria-required="true" type="text" name="signee_name" id="signee_name" class="signed_name" />
                </div>
                <p class="typeItDesc">${gs.getMessage('Signature')}</p>
                <label for='pad' aria-label="${gs.getMessage('Signature, mandatory')}" class="drawItDesc" style="display:block;">${gs.getMessage('Signature')}<span style="color: ${jvar_color_red};">*</span></label>

            </j:if>
            <j:if test="${sysparm_draw_only == 'true'}">
                <p class="drawItDesc" style="display:block;">${gs.getMessage('Draw your signature')}</p>
                <div class="sigNav" style="display:block;">
                    <!-- <a class="clearButton" href="#clear">${gs.getMessage('Clear')}</a> -->
                </div>
            </j:if>
            <div class="sig sigWrapper" style="display:block;">
                <div class="typed"></div>
                <canvas class="pad" name="pad" id='pad' width="400" height="150"></canvas>
                <input type="hidden" aria-label="${gs.getMessage('Signature Image')}" name="current_sys_id" value="${jvar_sys_id}" />
                <input type="hidden" aria-disabled="true" name="output" class="output" />
            </div>
            <p style="text-align:right; margin-top: 10px;"><a class="clearButton btn btn-default" href="#clear">${gs.getMessage('Clear')}</a></p>
            <p />
            ${gs.getMessage('Filling in the information will constitute your eSignature and will have the same legal impact as signing a printed version of this document.')}
            <div style="float:right">
                <button id='cancelSignature' data-dismiss="GlideModal" onclick="return onCancelSignature();" class="btn btn-default" style="margin-right:10px;">${gs.getMessage('Cancel')}</button>
                <button id='rejectSignature' onclick="return onRejectSignature();" class="btn btn-danger" style="margin-right:10px;">${gs.getMessage('Reject')}</button>
                <button id='acceptSignature' onclick="return onAcceptSignature();" class="btn btn-primary">${gs.getMessage('Accept')}</button>
                <input type="hidden" id="btn_clicked" name="btn_clicked" value="none"></input>
            </div>
        </div>
    </g:ui_form>
    <script>
        function onRejectSignature() {
            gel("btn_clicked").value = "reject";
            return false;
        }
    </script>
</j:jelly>

 

Note the buttons are declared on lines 59-61, along with the input 'btn_clicked' on line 62. I have tried to duplicate the action of 

onclick="return onAcceptSignature();"

with a custom one

<button id='rejectSignature' onclick="return onRejectSignature();" class="btn btn-danger" style="margin-right:10px;">${gs.getMessage('Reject')}</button>

that calls a scripted function I have added at the end

    <script>
        function onRejectSignature() {
            gel("btn_clicked").value = "reject";
            return false;
        }
    </script>

This is meant to duplicate the action of the similar functions declared in /scripts/wo_signature_pad.jsx

function doSubmit(submit) {
	if (submit)
		gel("btn_clicked").value = "ok";
	else 
		gel("btn_clicked").value = "cancel";
}

function onCancelSignature() {
	doSubmit(false);
	return false;
}

 

 

1 ACCEPTED SOLUTION

Kelly Logan
Kilo Sage

The answer does seem to be that the onAcceptSignature() method in the system script was closing the modal, so we duplicated this by adding a GlideModal.close() action to the onRejectSigature() function that we declared in the HTML. So the button and script section now looks like this:

            <div style="float:right">
                <button id='cancelSignature' data-dismiss="GlideModal" onclick="return onCancelSignature();" class="btn btn-default" style="margin-right:10px;">${gs.getMessage('Cancel')}</button>
                <button id='rejectSignature' onclick="return onRejectSignature();" class="btn btn-danger" style="margin-right:10px;">Reject</button>
                <button id='acceptSignature' onclick="return onAcceptSignature();" class="btn btn-primary">${gs.getMessage('Accept')}</button>
                <input type="hidden" id="btn_clicked" name="btn_clicked" value="none"></input>
            </div>
        </div>
    </g:ui_form>
    <script>
        function onRejectSignature() {
            gel("btn_clicked").value = "reject";
			// document.getElementById("btn_clicked").value = "reject";
			var gm = GlideModal.get();
			gm.close();
			return false;
        }
    </script>
</j:jelly>

The close() method closes the modal while still running the closure workflow, in this case the Processing script that then updates the state of the Work Order Task. Here is the current working version of the Reject section:

    if (btn_clicked == 'reject') {
		
        response.sendRedirect(gs.getSession().getStack().bottom());

		gs.addInfoMessage('The task has been rejected for review');

        if (wot.get(document_id)) {
            wot.state = 22; //Rejected for Review
			wot.update();
        }

    }



View solution in original post

5 REPLIES 5

Kelly Logan
Kilo Sage

H/t to Mike Hashemi for providing critical troubleshooting methods and working through this with me.