Excel Javascript Add-in: how to open ExecuteFunction in the taskpane rather than new iframe?
Asked Answered
K

1

7

I'm trying to use the Excel Javascript API to create an addin that:

  • Adds multiple buttons on the Home tab.
  • Each of the buttons opens the taskpane to a different screen.
  • Each of these taskpanes runs in the same runtime (e.g. I can share data between them with just setting data in window.data = "data").

As far as I understand, it is not possible to do this with multiple ShowTaskpane actions on the buttons, as this does not appear work with the shared runtime.

The approach I'm taking currently is:

  1. Set my function file as
<FunctionFile resid="Taskpane.Url"/>

(where <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>)

  1. Define the following actions:
<Control xsi:type="Button" id="FirstButton">
    ...
    <Action xsi:type="ExecuteFunction">
        <FunctionName>first</FunctionName>
    </Action>
</Control>
<Control xsi:type="Button" id="SecondButton">
    ...
    <Action xsi:type="ExecuteFunction">
        <FunctionName>second</FunctionName>
    </Action>
</Control>
  1. Define first and second as a functions in the global scope (and defined in the taskpane.html file). Each of these functions a) sets some state inside the Taskpane app (to get it to show something different, depending on the function call), then calls Office.addin.showAsTaskpane(). The code looks generally like:

the code for the first function called from the button

However, this does not work as expected. Namely, it opens the taskpane in a separate iframe to the side of the taskpane. It looks like this:

share function opens in a new iframe

When I add a Office.addin.showAsTaskpane() call to the share function, it looks like this:

showAsTaskpane just causes the taskpane to open as well as the new iframe

How can I use the Execute functions actions but do so within the taskpane? I want one shared runtime, and I want all of it to open and be within the taskpane itself. The documentation makes it seem like AppDomains can make this happen, but I'm not sure what I'm doing wrong.

Thanks for any information -- I really appreciate it!

Klepht answered 12/6, 2020 at 18:59 Comment(1)
Why aren't you using localStorage or cookies? In other words, do you have to keep those changes in the memory, or is it OK to save them to localStorage for this purpose? You could still remove them from LS on unloaded eventSelfsuggestion
S
1

The key problem here I think is you want to change some state in your taskpane based on the function executions. That's actually easy and you don't need the shared runtime for that.

In your taskpane, at the initialization part, you have to register the event listener for storage.

window.addEventListener('storage', () => {
  console.log('your local storage has changed');
});

In your functions, you could utilize the local storage, writing values in there which in your taskpane you'll have access to when the event is raised.

// example globally exposed function to be called using ExecuteFunction
function first(event) {
   localStorage.setItem('routePath', 'firstRoute');
   event.completed();
}

then in your taskpane-app you could have

window.addEventListener('storage', () => {
  const askedPath = localStorage.getItem('routePath');
  if (askedPath !== existingPath) {
    reRouteApp(localStorage.getItem('routePath')
  }
});

Depending on your framework of choice, you may want to watch out for how you register this event listener. To provide an example, if you're using react and hash-router, you could have your re-route method like so:

const reRouteApp = (route) => {
  window.location.hash = route;
}

while making sure you register the listener event on onComponentMount of the app.js or with useEffect to ensure you don't end up with multiple listeners.

Selfsuggestion answered 26/6, 2020 at 12:32 Comment(4)
@Mavi.....For me also same scenario that when using shared runtime, initially i was able to open taskpane by one of custom command but the same could not be refreshed once it is opened for the post actions....if i removed shared runtime then taskpane getting reloaded...... Since i required shared runtime for enable/disable ribbon commands i need help to implement with single taskpane as suggested to refreshing taskpane.Stonedead
Happy to help out but I'm not sure if I understand the problem entirely, can you explain it again? It would help if you can explain the scenario rather than the solution you want to arrive; ex: rather than saying I want to use shared runtime to do this, explain it like "I want my user to click on this, do some stuff, I'll check for xyz and want to avoid abc while doing that". I'm not sure what you mean by post-actions..Selfsuggestion
@Mavi..Thank you for the response......And here is scenario....in our application we have Login and logout with some other ribbon commands... If user clicked Login command (ShowTaskPane) then post successful authentications logout and other commands are enabled successfully..Stonedead
continuing from last comment... On next step if user tried to click logout command (ShowTaskPane) then nothing happens on same taskpane which it seems the taskpane not getting reloaded in shared runtime...Hence if possible can you please share the manifest configuration with shared runtime with single taskpane call from multiple ribbon command events....so that it can be easily achieved enable/disable of custom ribbon commands also.... Let me please know if anything required....Stonedead

© 2022 - 2024 — McMap. All rights reserved.