Yo! Create an add-in from your Script Lab code

Let’s say you created the trappings of an add-in with Script Lab and now you want to make it into a stand-alone add-in. You can export your code (just the manifest and html), copy and paste it into an existing project, or upload to GitHub to share it, but you cannot easily convert it into a fully functional Web Add-in project from Script Lab. I took the time to figure this out, so you do not have to. wlEmoticon-hotsmile.png These steps will show you how to export your solution from Script Lab, import into VSCode, apply a Yeoman Office template and then begin testing it in Office Online with, ah… minimal effort (more or less). wlEmoticon-confusedsmile.png

Here are the steps:

      1. First install Script Lab in Excel. You can follow my post for that here: Start Developing in OfficeJS Today with Script Lab
      2. Next, we will load one of the sample. On the Script Lab ribbon, click Code. yo-scriptlab1
      3. Click the Samples button and then select Basic API Call.
      4. Next, click the Share button ( yo-scriptlab2 )and click Export for publishing, this will download a ZIP file in an Internet Explorer download dialog. Click Openyo-scriptlab3
      5. If you get a warning open the file, click Allow: yo-scriptlab4
      6. Select these two files, right-click and then click Copy:
        • basic-api-call.html
        • basic-api-call-manifest.xml.
      7. Leave the ZIP folder and download window open for now.
      8. Next, create a folder on your computer, call it “sample-1” then Paste (press CTRL+V) the two files into the folder. You can now close the ZIP folder you copied from and the download window.
      9. Next, you will need to have VSCode installed and configured for Office development. You can following my post for that here: How to Configure VSCode for Office Development.
      10. Open VSCode and press [CTRL+`] to open the Integrated Terminal.
      11. Change to the “sample-1” folder you created above, using the command: cd c:\\sample-1
      12. Type the following command: yo office sample-1
      13. You will then select the option as detailed below: yo-scriptlab5
      14. Once completed, on the File menu, click Open Folder. Browse to the sample-1 folder and click Select location.
      15. Delete the following files and folder:
        • app.js
        • app.css
        • index.html
        • rousource.html
        • and the function-file folder
      16. If you want to use Chrome as your debug environment, I would suggest this step which you will click to open the bsconfig.json file and add the following line: “browser”:”chrome” like this:
      17. Click to open the basic-api-call.html file and remove the following Script Lab lines:
      18. Save, close, then rename the file to index.html.
      19. Click to open the basic-api-call-manifest.xml and then CTRL+click to open the sample-1–manifest.xml in a side by side window (on the right).
      20. Copy the following lines from the left pane and replace the same lines by pasting them in the right pane:
      21. Save and close all open files. You can now delete the basic-api-call-manifest.xml file.
      22. Your project is now ready. Press [CTRL+`] to open the Integrated Terminal and type: npm start. Make sure it launches on port 3000 or your add-in will not load: yo-scriptlab6
      23. Your browser will open, if you have a wanting page, click Advanced and then click Proceed to the website. You will not see your index.html.
      24. Open a new tab and browse to https://office365.com and then sign in with your credentials.
      25. From the Office menu, click Excel, then open a new blank workbook.
      26. On the Insert tab, click Office Add-ins.
      27. In the upper right of the dialog, click Upload my add-in. Click Browse and then select the file: c:\<path>\sample-1\sample-1-manifest.xml.
      28. Your adding will now be loaded. On the Home tab, you can click to open the taskpane, click the button and it should highlight the selected cell.

One major caveat is that this is not a preferred way to make a Web Project. This is bare bones and really just to get you going with minimal effort (if you can call ~30 steps minimal effort). The important thing to know is that all your code in going to be embedded in script tags inside the the HTML file and not in a separate JS file (as preferred – a.k.a. Separation of Concerns). So keep that in mind as you perform this work. If eventually your project turns into something much bigger, you will need to do some housekeeping.

So, ~30 steps… It would be nice if there were a way to do this more simply, but for now, this is the best way to do this. I have had a discussion with the product team in charge of Script Lab and they agree with such a feature, so I will update this post if it becomes available at some future point. wlEmoticon-hotsmile.png

How to Configure VSCode for Office Development

