How to actually use the Dialog2 along with a groovy script in Script Runner? Edited

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.

1 answer

1 accepted

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

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. :)

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Bridget Sauer
Published Thursday in Marketplace Apps

Calling all developers––You're invited to Atlas Camp 2018

 Atlas Camp   is our developer event which will take place in Barcelona, Spain  from the 6th -7th of   September . This is a great opportunity to meet other developers and get n...

77 views 0 5
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you