0

我正在使用 Google Apps 脚本为 Google 电子表格制作一些自定义 UI。

我正在尝试制作一个抽象的“向导”UI,它有一个任意的面板数组,然后在底部有一个“后退”和“下一步”按钮,根据你所在的“页面”来改变面板的可见性。

我需要某种机制,这样当你从向导的一个页面移动到下一个页面时,我可以在当前“页面”上调用一个函数来说“我现在要离开你了,请保存你的状态”,并且类似于下一个“页面”说“设置好自己,你即将变得可见”(类似于 onShow()、onHide())。

但是,我正在努力从后退和下一个按钮的事件处理程序中找出如何做到这一点。据我所知,访问 UI 元素或将字符串(通过“隐藏”的 ui 元素)传递给事件处理程序非常容易。

这是我目前拥有的相关代码:

/*
*********************************************************************
*/
function createWizard(pages) {
  app = UiApp.getActiveApplication();

  var currIdx = app.createHidden("currentPanelIndex", 0).setId("CurrentPanelIndex");
  var minIdx = app.createHidden("minPanelIndex", 0);
  var maxIdx = app.createHidden("maxPanelIndex", pages.length);
  app.add(currIdx);
  app.add(minIdx);
  app.add(maxIdx);

  var buttPanel = app.createHorizontalPanel();
  var backButton = app.createButton("Back"); 
  var nextButton = app.createButton("Next"); 
  buttPanel.add(backButton).add(nextButton);

  var mainPanel = app.createVerticalPanel();

  for (var i = 0; i < pages.length; i++) {
    pages[i].setId("Panel"+i).setVisible(false);
    mainPanel.add(pages[i]);
  }

  mainPanel.add(buttPanel);
  mainPanel.setCellVerticalAlignment(buttPanel, UiApp.VerticalAlignment.BOTTOM);
  mainPanel.setCellHorizontalAlignment(buttPanel, UiApp.HorizontalAlignment.RIGHT);

  app.add(mainPanel);

  // create handler to respond to events
  var clickHandler = app.createServerClickHandler("doBack")
    .addCallbackElement(currIdx)
    .addCallbackElement(minIdx)
    .addCallbackElement(maxIdx);
  backButton.addClickHandler(clickHandler);  
  var clickHandler = app.createServerClickHandler("doNext")
    .addCallbackElement(currIdx)
    .addCallbackElement(minIdx)
    .addCallbackElement(maxIdx);
  nextButton.addClickHandler(clickHandler);

  updateVisibility(currIdx, minIdx, maxIdx)
}

/*
*********************************************************************
*/
function doBack(eventInfo) {
  app = UiApp.getActiveApplication();

  var parameter = eventInfo.parameter;
  var currentPanel = Math.round(Number(parameter.currentPanelIndex));
  var minPanel = Math.round(Number(parameter.minPanelIndex));
  var maxPanel = Math.round(Number(parameter.maxPanelIndex));

  if (currentPanel > minPanel) {
    currentPanel--;
    // Store the new value
    app.getElementById("CurrentPanelIndex").setValue(String(currentPanel));

    updateVisibility(currentPanel);
  }

  return app;
}

/*
*********************************************************************
*/
function doNext(eventInfo) {
  app = UiApp.getActiveApplication();

  var parameter = eventInfo.parameter;
  var currentPanel = parseInt(parameter.currentPanelIndex);
  var minPanel = Math.round(Number(parameter.minPanelIndex));
  var maxPanel = Math.round(Number(parameter.maxPanelIndex));
  Logger.log(currentPanel);

  if (currentPanel < maxPanel) {
    currentPanel++;
    // Store the new value
    app.getElementById("CurrentPanelIndex").setValue(String(currentPanel));

    updateVisibility(currentPanel, minPanel, maxPanel);
  }

  return app;
}

/*
*********************************************************************
*/
function updateVisibility(currentPanel, minPanel, maxPanel)
{
  for (var i = minPanel; i < maxPanel; i++) {
    if (i == currentPanel) {
      app.getElementById("Panel"+i).setVisible(true);
      // I want to do something like panel[i].onShow()
    }
    else {
      app.getElementById("Panel"+i).setVisible(false);
      // I want to do something like panel[i].onShow()
    }
  }  
}

请注意,我认为我不能将 UI 元素扩展为能够具有“onShow”或“onHide”回调。我也看不到如何将回调作为字符串传递!

如有必要,我可以发布更多代码,但如果我以错误的方式处理此问题,我很乐意从头开始,因此我当前的实现细节相对不重要。

免责声明,我非常擅长 C++、C#、Lua 等,但在 JavaScript 方面几乎是新手,所以我可能遗漏了一些非常明显的东西!

4

1 回答 1

0

我认为您的方法可能太复杂了...您在用户界面中创建的所有小部件都可以从一开始就在不同的面板中创建,然后您的处理程序函数只需要“播放”它们的可见性。从用户角度来看,用户界面完全不同,但您有一个包含所有小部件的独特回调元素。这是我很久以前建议的一个非常基本的小示例,它基于相同的原理模拟选项卡面板。

4 个面板位于一个垂直面板中,因此每个面板都位于完全相同的位置,给人一种内容在变化的错觉。

我没有时间建议完整的演示代码,但请告诉我这种方法是否适合您的需求。


根据您的评论进行编辑

由于您已经有处理程序来处理previous/next两个按钮,我要做的就是在每个“页面”上复制 2 个相同的按钮,它们都具有相同的 2 个处理程序但不同的 ID。这样布局将保持不变,但您可以知道哪个“页面”使用e.parameter[source]. 如果您知道该页面并且您的所有小部件都具有一致的索引,那么您可以采取的具体操作是没有限制的。例如,从第 3 页切换到第 4 页将被识别,因为处理函数的源将是button_next_3并且(总是例如)从该面板将数据写入 SS 上的工作表 3。

希望我足够清楚,我认为这样的概念没有任何限制。你 ?

于 2013-10-14T17:41:18.220 回答