I thought I had written this some time ago, but I guess I did not. So here goes…

NOTE: First, I want to state that if you are creating applications for the full Office clients, it might be best to continue using Visual Studio 2017 as you are able to debug directly in these clients with much more ease than you can from VSCode.

Some might find it hard to believe, but I have been geeking out hard and using VSCode to develop OfficeJS (Office 365 Web Add-ins). I find it a very useful, light client, where I am able to focus on just the basics. When combined with tools like Node Package Manager (NPM), browser sync, Yoeman and Git, you have a surprisingly robust development environment what makes doing things delightfully easy. wlEmoticon-hotsmile.png But it was not always this way, I had a learning curve and it took me a while to get it all setup and running correctly. I am not saying it was hard, just… different. So I channeled my inner geek and much to his delight, it turned out for the better.

So as I stated the challenge was getting it all setup. This is going to be very different, especially if you are coming from the Visual Studio 2017 world (much more so, from the VBA world). So, here are the step by step instructions I use for getting my VSCode development environment all configured for Office Development:

  1. Download and install VSCode: https://code.visualstudio.com/ .
  2. Download and install Node to get Node Package Manager (NPM): https://nodejs.org/en/download/. On this page you will want to download the Windows/MSI/64-bit version.
  3. Download and install Git: https://git-scm.com/download. On this page you will want to make sure you select to install the latest which is from the link in the upper right of the page.
  4. Now we have the basic packages we need in order to begin development. What we need to do now is install the Yeoman generator. To do this:
    • Open VSCode
    • Press CTRL+`. This will open the console window. Alternatively you can go to the View menu and click Integrated Terminal
    • Switch to the Terminal in the Console and then type the following command: npm install global yo
  5. Now you are ready to start generating OfficeJS add-ins from VSCode, and these steps will walk you through the first one:
    • Type: yo office sample-1
    • Once you do this the scaffold generator will kick in and ask you a few questions. Answer them as I have, in bold, below:? Would you like to create a new subfolder for your project? No
      ? Which Office client application would you like to support? Excel
      ? Would you like to create a new add-in? Yes, I need to create a new web app and manifest file for my add-in.
      ? Would you like to use TypeScript? No
      ? Choose a framework: Jquery
      ? Would you like to open it now while we finish creating your project? Yes
    • Once complete you will not have a solution folder called sample1 under your user profile c:\users\<yourname>\sample-1, but the project will not be open in VSCode, yet…
    • To open your project on the File menu, click Open Folder and then browse to and open the sample1 folder, then press Select Folder. NOTE: If you are coming from Visual Studio where the tree of solution files appears on the right side of the screen, the “Explorer” in VSCode appears on the left and it is actually a listing of ALL files and ALL folders in the solution directory.
    • You will see the code files for your project on the left hand side in the Explorer. The key files of importance to you, getting started will be:
      • sample-1-manifest.xml – this is your manifest for publishing your add-in.
      • index.html – this is your primary page or “task pane” for your add-in.
    • In this example I will not have you edit any of the files, but the basics are completely provided to build a solution. At this point we will check this into Git. Press CTRL+SHIFT+G. This will open the Source Control repository page. Click the icon to the right of the words Source Control, to Initialize Repository. This will open the folder to your solution, simply click Initialize Repository. You can now work with Git to manage your project. I will not go into more detail, but if you are interested, please watch this video: https://git-scm.com/video/what-is-git
    • Finally, we are ready to debug. But first, if you are on Windows 10, and you use Edge or Internet Explorer as your default browser, I would strongly suggest using the Google Chrome browser because the debug tools are so much better. However, there is one change you need to make:
      • Open the bsconfig.json file in the Explorer
      • At the top of the configuration you need to place this line: “browser”: “chrome”, so that the file looks like this:
        {
            "browser": "chrome",
            "ui": {...
    • To debug, press CTRL+` to open or return to the Integrated Terminal. Type: npm start. This will open your project in Chrome. You might get a warning that the site is not trusted, click Advanced and select to trust anyway / continue.
    • Open another tab and browse to office365.com. Once there, log into your account. On the Office menu in the upper left, click Excel. On the Insert menu, click Office Add-ins. In the upper right of the dialog, click Upload my add-in. Click Browse and then select the file: c:\users\<yourname>\sample-1\sample-1-manifest.xml. Your add-in will now load on the Home tab, switch there, and press Show Taskpane.

