My goal is to produce a custom buttom, on clicking which a dialog with some checkboxes and text fields will be shown. After the user enters all the information and clicks the confirm button, another REST endpoint will be called which should take the information and do something I really want. All these things should be done within Script Runner.
As far as I know, the process should be:
1. create a "Custom web item" which "Run code and display a dialog"
2. create a corresponding REST endpoint script containing some HTML
3. create the second REST endpoint script which does things I want
4. finish the interaction details of the script in step2
Now I already have the second REST endpoint script (which is responsible for some integration between JIRA and other services), so what I need is to make a dialog, require some information and call the other endpoint when the confirm button is clicked. I understand that this requires some Javascript, but I find myself stuck just at the beginning which is making the javascript cooperate with the HTML part, or more exactly the groovy script. I've done quite a lot searching but since I'm both new to javascript and HTML there are just too many concepts which make me really confused.
I took the example from here https://scriptrunner.adaptavist.com/latest/jira/fragments/WebItem.html and made my endpoint code so:
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate import groovy.transform.BaseScript import javax.ws.rs.core.MediaType import javax.ws.rs.core.MultivaluedMap import javax.ws.rs.core.Response @BaseScript CustomEndpointDelegate delegate showDialog() { MultivaluedMap queryParams -> def sprintId = queryParams.getFirst("sprintId") as String; def boardId = queryParams.getFirst("boardId") as String; // get a reference to the current page... // def page = getPage(queryParams) def dialog = """ <section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true"> <header class="aui-dialog2-header"> <h2 class="aui-dialog2-header-main">Create IMS Checkpoint</h2> <a class="aui-dialog2-header-close"> <span class="aui-icon aui-icon-small aui-iconfont-close-dialog">Close</span> </a> </header> <div class="aui-dialog2-content"> <div id="container" style="width:px"> <form class="aui"> <div id="projects" style="height:220px;width:280px;float:left;"> <p>Please select the project:</p> <p> <input class="checkbox" type="checkbox" name="project" value="projectA">MB_213_16_PSCM_ECU</input><br> <input class="checkbox" type="checkbox" name="project" value="projectB">MB_213_16_PSCM_CCC</input><br> <input class="checkbox" type="checkbox" name="project" value="projectC">MB_223_19_PSCM_ECU</input><br> <input class="checkbox" type="checkbox" name="project" value="projectD">MB_223_16_PSCM_CCC</input><br> </p> </div> <div id="description" style="height:220px;width:280px;float:left;"> <p>Please enter the description information:</p> <p>Info1: <input id="input1" class="text" type="text" name="descriptionInfo1"></input><br> Info2: <input id="input2" class="text" type="text" name="descriptionInfo2"></input><br></p> </div> </form> </div> </div> <footer class="aui-dialog2-footer"> <div class="aui-dialog2-footer-actions"> <button id="submit-button" class="aui-button aui-button-primary">Confirm</button> <button id="dialog-close-button" class="aui-button aui-button-link">Close</button> </div> <div class="aui-dialog2-footer-hint">Some hint here if you like</div> </footer> </section> """ Response.ok().type(MediaType.TEXT_HTML).entity(dialog.toString()).build() }
The script works fine and will create a dialog with checkboxes, textfields and a confirm button. Then comes the problem, I have no idea how to combine it with a javascrpt specifically. For instance, it is written on the page that The button with the ID dialog-close-button will be automatically wired to close when clicked if you use a dialog ID of sr-dialog. If you require more complex interactions you should require some javascript and wire the elements: I really have no idea how to wire the elements.
And the You must explicitly require the web resource key on https://docs.atlassian.com/aui/latest/docs/dialog2.html makes me even more confused because I didn't see it in the example above. If I do a little bit more digging into it I will just find many things about XML which are apparently not what I want. Reading the web resource fragment and Web Resource Plugin Module won't help too.
Actually there is already a question where @Roberto Saltini wanted to do similar things How to call a script runner REST endpoint from a custom Dialog connecte to a script runner Web Item?, gramatically I understand what the code provided there will do, but agian the problem is I don't know how to apply it. Acutally I don't have a clear picture of how things cooperate with each other here. Lik I said, I'm new to javascript and html, so the single way I know for now to combine javacript with html is to put the javascript code into the html code wrapped by a pair of tags, but here the html code itself is just a fragment of a groovy script, besides there is something called AJS which indicates maybe some JIRA configuration also needs to be involved, it's just getting too complicated for me and there seems to be nothing helpful online for a beginner like me.
Could anyone give some clear clues for that? Thanks very much.
I think you're really close, actually. It's easy to get lost in the documentation forest.
Basically, you just need some way to send the contents of your dialog box's form to the second REST endpoint, right?
It seems to me that one way you could do that would be to put the submit buttons inside the form and just point the form's action attribute to your REST endpoint. You can get the base URL of JIRA like this:
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.component.ComponentAccessor
def baseUrl = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL)
Then reference it in your form like this (note how I put the submit button inside the form):
<section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true"> <header class="aui-dialog2-header"> <h2 class="aui-dialog2-header-main">Create IMS Checkpoint</h2> <a class="aui-dialog2-header-close"> <span class="aui-icon aui-icon-small aui-iconfont-close-dialog">Close</span> </a> </header> <div class="aui-dialog2-content"> <div id="container" style="width:px"> <form id="my-custom-sr-dialog-form" class="aui" action="${baseUrl/rest/scriptrunner/latest/custom/yourSecondEndpoint}"> <div id="projects" style="height:220px;width:280px;float:left;"> <p>Please select the project:</p> <p> <input class="checkbox" type="checkbox" name="project" value="projectA">MB_213_16_PSCM_ECU</input> <br> <input class="checkbox" type="checkbox" name="project" value="projectB">MB_213_16_PSCM_CCC</input> <br> <input class="checkbox" type="checkbox" name="project" value="projectC">MB_223_19_PSCM_ECU</input> <br> <input class="checkbox" type="checkbox" name="project" value="projectD">MB_223_16_PSCM_CCC</input> <br> </p> </div> <div id="description" style="height:220px;width:280px;float:left;"> <p>Please enter the description information:</p> <p>Info1: <input id="input1" class="text" type="text" name="descriptionInfo1"/><br> Info2: <input id="input2" class="text" type="text" name="descriptionInfo2"/><br></p> </div> <button id="submit-button" class="aui-button aui-button-primary">Confirm</button> </form> </div> </div> <footer class="aui-dialog2-footer"> <div class="aui-dialog2-footer-actions"> <button id="dialog-close-button" class="aui-button aui-button-link">Close</button> </div> <div class="aui-dialog2-footer-hint">Some hint here if you like</div> </footer> </section>
That will cause the form's data to get posted to your REST endpoint, though notably, it will also navigate your users to a different page (whatever is returned by your REST endpoint). Maybe that's what you want, but you probably want something a little more AJAXy. In that case, don't move your button around, but add some JavaScript like that below as a custom web resource:
(function ($) { $(function () { AJS.dialog2.on("show", function (e) { var targetId = e.target.id; if (targetId === "sr-dialog") { var someDialog = AJS.dialog2(e.target); $(e.target).find("#submit-button").click(function (button) { $.ajax({ type: "POST", url: AJS.contextPath() + "/rest/scriptrunner/latest/custom/yourSecondEndpoint", data: AJS.$(window.opener.document).find("#my-custom-sr-dialog-form").serialize(), beforeSend: function (request) { request.setRequestHeader("X-Atlassian-token", "no-check"); } }).done(function(response) { //do whatever needs done in the UI here }); }); } } ); }); })(AJS.$);
If you need some help figuring out how the $.ajax function works, consult the relevant jQuery docs.
Hi Jonny,
thanks very much! Actually before you answered I figured out a way by myself which is not to a add a submit button inside the form but add a normal button outside the form and add some javascripts to send a POST when the button is clicked (because I do not want the page to be redirected, instead I only need some information sent), so far it works well, but I guess there's something not so good with this solution as you emphasized "don't move your button around", right? So what's the difference between these two solutions?
Best regards
Zhixun
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Your solution sounds fine, and is totally legitimate. I just meant if you moved the button my code would break, but clearly you're comfortable working around that. :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here a tutorial of this same example: https://mraddon.blog/2020/09/21/example-of-dialogs-with-jira-and-scriptrunner/
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey, @Raul Pelaez _TecnoFor - Marketplace Partner_
I want to build dialog like yours but when I paste the code it looks like
Can you help understanding what I did wrong?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I have this log in my rest endpoint
The following log information was produced by this execution. Use statements like:log.info("...") to record logging information.
2021-01-27 09:06:05,900 ERROR [common.UserCustomScriptEndpoint]: *************************************************************************************
2021-01-27 09:06:05,900 ERROR [common.UserCustomScriptEndpoint]: Script endpoint failed on method: GET showDialog
java.lang.NullPointerException: Cannot invoke method replaceAll() on null object
at java_lang_String$replaceAll$4.call(Unknown Source)
at Script278.trimIssueKey(Script278.groovy:34)
at Script278$trimIssueKey.callStatic(Unknown Source)
at Script278$trimIssueKey.callStatic(Unknown Source)
at Script278$_run_closure1.doCall(Script278.groovy:100)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy:221)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:345)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:343)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.doEndpoint(UserCustomScriptEndpoint.groovy:215)
at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.getUserEndpoint(UserCustomScriptEndpoint.groovy:108)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello, the code must be inserted as custom REST Endpoint using the standard process of Scriptrunner. After this you need to create the action (button) inside the ticket (this is a Web Fragment) The Web Fragment will run the query to the REST custom endpoint and will show the Dialog.
First start with a simple example like this:
https://mraddon.blog/2017/03/29/jira-scriptrunner-rest-endpoint-web-fragment-example/
Regards!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Raul Pelaez _TecnoFor - Marketplace Partner_ Now I dont have Java error but I have a problem that the dialog opens over a full screen and looks styleless.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@ZhixunDeng, can you please post the code of your first nad second rest point for our better understanding. thanks in advance
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm sorry, but I posted this question about two years ago when I was doing those stuff for my internship, and I have already forgotten all of it for too long... I guess the question can just be ignored now.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.