Zack Barresse
Zack Barresse

Reputation: 249

Office Add-in buttons not calling functions

I've been working on this project, a simple Table of Contents add-in for Excel. I can't seem to get my buttons to fire. I'm able to debug and see my taskpane, but clicking my buttons do nothing.

There are 2 buttons: create and remove. My js file is here.

EDIT

Using ScriptLab, the below code is what I successfully tested. However, when I tried to port it back to VS the buttons do nothing when clicked.

$("#run").click(() => tryCatch(run));

async function run() {
  await Excel.run(async (context) => {

    var sheets = context.workbook.worksheets;
    sheets.load("items/name");
    var sheetName = 'Table of Contents';
    await context.sync();

    return context.sync()
      .then(function () {

        var toc = sheets.items.find(ws => ws.name == sheetName);
        if (!toc) {
          toc = sheets.add(sheetName);
          context.sync();
        } else {
          toc.getUsedRange().clear();
        }
        toc.load("name, position");
        context.sync();

        var values = [];
        var count = 0;
        sheets.items.forEach((ws) => {
          if (ws.name !== sheetName) {
            values.push([(count + 1), "=HYPERLINK(\"#\"&\"'\" & \"" + ws.name + "\" & \"'!A1\",\"" + ws.name + "\")"]);
            count++;
          }
        })

        toc.position = 0;
        toc.activate();
        toc.getRange("A:A").format.columnWidth = 2;
        toc.getRange("B:B").format.columnWidth = 20;
        toc.getRange("C:C").format.columnWidth = 200;
        toc.getRange("C:C").format.wrapText = true;
        toc.getRange("1:1").format.rowHeight = 5;
        toc.getRange("3:3").format.rowHeight = 5;
        toc.getRange("B2").values = [["Table of Contents"]];
        toc.getRange("B2").format.font.size = 18;
        toc.getRange("B2").format.font.bold = true;

        if (values.length === 0) {
          console.log('error 1');
          return context.sync();
        }

        var dataRangeAddress = `B4:C${3 + (count || 1)}`;
        var dataRange = toc.getRange(dataRangeAddress);
        context.sync();
        dataRange.values = values;
        toc.calculate(false);

        return context.sync();
      });

    await context.sync();
  });
};

/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
  try {
    await callback();
  } catch (error) {
    // Note: In a production add-in, you'd want to notify the user through your add-in's UI.
    console.error(error);
  }
};

Upvotes: 0

Views: 129

Answers (2)

Zack Barresse
Zack Barresse

Reputation: 249

Originally I was working from a template and adjusting it. This was created in an earlier version of VS (2015) before upgrading to 2019. As such, I found slight differences in naming conventions.

This particular issue was related to the Office.initialize function in the 'element' and 'messageBanner' variables. Adjusting this code let the buttons work a treat. I suspect if I had not created the original project in an earlier version, it probably would've worked just fine.

Original/offending code:

    var element = document.querySelector('.ms-MessageBanner');
    messageBanner = new fabric.MessageBanner(element);

Adjusted/working code:

    var element = document.querySelector('.MessageBanner');
    messageBanner = new components.MessageBanner(element);

Upvotes: 0

Rick Kirkham
Rick Kirkham

Reputation: 9684

One thing I notice is that you have a for ... in loop running over sheets.items:

for (i in sheets.items)

But WorksheetCollection.items is an array. It is considered a bad practice to use a for ... in loop over an array. (See for...in.) Aside from that, doing something non-standard like that makes it harder for others to reason about your code.

More importantly, you need to get more information about what is going wrong. Please download the ScriptLab tool. You can use it to test your methods and it has a nice console that will report errors to you.

UPDATE: I also see that your removeTableOfContents function tests the truth of !sheet, but no variable named sheet is declared in the file, so !sheet will always resolve as truthy.

Upvotes: 1

Related Questions