This looks like a lot of work and I know for most of you that are like me, coming from a Visual Studio and/or VBA background, this is very alien. You might consider this a step backwards or it might seem like it is time to hang up the spurs. wlEmoticon-disappointedsmile.png But give it some time, especially if you are just getting into OfficeJS, it will grow on you. In the meantime, here are some of my other blog entries around this to help you:

Please let me know if you have questions or would like some help with any of this. What I hope to be able to do at some point is to add posts on:

  • Importing a Script Lab project into a Yo Office scaffold
  • A video on the steps outlined in this post. I have done videos for internal training at Microsoft before, but never on my own for my blog. So this will be new territory if I can get around to it.
  • Other samples posts to getting started with various projects.

If you have any ideas of what you would like to see, please let me know.

OfficeJS.dialogs version 1.0.8

I have recently updated the OfficeJS.dialogs to version 1.0.8. I have also updated the Node Package Manager version as well. You can get it by running the following command in the VSCode Terminal Window:

npm install officejs.dialogs

With this latest version comes a few bug fixes, some cleanup of the code, cleaner JSDoc documentation and a PrintPreview dialog. The PrintPreview started out as a proof of concept but it actually works for me – in the browser anyway. I am not sure how well it will work in any of the full clients as I have not tested it there yet. If anyone has a chance to test it, please let me know if you encounter any issues.

Here is a sample of the PrintPreview dialog:

print

Here is some code to implement it:

 

OfficeJS.dialogs Updated (v1.0.5)

I have been working hard on my OfficeJS.Dialogs library and just published version 1.0.5. You can get it from NPM and GitHub. See my previous post for more information on how to do this.

I have added a few new features:

  • A simple Alert.Show() method that displays a simple OK box. For those times you want to just simply pop up a quick notification to the user.
  • A Progress.Show() that displays a progress bar. This allows for you to show the progress bar and then issue Progress.Update() to move the progress bar along. When you are done you call Progress.Complete().
  • A Wait.Show() dialog that will show an indeterminate spinner. This form will remain up until you issue a Wait.CloseDialog().
  • New UpdateMessage() and Update() methods were added to the MessageBox. This was done to allow you to quickly ask a lot of questions of the user in one instance of the dialog, without giving the user back to the application for a second while the new dialog is rendered. UpdateMessage() will just update the message but keep all the buttons the same, but you will specify a new callback. Update() will allow you to fundamentally change all the settings the MessageBox (buttons, icon, caption, text and all), plus a new callback function.
  • Behind the scenes I made some improvements/bug fixes:
    • If you try to show two dialogs too quickly, nothing will happen. So I added a half-second delay between dialog displays to make sure you never get an overlap.
    • You will get an error message in your callback if more than one dialog is attempted to be opened at once.
    • “Window Messaging” has been setup with Progress and MessageBox to allow the parent and the dialog to pass messages back and forth. It involves using setTimeout().

For those interested in the last item, here is what that look like:

        /**
        * Handles messages coming from the parent
        */
        function startMessageHandler() {
            setTimeout(function() {
                var message = localStorage.getItem("dialogMessage");
                localStorage.setItem("dialogMessage", ""); // clear the message
                if(message !== undefined && message !== null && message != "")
                {
                    var msg = JSON.parse(message);
                    if(msg.message == "update") {
                        // update the form
                        updateForm(msg.settings);
                    } else if(msg.message == "close") {
                        // do nothing special here
                        return; // stops the message pump
                    } else if(msg.message == "progress") {
                        if(msg.settings.Number > 100) return;
                        $("#bar").prop("value",msg.settings.Number);
                    }
                }
                startMessageHandler(); // call again
            }, 0);
        }

Here is an example of how to use the Progress dialog. The method signature is like this:

