2
votes

Can't find the solution to this anywhere and I really hope it's possible.

I'm writing a Jira gadget and I have a configuration screen with 2 fields. One is the quickfind project picker; you type and it finds projects and you click the one you want.

The second field is Component. You can select the component of the project that you wish to filter by. However the components are different for each project so the Component field is populated with a AJAX call specified in the gadget in the "args" section of the "config" part.

Only problem is that this AJAX only gets called when the gadget is first loaded; i.e.: before a project is selected so the result is always "Select A Project".

I need a way to rerun this AJAX call on the event of the selected project being changed.

Is this possible? Or is there an alternative solution? I've tried timers to check for changes but there were a few problems there also; mainly that I couldn't access/alter the Component drop-box field. The gadget would just refuse to load.

Update: Below is the Javascript for the gadget. As you can see I added a refreshComponents() Javascript method which can retrieve the Components given a project ID however I have no way to attach this to the appropriate event. Also I can't seem to directly alter any components on the the page with the likes of jQuery or ordinary JS

<div id="chart_div" style="overflow: auto;"></div>

        <script type="text/javascript">

                var gadget = this;
                google.load('visualization', '1.0', {'packages':['corechart']});

                var oldProject = "initiated";
                var globalGadget;
                function timedComponentUpdate()
                {
                    //alert(globalGadget.getPref("projectId"));
                    //setTimeout("timedComponentUpdate()",3000);
                }

                function refreshComponents(idString)
                {
                    //refetch components
                    var url = "__ATLASSIAN_BASE_URL__/rest/severity-gadget/1.0/severity-issues/getComponents.json";
                    url += "?projectId=" + idString; 
                    alert(url);

                    var xmlhttp;
                    if (window.XMLHttpRequest)
                        xmlhttp=new XMLHttpRequest();
                    else
                    {
                        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    xmlhttp.onreadystatechange=function()
                        {
                            if (xmlhttp.readyState==4)
                            {
                                //document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
                                alert(xmlhttp.responseText);
                            }
                        }

                    xmlhttp.open("GET",url,true);
                    xmlhttp.send();
                }

                function drawChart(args, bugtype, comp) {
                    //setup for whether were getting opened or closed
                    var axisTitle;
                    var compTitle;
                    var chart;

                    if(bugtype == "Bug")
                        axisTitle = "Bug";
                    else
                        axisTitle = "Issue";

                    if(comp == "All")
                        compTitle = "";
                    else
                        compTitle = " - Component: " + comp;

                    var wVar = gadgets.window.getViewportDimensions().width-20;
                    var hVar = wVar/3;
                    var hVar = hVar*2;

                    // Create the data table.
                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'Issues');
                    data.addColumn('number', 'Trivial');
                    data.addColumn('number', 'Minor');
                    data.addColumn('number', 'Major');
                    data.addColumn('number', 'Critical');
                    data.addColumn('number', 'Blocker');

                    AJS.$(args.weeks).each(function() {
                        data.addRow(["Week "+this.number,
                            parseInt(this.issues[0]),
                            parseInt(this.issues[1]),
                            parseInt(this.issues[2]),
                            parseInt(this.issues[3]),
                            parseInt(this.issues[4])
                        ]);
                    });

                    var options = {'title':'Weekly '+axisTitle+' Backlog' + compTitle,
                          'width':wVar,
                          'height':hVar,
                           axisFontSize:4,
                           isStacked:true,
                           fontName: '"Arial"'
                    };

                    chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
                    chart.draw(data, options);
                }

                var gadget = AJS.Gadget(
                    {
                        baseUrl: "__ATLASSIAN_BASE_URL__",
                        useOauth: "/rest/gadget/1.0/currentUser",
                        config: {
                            descriptor: function(args)
                            {
                                document.getElementById("chart_div").innerHTML = "";

                                var gadget = this;
                                var projectPicker = AJS.gadget.fields.projectOrFilterPicker(gadget, "projectId", args.projectOptions);

                                //bh
                                oldProject = this.getPref("projectId");
                                //refreshComponents(this.getPref("projectId"));

                                return {
                                    theme : function()
                                    {
                                        if (gadgets.window.getViewportDimensions().width < 450)
                                        {
                                            return "gdt top-label";
                                        }
                                        else
                                        {
                                            return "gdt";
                                        }
                                    }(),
                                    fields: [
                                        AJS.gadget.fields.nowConfigured(),
                                        projectPicker,
                                        AJS.gadget.fields.days(gadget, "weeksPrevious"),
                                        {
                                            userpref: "issueType",
                                            label: "Issue Type:",
                                            description:"Choose which issue type you would like",
                                            type: "select",
                                            selected: this.getPref("issueType"),
                                            options:[
                                                {
                                                    label:"Any",
                                                    value:"Any"
                                                },
                                                {
                                                    label:"Bug",
                                                    value:"Bug"
                                                }
                                            ]
                                        },
                                        {
                                            userpref: "component",
                                            label: "Component:",
                                            description:"Choose which issue type you would like",
                                            type: "select",
                                            selected: this.getPref("component"),
                                            options:args.components
                                        }
                                    ]
                                };
                            },
                            args: function()
                            {
                                return [
                                {
                                    key: "components",
                                    ajaxOptions: function() {
                                        var ajaxProject = this.getPref("projectId");
                                        if(ajaxProject == "")
                                            ajaxProject = "null";

                                        return {
                                            url: "/rest/severity-gadget/1.0/severity-issues/getComponents.json",
                                            data:
                                            {
                                                projectId : ajaxProject
                                            }
                                        }
                                    }

                                }

                                ];
                            }()
                        },
                        view: {
                            onResizeReload: true,
                            onResizeAdjustHeight: true,
                            template: function(args) {
                                var gadget = this;

                                gadget.getView().empty();

                                drawChart(args.issueData, this.getPref("issueType"), this.getPref("component"));

                                gadget.resize();
                            },
                            args: [{
                                key: "issueData",
                                ajaxOptions: function() {
                                    return {
                                         url: "/rest/severity-gadget/1.0/severity-issues.json",
                                         data:  {
                                            projectId : gadgets.util.unescapeString(this.getPref("projectId")),
                                            weeksPrevious: this.getPref("weeksPrevious"),
                                            issueType: this.getPref("issueType"),
                                            component: this.getPref("component"),
                                            backlog: true
                                        }
                                    };
                                }
                            }]
                        }
                    }
                );
        </script>
