How to modify a macro parameter in Confluence Cloud?
Asked by Six:

My goal is to create a custom dynamic macro in Confluence, where the user can select two parameters during the "macro setup". There is two dropdown, where they can select the values. The first parameter depends from the user, and the second parameter depend from the first, so I need to change them in "runtime". How can I do this?

I have added my macro to the macros menu through atlassian-connect.json:

```
"dynamicContentMacros": [
  {
    "url": "/macro",
    "width": "200px",
    "height": "200px",
    "name": {
      "value": "0Server"
    },
    "key": "server-dynamic-macro",
    "cacheable": false,
    "icon": {
      "width": 80,
      "height": 80,
      "url": "/logo-large.png"
    },
    "parameters": [
      {
        "identifier": "server",
        "name": {
          "value": "Server"
        },
        "type": "enum",
        "required": true,
        "multiple": false,
        "defaultValue": "Please select a server",
        "values": [
          "Please select a server,",
          "Please select a server"
        ],
        "hidden": false
      },
      {
        "identifier": "drive",
        "name": {
          "value": "drive"
        },
        "type": "enum",
        "required": true,
        "multiple": false,
        "defaultValue": "Please select a drive",
        "values": [
          "Please select a drive",
          "Please select a drive"
        ],
        "hidden": false
      }
    ]
  }
]
```

And this part is working:  
![macro-ui.png](/t5/image/serverpage/image-id/114130i1F13F6587B39E0E4/image-dimensions/844x289?v=v2 "macro-ui.png")  

But now how can I change the dropdown options list? I found out, the best, if I do it with JavaScript callbacks, but I got "*Uncaught TypeError: Cannot read property 'appendChild' of null* ". I think it's because my code runs in a iframe, so not seeing the parent object. I think I couldn't call the document.parent, because that's already cross scripting.   
The Confluence JavaScript API documentation says:

"Atlassian Connect provides a JavaScript client library called all.js.  
<https://connect-cdn.atl-paas.net/all.js>  
This library establishes the cross-domain messaging bridge with its parent."  
...  
"You must add the all.js script to your pages in order to establish the cross-domain messaging bridge."

I have added the all.js to my macro HTML page, but I have no idea, how can I now change the element on the parent page?

This is, how my HTML page looks like now:

```
<!DOCTYPE html>
<html>
<head>
    <title>Sample cacheable macro</title>
    <meta charset="UTF-8"/>
    <script src="https://connect-cdn.atl-paas.net/all.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function () {
            // Request data from app API
            AP.context.getToken(function (token) {
                var addJwtHeader = function (request) {
                    request.setRequestHeader("Authorization", "JWT " + token);
                };
                var fillServers = function(server){
                    var select = document.getElementById("macro-param-server");
                    opt = document.createElement("option");
                    opt.value = server.toString();
                    opt.textContent = server.toString();
                    select.appendChild(opt);
                }
                $.ajax({
                    url: "data",
                    beforeSend: addJwtHeader
                }).done(function (data) {
                    $("#data").text("Host: " + JSON.stringify(data, null, '\t'));
                    data.forEach(fillServers);
                    AP.resize();
                });
            });
        });
    </script>
</head>
<body>
<div class="ac-content">
    <pre id="body"></pre>
    <pre id="data"></pre>
</div>
</body>
</html>
```

(The JavaScript part is working, I have tested it with a select on the same page.)

I'm using spring-boot and Maven.

Six


Answers:
author: Michael Yang - Shinetech Software
body: I also want to know if there is any way to access the dom elements of the parent page from the iframe of a macro.

comments: author: Six
body: Hi [@Michael Yang - Shinetech Software](/t5/user/viewprofilepage/user-id/3347045)

In my case the solution was that I have created my own page, with my own dropdowns and javascripts, and I show this custom page inside the macro.

By default you couldn't reach the parent page elements from the iframe with javascript. (There are some exceptions, but I think that's not what you need. You can read about them here: <https://stackoverflow.com/questions/5604839/accessing-an-element-outside-of-iframe>)

Atlassian gives you some extra functionality, though JavaScript API, what can be useful for some functions: <https://developer.atlassian.com/cloud/confluence/about-the-javascript-api/>

Six


author: Michael Yang - Shinetech Software
body: Thank you [@Six](/t5/user/viewprofilepage/user-id/1284084) for providing these information! Yes, the javascript can be run from within the iframe, but so far as I know there is no way to run the my own javascript on the parent(top) page. The javascript API is interface designed on specified functions on purpose.


Tags: app

cloud

confluence-app

confluence-cloud

confluence-development

development