Premium support for our pure JavaScript UI components


Post by marasoft@netrom.ro »

Hello,

I need to display the cellMenuFeature items when I'm clicking on a button from the resource row instead of right clicking on a resource.
This code is currently displaying my custom item when I'm right clicking a resource:

  cellMenuFeature={{
                    items: {
                      removeRow: false,
                      cut: false,
                      copy: false,
                      extraItem: {
                        text: getTranslationByKey(translationGroup, 'lblSafeManning',
                          'Safe manning'),
                        icon: 'fas fa-user-tie',
                        weight: 200,
                        menu: this.state.safeMannings,
                      },
                    },
                  }}

Now what I want to do is to display my custom extra item when I'm clicking a button on a resource, for that I've added the button to the resource and then I'm listening to the cellClick action like that:

 cellClick({ record, event }) {
                      // Add a new client when clicking plus icon
                      if (event.target.closest('.fa-user-tie')) {
                        // how to display the cellMenu items from here??
                      }
                    },

How can I do that?

Best regards,


Post by Maxim Gorkovsky »

Hello.
You can try this https://lh/bryntum-suite-release/grid/docs/#Grid/feature/CellMenu#function-showContextMenu:

cellClick(event) {
  grid.features.cellMenu.showContextMenu(event);
}

Post by marasoft@netrom.ro »

Hello,

Hello,

Thanks for your quick response however this is not working, bellow is the code:

cellClick(event) {
                      if (event.event.target.closest('.fa-user-tie')) {                   this.scheduler.current.schedulerInstance.columns.grid.features.cellMenu.showContextMenu(event);
                      }
                    },

I receive the following error:

Screenshot_924.png
Screenshot_924.png (93.33 KiB) Viewed 1053 times
Attachments
Screenshot_925.png
Screenshot_925.png (88.42 KiB) Viewed 1052 times

Post by Maxim Gorkovsky »

Just to clarify, in your case you should call context menu like this:

cellClick(event) {
    if (event.event.target.closest('.fa-user-tie')) {
        this.scheduler.current.schedulerInstance.features.cellMenu.showContextMenu(event);
    }
},

How do you add the icon to the cell? Are you using tree? Please post your scheduler config which is related showing icons there.


Post by marasoft@netrom.ro »

See bellow the column configuration:

const locationRankConfig = {
  children: true,
  treeFeature: true,
  columns: [
    { type: 'tree',
      field: 'name',
      text: 'Name',
      width: 280,
      align: 'left',
      editor: false,
      htmlEncode: false,
      renderer: ({ value, record }) => {
        const highlight = record.data.highlight;
        if (record.data.parentId === null) {
          return `<div>${value} <i class="fas fa-user-tie"
           style="margin-left: 12px; cursor: pointer;" /></div>`;
        }
        if (record.data.safeManning && !record.data.safeManningFilled && !record.data.inThePast) {
          return `<div><i class="fas fa-exclamation-triangle" 
          style="left: 12px; color: red; position: absolute"></i>
          <label class=${highlight ? 'highlight' : ''}>
          ${value}</label></div>`;
        }
        if (record.data.safeManningFilled && !record.data.inThePast) {
          return `<div><i class="fa fa-check" 
        style="left: 12px; color: green; position: absolute"></i>
        <label class=${highlight ? 'highlight' : ''}>
        ${value}</label></div>`;
        }
        return `<div><label class=${highlight ? 'highlight' : ''}>${value}</label></div>`;
      },
    },
  ],
};

Yes, I am using tree.

I've tried this as well, same internal error:

   this.scheduler.current.schedulerInstance.features.cellMenu.showContextMenu(event);