1
Show us the JavaScript code you have done so far. - Anders
Added the JS part. theres more to it - if you want to see just let me know. Thanks. - carlmango11

1 Answers

0
votes

I think you'll need to turn your component field into a Callback Builder.

Inside the callback function you'll need to do a few things:

  1. retrieve the options via an AJAX request
  2. render the dropdown
  3. attach an event handler to refresh the list when a particular event occurs

Your new component field might look something like this... I've assumed you've got jQuery available for brevity.

{
    userpref: "component",
    label: "Component",
    id: "component_field_id"
    description: "Choose which issue type you would like",
    type: "callbackBuilder",
    callback: function(parentDiv){

        function renderOptions(options){
            // Remove elements from the parentDiv and replace them
            // with new elements based on the options param
            // You can use gadget.getPref('component') to ensure you
            // mark the right option as selected
        }

        function getOptions(){
            $.ajax({
                 url: "__ATLASSIAN_BASE_URL__/rest/severity-gadget/1.0/severity-issues/getComponents.json",
                 data: {
                     // You might be able to get hold of the selected value
                     // from the gadget object instead of like this
                     projectId: $("#filter_projectOrFilterId_id").val() 
                 }
            }).done(renderOptions);
        }

        // Retrieve and render options on gadget load
        getOptions();

        // Retrieve and render options on an event
        $(parentDiv).on("update-options", getOptions);
    }
}

Additionally, you'll need to trigger an event when the project select field value changes. Somewhere else in your JS code (not inside the gadget definition) you'll need to put code like this, but you'll need to confirm the CSS selector for the project/filter selector:

$(document).on("change", "#filter_projectOrFilterId_id", function(){
    $("#component_field_id").trigger("update-options");
});

I've not tested this but that's how I'd attempt to achieve what you're asking for.