Search code examples
javascripthtmlfullcalendarfullcalendar-4

Dynamic change text on customButtons


I want to have edit/read-only button for the calendar.

Everything works, but when I change view/day after click then default name of the button got added to the custom one, like this: "stopedit" instead of just "stop"

Any idea how to resolve it?

customButtons: {
  toggleEditButton: {
    text: "edit",
    click: function () {
      if (calendar.getOption("editable")) {
        calendar.setOption("editable", false);
        calendar.setOption("selectable", false);
        event.target.innerHTML = "edit";
      } else {
        calendar.setOption("editable", true);
        calendar.setOption("selectable", true);
        event.target.innerHTML = "stop";
      }
    }
  }
}

https://codepen.io/DimaKompot/pen/NWGJJxB?editors=0011


Solution

  • I never used Fullcalendar before, but it seems that when re-rendering, Fullcalendar sets the button text defined by text: "edit" (line 3) by appending the text in the DOM. As you already set content via innerHTML, you get editedit or stopedit in those cases.

    It's always dangerous to fiddle in the DOM of other components, as our own changes often collide with the rendering logic of the component, and it's hard to find official (or unofficial) and good-enough extension points. So it's best to play by the components rules, if possible.)

    As the customButtons API doesn't expose any rendering logic, changing the text option at runtime with setOption was the next-best idea.

    Some component libraries (e.g. DevExpress) offer a path-syntax like calendar.setOption('customButtons.toggleEditButton.text', 'stop'), but that didn't work.

    But fortunately, when replacing the whole customButtons option, Fullcalendar respects that change and re-renders the button:

    var customButtonsOption = calendar.getOption('customButtons');
    calendar.setOption("customButtons", {
        ...customButtonsOption,
        toggleEditButton: {
            ...customButtonsOption.toggleEditButton,
            text: 'edit'
        }
    });
    

    Full working example: https://codepen.io/sbusch/pen/abvxYXm?editors=0010

    Note: I use the Object spread operator ..., which may not be available depending on your build environment and targeted browsers. A (very verbose) workaround in that case is to use Object.assign.