Progress.Show( [message], [start], [max], [completeCallback], [cancelCallback] )

  • The message is the message the user see’s when the dialog is opened.
  • The start is the number you want the progress bar to start at. Usually this should just be zero (0).
  • The max is the number you want the Progress bar to end at. Usually this should be 100. But it can be any number you want. If you have 5 steps to perform in the background while this dialog is up, you can set this to 5.
  • The completeCallback is your callback function to be called when your code calls the Progress.Compelte().
  • The cancelCallback is what gets called when the user presses the Cancel button on the form.

By itself, this will do nothing. You will have to call the Progress.Update() command in order to move the progress bar, or update the message to the user. Here is the method signature for the Update method:

Progress.Update( [amount], [message] )

  • The amount is how much you want the progress bar to move. If you do not specify an amount, an amount of 1 is assumed.
  • The message is a new message to provide the progress bar. If you want to update the message and do not want to increment the progress bar, specify an amount of zero (0).

Once you are all done with the Progress dialog, you issue a Progress.Complete() call. There are no parameters to it. Once called, your completeCallback in the Progress.Show() call will then be executed.

Here is an example:

// reset first to make sure we get a fresh object
Progress.Reset();
// display a progress bar form and set it from 0 to 100
Progress.Show("Please wait while this happens...", 0, 100, function() {
    // once we are done - when your code
    // calls Progress.Complete()
    Alert.Show("All done folks!");
  }, function() {
    // this is only going to be called if the user cancels
    Alert.Show("The user cancelled");
});
doProgress();

