Uploaded image for project: 'Jira Service Management Data Center'
  1. Jira Service Management Data Center
  2. JSDSERVER-6029

Custom error message from validator does not display for JSD workflows or projects when using third party apps

    XMLWordPrintable

Details

    Description

      Summary

      When using a third party app (e.g. JMWE) for adding comment validator in a JSD workflow with transition screen, the customer input error message is not displayed in the transition screen unlike non JSD projects. This is a regression from earlier JSD versions, which, since 3.0.0, were correctly displaying the error message.

      Steps to reproduce

      1. Spawn Jira 7.12.1 and JSD 3.15.1 (the latest)
      2. On a Jira Service Desk workflow, on a transition that has a transition screen, add a "Comment Required Validator" from JMWE (for example - a similar Validator from another app will have the same problem)
      3. Trigger the transition, don't input a comment and hit "Submit"
      4. No error message is displayed but the form remains open

      If you do the same on a non-JSD workflow, the error message is displayed correctly below the comment field

      Investigation Notes

      • Initially both screens does not have the div.error element to populate the error message
      • Difference between Non JSD and JSD projects:
        • both calls the _submitForm function in FormDialog.js:
          FormDialog.js
          _submitForm: function _submitForm(e) {
              this.cancelled = false;
              this.xhr = null;
              this.redirected = false;
              this.serverIsDone = false;
          
              var instance = this;
              var defaultRequestOptions = jQuery.extend(true, {}, this.options.submitAjaxOptions);
          
              var requestOptions = jQuery.extend(true, defaultRequestOptions, {
                  url: this._getPath(this.$form.attr("action")),
                  data: this._getFormDataAsObject(),
                  complete: function complete(xhr, textStatus, smartAjaxResult) {
                      instance.hideFooterLoadingIndicator();
          
                      if (!instance.cancelled) {
                          instance._showMessagesFromXhrResponse(xhr);
                          if (smartAjaxResult.successful) {
                              instance.$form.trigger("fakesubmit");
                              instance._handleServerSuccess(smartAjaxResult.data, xhr, textStatus, smartAjaxResult);
                              //
                              // if we have already been redirected then the page is asynchronously unloading and going elsewhere
                              // and hence we should not do the complete processing since its pointless and could only do harm
                              //
                              if (!instance.redirected) {
                                  instance._handleSubmitResponse(smartAjaxResult.data, xhr, smartAjaxResult);
                              }
                          } else {
                              instance._handleServerError(xhr, textStatus, smartAjaxResult.errorThrown, smartAjaxResult);
                          }
                      }
                      //The form may have changed. Lets just make sure there us no 'submitting' class to be extra sure.
                      instance.$form.removeClass("submitting");
                  }
              });
          
              // and since we're a dialog, and since web actions don't offer responses tailored to the accepts header, we should always set these request options:
              requestOptions.data.decorator = "dialog";
              requestOptions.data.inline = true;
          
              this.showFooterLoadingIndicator();
          
              this.xhr = SmartAjax.makeRequest(requestOptions);
          
              e.preventDefault();
          },
          
        • However, smartAjaxResult.data passed to the requestOptions callback from non JSD contains the error message which is replaced as a content in instance._handleServerSuccess(smartAjaxResult.data, xhr, textStatus, smartAjaxResult) :
          FormDialog.js
          _handleServerSuccess: function _handleServerSuccess(data, xhr, textStatus, smartAjaxResult) {
              var msgInstructions = this._detectMsgInstructions(xhr);
          
              if (msgInstructions) {
                  Messages.showMsgOnReload(msgInstructions.msg, {
                      type: msgInstructions.type,
                      closeable: msgInstructions.closeable,
                      target: msgInstructions.target
                  });
              }
          
              //
              // Check the status of the X-Atlassian-Dialog-Control header to see if we are done
              //
              var instructions = this._detectRedirectInstructions(xhr);
              this.serverIsDone = instructions.serverIsDone;
          
              if (instructions.redirectUrl) {
                  if (this.options.onSuccessfulSubmit) {
                      this.options.onSuccessfulSubmit.call(this, data, xhr, textStatus, smartAjaxResult);
                  }
                  this._performRedirect(instructions.redirectUrl);
              } else if (!this.serverIsDone) {
                  this.setSubmitResponseContent(data);
              }
          },
          
        • Non JSD smartAjaxResult.data value contains user input error message: "<div class="error">Anne - Non JSD Comment required!</div>":
          "
          <div class="jira-dialog-content">
              <div class="dialog-title hidden">Start Progress [PROJ-1]</div>
          
              <form action="/jira/secure/CommentAssignIssue.jspa?atl_token=BWP3-NZB2-6EDY-6C7K_70517b4464110e3b3d3983abaad5880372d16c43_lin" class="aui dnd-attachment-support" enctype="multipart/form-data" id="issue-workflow-transition" method="post">
                  <div class="form-body">
          
                      <h2 class="dialog-title">
          
                          Start Progress
          
          </h2>
          
                      <div class="hidden">
                          <input name="action" type="hidden" value="11" />
                      </div>
          
                      <div class="hidden">
                          <input name="id" type="hidden" value="10002" />
                      </div>
          
                      <div class="hidden">
                          <input name="viewIssueKey" type="hidden" value="" />
                      </div>
          
                      <div class="hidden">
                          <input name="formToken" type="hidden" value="e2f45e34e0e56241a89d304a7ce5092ce8c271e5" />
                      </div>
          
                      <div class="field-group aui-field-wikiedit comment-input">
                          <label for="comment">Comment</label>
          
                          <div class="jira-wikifield" field-id="comment" renderer-type="atlassian-wiki-renderer" issue-key="PROJ-1">
                              <div class="wiki-edit">
                                  <div id="comment-wiki-edit" class="wiki-edit-content">
                                      <textarea class="textarea long-field wiki-textfield mentionable" cols="60" id="comment" name="comment" rows="10" wrap="virtual" data-projectkey="PROJ" data-issuekey="PROJ-1"></textarea>
                                      <div class="rte-container">
                                          <rich-editor contenteditable="true" data-issue-key="PROJ-1" data-content-present="true" tabindex="-1"></rich-editor>
                                      </div>
                                      <div class="content-inner">
                                      </div>
                                  </div>
                              </div>
                              <div class="field-tools">
                                  <dl id="wiki-prefs" class="wiki-js-prefs" style="display:none">
                                      <dt>trigger</dt>
                                      <dd>comment-preview_link</dd>
                                      <dt>fieldId</dt>
                                      <dd>comment</dd>
                                      <dt>fieldName</dt>
                                      <dd>Comment</dd>
                                      <dt>rendererType</dt>
                                      <dd>atlassian-wiki-renderer</dd>
                                      <dt>issueKey</dt>
                                      <dd>PROJ-1</dd>
                                  </dl>
                                  <button class="jira-icon-button fullscreen wiki-preview" id="comment-preview_link" type="button">
                                      <span class="aui-icon wiki-renderer-icon">Preview comment</span>
                                  </button>
                                  <a class="help-lnk" id="viewHelp" href="/jira/secure/WikiRendererHelpAction.jspa?section=texteffects" title="Get local help about wiki markup help" data-helplink="local"><span class="aui-icon aui-icon-small aui-iconfont-help"></span></a>
                              </div>
                          </div>
                          <div class="save-options wiki-button-bar">
                              <div class="security-level">
                                  <fieldset class="hidden parameters">
                                      <input type="hidden" title="securityLevelViewableByAll" value="Viewable by All Users">
                                      <input type="hidden" title="securityLevelViewableRestrictedTo" value="Restricted to <span class='redText'>{0}</span>">
                                  </fieldset>
                                  <a class="drop" href="#">
                                      <span class="security-level-drop-icon aui-icon aui-icon-small  aui-iconfont-unlocked">
                          This comment will be Viewable by All Users
                      </span>
                                      <span class="icon drop-menu"></span>
                                  </a>
                                  <select name="commentLevel" id="commentLevel" data-enable-default="true">
                                      <option value="">All Users</option>
                                      <optgroup label="Project Roles">
                                          <option value="role:10002">Administrators</option>
                                      </optgroup>
                                  </select>
                                  <span class="current-level">Viewable by All Users</span>
                                  <span class="default-comment-level" data-project-id="10000"></span>
                              </div>
                              <span class="security-level-inline-error"></span>
                          </div>
          
                          <div class="error">Anne - Non JSD Comment required!</div>
                      </div>
              <!-- more code here... -->
              </form>
              <!-- // .aui.dnd-attachment-support #issue-workflow-transition -->
          
          </div>
          "
          
        • JSD returned smartAjaxResult.data value does not contain the error:
          "
          
          <div class="jira-dialog-content">
              <div class="dialog-title hidden">In progress [BS-2]</div>
          
              <form action="/jira/secure/CommentAssignIssue.jspa?atl_token=BWP3-NZB2-6EDY-6C7K_70517b4464110e3b3d3983abaad5880372d16c43_lin" class="aui dnd-attachment-support" enctype="multipart/form-data" id="issue-workflow-transition" method="post">
                  <div class="form-body">
          
                      <h2 class="dialog-title">
          
                          In progress
          
          </h2>
          
                      <div class="hidden">
                          <input name="action" type="hidden" value="891" />
                      </div>
          
                      <div class="hidden">
                          <input name="id" type="hidden" value="10001" />
                      </div>
          
                      <div class="hidden">
                          <input name="viewIssueKey" type="hidden" value="" />
                      </div>
          
                      <div class="hidden">
                          <input name="formToken" type="hidden" value="d4fa0340cfb2e7648e721bd28688f66850e18675" />
                      </div>
          
                      <div class="sd-comment-field-edit-root" data-payload="{&quot;issueId&quot;:10001,&quot;issueKey&quot;:&quot;BS-2&quot;,&quot;reporterDisplayName&quot;:&quot;admin&quot;,&quot;comment&quot;:&quot;&quot;,&quot;userKey&quot;:&quot;admin&quot;,&quot;userName&quot;:&quot;admin&quot;,&quot;agentDisplayName&quot;:&quot;admin&quot;,&quot;avatarUrl&quot;:&quot;https://www.gravatar.com/avatar/64e1b8d34f425d19e1ee2ea7236d3028?d\u003dmm\u0026s\u003d48&quot;,&quot;isAgent&quot;:true,&quot;isExternalMode&quot;:true,&quot;isEdit&quot;:false,&quot;isBulkEdit&quot;:false,&quot;isRteEnabled&quot;:true,&quot;modifierKey&quot;:&quot;Ctrl+Alt&quot;,&quot;errors&quot;:[],&quot;isSecurityLevelAvailable&quot;:false}"></div>
          
                      <div class="hidden">
                          <input name="atl_token" type="hidden" value="BWP3-NZB2-6EDY-6C7K_70517b4464110e3b3d3983abaad5880372d16c43_lin" />
                      </div>
          
                  </div>
          
                  <div class="buttons-container form-footer">
                      <div class="buttons">
          
                          <input accesskey="s" class="aui-button" id="issue-workflow-transition-submit" name="Transition" title="Press Ctrl+Alt+s to submit this form" type="submit" value="In progress" />
          
                          <a accesskey="`" class="aui-button aui-button-link cancel" href="/jira/browse/BS-2" id="issue-workflow-transition-cancel" title="Press Ctrl+Alt+` to cancel">Cancel</a>
          
                      </div>
          
                  </div>
          
              </form>
              <!-- // .aui.dnd-attachment-support #issue-workflow-transition -->
          
          </div>
          "
          
        • And the _handleServerSuccess sets the content to the data in: this.setSubmitResponseContent(data);
          _handleServerSuccess: function _handleServerSuccess(data, xhr, textStatus, smartAjaxResult) {
              var msgInstructions = this._detectMsgInstructions(xhr);
          
              if (msgInstructions) {
                  Messages.showMsgOnReload(msgInstructions.msg, {
                      type: msgInstructions.type,
                      closeable: msgInstructions.closeable,
                      target: msgInstructions.target
                  });
              }
          
              //
              // Check the status of the X-Atlassian-Dialog-Control header to see if we are done
              //
              var instructions = this._detectRedirectInstructions(xhr);
              this.serverIsDone = instructions.serverIsDone;
          
              if (instructions.redirectUrl) {
                  if (this.options.onSuccessfulSubmit) {
                      this.options.onSuccessfulSubmit.call(this, data, xhr, textStatus, smartAjaxResult);
                  }
                  this._performRedirect(instructions.redirectUrl);
              } else if (!this.serverIsDone) {
                  this.setSubmitResponseContent(data);
              }
          },
          

      Workaround

      None

      Related tickets

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              acalantog Anne Calantog
              Votes:
              28 Vote for this issue
              Watchers:
              18 Start watching this issue

              Dates

                Created:
                Updated:

                Backbone Issue Sync