Also if it helpls this is the full configuration of the scheduler:

     <BryntumScheduler
                  {...baseConfig}
                  {...schedulerConfig}
                  ref={this.scheduler}
                  eventEditFeature={false}
                  createEventOnDblClick={false}
                  children={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
                  treeFeature={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
                  // Custom view preset with header configuration
                  viewPreset={{
                    base: 'dayAndWeek',
                  }}
                  onEventDblClick={this.enterEdit}
                  panFeature={{ pan: true }}
                  eventDragCreateFeature={false}
                  scheduleMenuFeature={false}
                  onScroll={this.onVerticalScroll}
                  onEventDragAbort={this.onEventDragAbort}
                  timeRangesFeature={{
                    showCurrentTimeLine: true,
                    showHeaderElements: false,
                  }}
                  listeners={{
                    cellClick(event) {
                      // Add a new client when clicking plus icon
                      if (event.event.target.closest('.fa-user-tie')) {
                         debugger;
                         currentContext.scheduler.current.schedulerInstance.features.cellMenu.showContextMenu(event);
                       //  currentContext.scheduler.current.schedulerInstance.columns.grid.features.cellMenu.showContextMenu(event);
                      }
                    },
                    cellMenuBeforeShow({ items, record }) {
                      debugger;
                      if (!record.data.isVessel) {
                        items.extraItem.hidden = true;
                      }
                      if (hasValue(currentContext.state.selectedSafeMannings) && currentContext.state.selectedSafeMannings.length > 0) {
                        const selectedSafeManning = currentContext.state.selectedSafeMannings.find(s => s.vesselId === record.data.vesselId);
                        // This should be removed when the default safe manning for a vessel will be saved
                        // into the database, in that case, selected safe manning id won't be null anymore
                        if (!hasValue(selectedSafeManning.safeManningId)) {
                          selectedSafeManning.safeManningId = items.extraItem.menu[0].id;
                        }
                        if (selectedSafeManning) {
                          items.extraItem.menu.forEach(item => {
                            if (item.id === selectedSafeManning.safeManningId) {
                              item.icon = 'fa fa-check';
                            } else {
                              item.icon = undefined;
                            }
                          });
                        } else {
                          items.extraItem.menu.forEach(item => {
                            item.icon = undefined;
                          });
                        }
                      }
                    },
                  }}
                  cellMenuFeature={{
                    items: {
                      removeRow: false,
                      cut: false,
                      copy: false,
                      extraItem: {
                        text: getTranslationByKey(translationGroup, 'lblSafeManning',
                          'Safe manning'),
                        icon: 'fas fa-user-tie',
                        weight: 200,
                        menu: this.state.safeMannings,
                      },
                    },
                  }}
                  eventMenuFeature={{
                    items: {
                      editEvent: false,
                      deleteEvent: false,
                      addEvent: false,
                      cutEvent: false,
                      copyEvent: false,
                      // custom item with inline handler
                      delete: {
                        text: getTranslationByKey(translationGroup, 'btnDeleteAppointment',
                          'Delete appointment'),
                        icon: 'b-fa b-fa-user-times',
                        weight: 200,
                        onItem: ({ eventRecord, resourceRecord }) =>
                          currentContext.handleDeleteAppointment(eventRecord, resourceRecord),
                      },
                    },
                  }}
                  onEventDrag={this.onEventDrag}
                  onEventKeyDown={this.onEventKeyDown}
                  enableDeleteKey={false}
                  rowHeight={parseInt(this.state.rowHeight, 10)}
                  eventBodyTemplate={(data) => {
                    let color = data.data.eventColor;
                    if (color === '#0') {
                      color = WHITE_COLOR;
                    }
                    const updatedColor = hasValue(color) ? currentContext.pickTextColorBasedOnBgColorSimple(color, WHITE_COLOR, BLACK_COLOR) : WHITE_COLOR;
                    const isRecurrence = data.data.isRecurrence;
                    if (isRecurrence) {
                      return `<div class="b-sch-event-header">
                      <i class="far fa-sync-alt" style="padding-right: 10px; 
                       font-weight: 800;"></i><label style="color: ${updatedColor};">${data.data.name}<label></div>`;
                    }
                    //  if (data.data.startDate < Date.now() && data.data.endDate > Date.now()) {
                    //    const isCrewMemberBirthday = this.isCrewMemberBirthday(data.data);
                    //    if (isCrewMemberBirthday === true) {
                    // eslint-disable-next-line max-len
                    //      return `<div class="b-sch-event-header"><i class="fas fa-birthday-cake" style="padding-right: 10px; font-weight: 800;"></i>${data.data.name}</div>`;
                    //    }
                    //  }
                    return `<div class="b-sch-event-header"><label style="color: ${updatedColor};">${data.data.name}<label></div>`;
                  }}
                  timeRanges={this.state.timeRanges}
                  tbar={[
                    {
                      type: 'button',
                      ref: 'zoomInButton',
                      icon: 'b-icon-search-plus',
                      text: 'Zoom in',
                      onClick() {
                        currentContext.scheduler.current.schedulerInstance.zoomIn();
                      },
                    },
                    {
                      type: 'button',
                      ref: 'zoomOutButton',
                      icon: 'b-icon-search-minus',
                      text: 'Zoom out',
                      onClick() {
                        currentContext.scheduler.current.schedulerInstance.zoomOut();
                      },
                    },
                    {
                      type: 'button',
                      ref: 'scrollToTime',
                      text: getTranslationByKey(translationGroup, 'btnCurrentTime',
                        'Current time'),
                      onClick() {
                        currentContext.scheduler.current.schedulerInstance.scrollToDate(
                          today,
                          {
                            highlight,
                            animate: {
                              easing: 'easeFromTo',
                              duration: animate,
                            },
                            block: center ? 'center' : 'nearest',
                          });
                      },
                    },
                    {
                      type: 'slider',
                      ref: 'rowHeight',
                      text: getTranslationByKey(translationGroup, 'lblRowHeight',
                        'Row height'),
                      value: Cookies.get('rowHeight') ? Cookies.get('rowHeight') : 36,
                      showValue: true,
                      min: 25,
                      onInput({ value }) {
                        Cookies.set('rowHeight', value);
                        currentContext.scheduler.current.schedulerInstance.rowHeight = value;
                      },
                    },
                  ]}
                  project={{
                    stm: {
                      autoRecord: true,
                      disabled: false,
                    },
                  }}
                  startDate={new Date(2018, 11, 1, 18)}
                  endDate={new Date(2022, 11, 1, 18)}
                  resources={this.state.resources}
                  events={this.state.events}
                  allowOverlap={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
                  onBeforeEventDropFinalize={({ context }) => {
                    switch (this.state.selectedViewType.id) {
                      case PERSONAL_PLANNING_VIEW:
                        return this.validateDrop(context.draggedRecords[0].data,
                          context.newResource, context.startDate, context.endDate);
                      case LOCATION_RANK_VIEW:
                        break;
                      case RANK_LOCATION_VIEW:
                        break;
                      default:
                        break;
                    }
                  }}
                  onEventResizeEnd={this.onAppointmentResized}
                  onTimeAxisChange={this.onTimeAxisChange}
                  onEventDrop={this.onEventDrop}
                  eventDragFeature={{
                    showToolTip: true,
                    validatorFn: ({ draggedRecords, newResource, startDate, endDate }) =>
                      currentContext.validateDragEvent(draggedRecords[0].data,
                        newResource.data, startDate, endDate, false),
                  }}
                  eventResizeFeature={{
                    showToolTip: true,
                    validatorFn: ({ eventRecord, startDate, endDate }) =>
                      currentContext.validateResizeEvent(eventRecord.data,
                        startDate, endDate),
                  }}
                />

Post by Maxim Gorkovsky »

Record id is missing from the param, works if you just add one like this:

listeners : {
    cellClick(event) {
        event.id = event.record.id;
        grid.features.cellMenu.showContextMenu(event);
    }
}

Post by marasoft@netrom.ro »

Thanks, it is working now!


Post Reply