I'm trying to use the Excel Javascript API to create an addin that:
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:
<FunctionFile resid="Taskpane.Url"/>
(where <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
)
<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>
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: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:
When I add a Office.addin.showAsTaskpane()
call to the share
function, it looks like this:
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With