function doProgress() {
  // increment by one, the result that comes back is
  // two pieces of information: Cancelled and Value
  var result = Progress.Update(1);
  // if we are not cancelled and the value is not 100%
  // we will keep going, but in your code you will
  // likely just be incrementing and making sure
  // at each stage that the user has not cancelled
  if(!result.Cancelled && result.Value <= 100) {     setTimeout(function() {       // this is only for our example to       // cause the progress bar to move       doProgress();     },100);   } else if(result.Value >= 100) {
    Progress.Compelte(); // done
  }
};

That example also uses the new Alert dialog. This one is very simple:

Alert.Show ( [message] )

This next example uses the new Wait dialog, which is much simpler to implement. Here is the method signature:

Wait.Show( [message], [showCancel], [cancelCallback] )

  • The message is the message you want to show the user. If you specify null, it will appear as simply “Please wait…”
  • The showCancel flag if set will allow the user to see a Cancel button.
  • The cancelCallback function is only valid if the showCancel option is true. When the user presses cancel, this function gets called.

When you are ready to close the Wait dialog, you issues a Wait.CloseDialog(). Here is an example:

  Wait.Show(null, true, function() {
    Alert.Show("The user cancelled.");
  });
  setTimeout(function(){
    Wait.CloseDialog();
    Alert.Show("Done!");
  }, 15000);

If you have some suggestions for some things you would like to see added to this library, please add a comment below or reach out to me on LinkedIn or Twitter. Some ideas I will be working on:

  • Allow you to call another dialog type without having the close the dialog.
  • A selection dialog, where you have a dropdown list of a listbox where you wan select (or multi-select) items.
  • An option to resize forms.
  • An option to use the message handler in your own custom form – minimal code

Dialogs in OfficeJS

I have been working on a number of projects for my customers and recently, dialogs have taken front and center stage. The Office.context.ui Dialogs are powerful, albeit a tad confusing and the documentation suffers from a few easily missed points.  Here is the documentation:

But in this post, I hope to explain everything I have learned. To start off with here is the code to issue the dialog:

  Office.context.ui.displayDialogAsync('https://localhost:3000/function-file/dialog.html',
      { height: 20, width: 30, displayInIframe: true },
      function (asyncResult) {
          dialog = asyncResult.value;
          // callbacks from the parent
          dialog.addEventHandler(Office.EventType.DialogEventReceived, processMessage);
          dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
      });

What this dialog does is opens as a modal form in a frame over the application (in Office Web Apps). It looks like this:

screen.PNG

As you can see the dialog is modal. But what is really important are the two event handlers you need to register to be able to get back to your code:

          dialog.addEventHandler(Office.EventType.DialogEventReceived, processMessage);
          dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
The first one is an event receiver and really this is the event handler for errors, such as being unable to open the dialog or, most importantly, the user closed the dialog by clicking the (X) in the upper right of the dialog. There are a series errors you can catch, but specifically, the dialog cancel is this:
12006 The dialog box was closed, usually because the user chooses the X button.
The second one is a handler for messages coming from the dialog. These messages can be anything, but is usually a string or a JSON string. You can send a message from the dialog like this:
Office.context.ui.messageParent('{message}');
When the dialog issues a message using the code above, the function defined in the event handler is called. For example, if the user clicks an OK button or Submit button, you can pass the stringified values from the form back to the callback function. From there the dialog actually remains open until the caller issues a close, like this:
    // close the dialog
    dialog.close();
In the example above where I make the displayDialogAsync call, you will see I defined the SAME callback function for both dialog events. I did this because the results can be parsed by the same function. Here is what my function look like:
function processMessage(arg) {
    // close the dialog
    dialog.close();
    // procress the result
    if(arg.error == 12006) {
      // user clicked the (X) on the dialog
      sendEvent.completed({ allowEvent: false });
    } else {
      if(arg.message=="Yes") {
        // user clicked yes
        sendEvent.completed({ allowEvent: true });
      } else {
        // user clicked no
        sendEvent.completed({ allowEvent: false });
      }
    }
}
My previous blog post references all the code for the dialog:

Yo Office

Ok, odd title, I know. For some developers “in the know,” they will understand what I am eluding to. So what does it mean? It is short for Yeoman. In their own words, here is what it does:

Yeoman helps you to kickstart new projects, prescribing best practices and tools to help you stay productive. To do so, we provide a generator ecosystem. A generator is basically a plugin that can be run with the `yo` command to scaffold complete projects or useful parts.

So, by “yo office”, I am telling you that Office Web Add-in templates can be delivered through this cross-platform command line tool. This means you do NOT need Visual Studio (or even Windows) to create a new Office Web Add-in project package. More importantly, these packages are setup through NodeJs Package Manager and are configured to use Node.js web server (which comes on MANY different platforms).

Now, if you are like me (a 20+ year VS Office Developer veteran), when I first heard this, it all sounds just like this:

Γράφω στα ελληνικά και αν καταλαβαίνετε αυτό, καλό για σας
FYI: That is Greek. wlEmoticon-hotsmile.png
So, I have a choice here and that is to make this a long blog post, or a short blog post and I dislike making long posts as much as you do reading them, so… In this case, here is the executive summary: The Microsoft Office Developer team is trying to make Office an accessible development platform no matter where you come from (experience wise) or what platform you use.
Now, for “super hip” developers living on the cusp of command-line based free developer tooling, put this in your MacBook:
yo office
For the rest of you…
To get this to work, you need to install Node JS from here. And next you need to install the prerequisites as per these steps. Once installed, you will open the Node JS command prompt (in Windows, from the Start menu, type NodeJS and it should appear as a choice) and perform these steps:
  1. Change directory (using cd) to the folder where you want the project to live.
  2. Type “yo office” and then answer the questions.
  3. In my case, I developed an Outlook add-in, with a manifest, using JavaScript, called “Outlook-Sample-1” and I chose JQuery as the framework. Here is the output:

yo.PNG

When it is done, it will create a folder called Outlook-Sample-1 and place a set of files in it that you can edit and the NodeJS configuration to run it from a standalone web server locally. I used Visual Studio Code (or VS Code, as it is known, which is a new multi-platform code editor from Microsoft that runs on Mac, Windows, and Linux), to edit the add-in.
NOTE: If you have configured everything in Visual Studio Code correctly, you can not only get NodeJS to interact from the “Terminal Window” you can also hook to GitHub to push/pull your projects. It is a whole other topic for a whole other blog post, but VS Code is a bare essentials utilitarian cross-platform code editing development tool.
Now, which files you need to edit and such are beyond the scope here, but if you have done some development in this area before, you can probably quickly figure it out. I might post more on this in the future. Stay tuned!

Ok, ok… I know, I know… I need to stop here and address the big huge hulking elephant in the room. YES, these are command line tools. Yes, DOS is still dead. No, it is. Really. Repeat after me, DOS “IS” DEAD. Now, just accept that this is the way it is, because this is the way it is. I know, it seems so… 1994… Neo called from the Matrix to assure you it is, indeed, 2017. wlEmoticon-surprisedsmile.png For my fellow Visual Studio, 20+ year developer gurus: “deep breaths.” Now, back to our regularly scheduled broadcast..


Here is a view of my project from VS Code, with the Terminal Window open…
vscode.PNG
Once I was done, I opened a NodeJS command prompt in the Terminal window and launched my project using the following command:
npm  start
Once you run this command, you will effectively start NodeJS web server at http://localhost:3000 which will be hosting your WebAdd-in. But you still need to side load your manifest. To do this, you will need to follow these steps (for Windows), here for Mac, here for Outlook. This gets all kinds of technical and deep into other areas that are potentially future blog posts, but the point is that you can then debug your add-in locally no matter which platform you are on.
Ok, Ok… back to the elephant
So, is this BETTER than Visual Studio Enterprise and the JavaScript debugger there and code assistance I get?
Well, this is more nuanced… I lean towards “no” as most of this stuff is too lightweight, especially given my experience. Especially without the debugging. But, I do see some advantages (besides the command line tools) that have its advantages for use on Windows:
  • It is available across multiple platforms – including Windows. VS Code, Node JS, and “yo office” are everywhere, anywhere, over there, under that, etc.. wlEmoticon-disappointedsmile.png
  • Out-of-the-box support for TypeScript. Which I have not blogged on a lot, but Michael Zlatkovsky has covered well in his book. TypeScript makes JSDoc seem like child’s play.
  • Out-of-the-box support for the Node Package Manager ecosystem. This is a huge repository of reusable code.
  • VS Code is a light weight editor that hooks into NPM, Node and Git really well. And while it does not debug, recent builds of Office have added the ability to hook to a debugger right from your taskpane. Which is only good if you have a taskpane, but it is a start.
  • Node provides auto-refresh (browser-sync), auto-compilation, and other goodness.

Again, this might look like a lot of Greek, but if you find your shop turning Greek, you can at least know some starter phrases to begin acquiring the knowledge you need to speak it.

 

So, why is any of this important to me? Especially if you are telling me:
“I use Visual Studio Enterprise (or Pro) and I am happy with it, why would you introduce me to this Greek language lesson.”
The answer comes in three points you can take away:
  • Office development is really multi-platform capable now. This correlates to the fact the Office Applications are also multi-platform. Write your add-in once, and it will run (or the future plan is, it will run) on every platform you can think of: Windows, Mac, iOS, Android, Linux (or essentially an browser or any platform with a browser that has HTML5 support).
  • You know more about the vision, commitments and goals of the core Microsoft Office teams. If you get nothing out of this other than Microsoft is committed to true multi-platform capabilities with Office Web Add-ins, you have come away with a major point. But there is also the knowledge on how Office development can be done no matter the developer background. And hey. You 20+ year VS Office Developer veterans: take this to heart and read into it, because these are the tea leaves; then look over to your mentee that is likely your kids age and <sigh>.
  • You can move to another platform and still take what you know with you. This means that “cool” MacBook you bought several years back and gave to your kiddo when they went off to college can actually do something more than read email and browse web pages. wlEmoticon-hotsmile.png Uh, I still strongly suggest you stick to Web Add-in development on Windows and Visual Studio Enterprise if you are already there… just saying…
So, with this, I hope I have sufficiently given you a vision of things to come, and maybe even given a few of you some new things to research and delve into. If you want more, the entire how-to with Yeoman, including a cool video, is on the following page:

OfficeJS: Create a (VERY) Basic Add-in for Excel

Recently, I was asked what is needed in order to create the most basic add-in you can. The least amount of files, work and effort. Technically, you only need two files:

  1. An HTML file with all your JavaScript inline and all the Office and JQuery libraries being pulled from a CDN.
  2. An XML Manifest file that defines the add-in.

You publish the HTML file to a web server, get the address to where it is published, update the manifest with that information and then install the XML file as an add-in. The XML file will define the add-in name/description and points to the HTML file for the code. When you launch the add-in, the task pane will open and the HTML page will be loaded in it. From there your JavaScript will execute and your add-in will come alive. It is THAT easy. 2 files.

To demonstrate this, I created a simple Excel add-in. Here is the code for the bare minimum manifest XML:

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp
xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides"
xsi:type="TaskPaneApp">
<Id>5226365f-62d0-435f-a4af-cc6a7bd753b2</Id>
<Version>1.0.0.1</Version>
<ProviderName>TheOfficeContext.com</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<DisplayName DefaultValue="BasicAddin" />
<Description DefaultValue="This is a basic addin."/>
<IconUrl DefaultValue="" />
<Hosts>
<Host Name="Workbook" />
</Hosts>
<DefaultSettings>
<SourceLocation DefaultValue="https://basicaddin.azurewebsites.net/home.html" />
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
</OfficeApp>

Here is the HTML file that is quite basic, I am not even using the Microsoft Fabric for the controls. This is a simple HTML page, period:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title>Excel Basic Add-In</title>
<!--using JQuery CDN so we do not need to include-->
<script src="https://code.jquery.com/jquery-1.12.4.min.js" type="text/javascript"></script>
&nbsp;&nbsp;&nbsp; <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<script type="text/javascript">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "use strict";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The initialize function must be run each time a new page is loaded.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Office.initialize = function (reason) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(document).ready(function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add a click event handler for the button.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $('#simple-button').click(function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function (result) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (result.status === Office.AsyncResultStatus.Succeeded) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner-text").text('The selected text is: "' + result.value + '"');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner").show();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner-text").text('Error: ' + result.error.message);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner").show();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner-close").click(function () { $("#banner").hide(); });
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#banner").hide();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })();
&nbsp;&nbsp;&nbsp; </script>
</head>
<body>
<div id="content-main">
<div class="padding">
<h1>Basic Addin</h1>
<div>Select a cell with text and then...</div>
<button id="simple-button">Click Here!</button></div>
</div>
<div id="banner" style="position:absolute;bottom: 0;">
<div id="banner-text"></div>
<button id="banner-close"> <i>X</i> </button></div>
</body>
</html>

What this add-in does is very simple. It opens the task pane with a single button. Enter some text in a cell in Excel, select that cell, and then click the button. It gets the text and displays it in a popup at the bottom of the pane. I have published this add-in manifest here:

https://basicaddin.azurewebsites.net/basicaddin.xml

You can run it by using these steps:

  1. Open Excel Online. I first log into https://outlook.office365.com. Then I click on the menu button in the upper left and select Excel.
  2. I select to create a “New blank workbook.”
  3. On the Insert tab, I click Add-ins.
  4. In the upper right, I select “Upload My Add-in”
  5. I click Browse and in the Filename box, I put https://basicaddin.azurewebsites.net/basicaddin.xml and then click Open. This will download the add-in to the cache on your system and you will get a file name like “basicaddin[1].xml.”
  6. Click Upload.
  7. The add-in will load from my Azure site and you will see the button demonstrated above.

Now, to go ahead and answer a question I know are coming. How did I upload this Azure without Visual Studio publishing tools:

  1. I went to my Azure Protal (portal.azure.com).
  2. I clicked the +New button on the left side.
  3. I selected Web + Mobile, then Web App
  4. I filled in the required information: Name and resource group and clicked Create.
  5. After it was done, I followed these steps to get to the site via FTP: https://blogs.msdn.microsoft.com/kaushal/2014/08/01/microsoft-azure-web-site-connect-to-your-site-via-ftp-and-uploaddownload-files/
  6. I uploaded ONLY the HTML file.
  7. I  got the path to the location from the Azure portal:
    capture
  8. Next, I updated the XML manifest to point to https://basicaddin.azurewebsites.net/home.html
  9. Then I used the steps above to load it into Excel Online.

This is fairly simple from a web developer perspective. Now, if you are not a web developer (but a traditional Office developer), you are probably still on the fence on how/why you would want to go through all of this. Again, the primary thing I am demonstrating here is how you can build an add-in with as few files as possible. But, I want to reiterate how these new add-ins are truly cross-platform. Follow these steps on your iPad and you will know what I mean. It is incredible and this work really is not that difficult to perform. It might just be a tad time consuming in the beginning as you are getting used to the new interfaces.

If you have questions, please feel free to reach out to me.