swisnl / jQuery-contextMenu

jQuery contextMenu plugin & polyfill
https://swisnl.github.io/jQuery-contextMenu/
MIT License
2.25k stars 744 forks source link

Cannot read property 'disabled' of undefined #724

Open YonSunZhen opened 4 years ago

YonSunZhen commented 4 years ago

when i use Submenus and custom icons,it always occur the mistake

private hotbox(nodeId?) {
    $.contextMenu({
      selector: 'g[id^="minder_node"]',
      // hideOnSecondTrigger: true,
      autoHide: true,
      build: ($trigger, e) => {
        if (!this.power) {
          return false;
        }
        const nodeCategory = this.selectData.category;
        return {
          items: this.buildItems(nodeCategory)
        };
      }
    });
  }

private buildItems(category: ETechCategory) {
    let items;
    const removeItem = {
      name: 'Delete',
      icon: (opt, $itemElement, itemKey, item) => {
        $itemElement.html('<span class="mdi mdi-delete icon"></span> <span class="word">Delete Domain</span>');
        return 'context-menu-icon-del';
      },
      callback: (itemKey, opt, rootMenu, originalEvent) => {
        const no = this.selectNo;
        this.removeNode(no);
      }
    };
    const sep = '---------';
    if (category === ETechCategory.FIELD || category === ETechCategory.GROUP) {
      items = {
        addGroup: {
          name: 'Add Group',
          icon: (opt, $itemElement, itemKey, item) => {
            $itemElement.html('<span class="mdi mdi-plus-circle icon"></span> <span class="word">Add Group</span>');
            return 'context-menu-icon-add1';
          },
          callback: (itemKey, opt, rootMenu, originalEvent) => {
            this.onAddNode(ENodeType.GROUP);
          }
        },
        sep1: sep,
        addPoint: {
          name: 'Add Technical',
          icon: (opt, $itemElement, itemKey, item) => {
            $itemElement.html('<span class="mdi mdi-plus-circle icon"></span> <span class="word">Add Technical</span>');
            return 'context-menu-icon-add2';
          },
          callback: (itemKey, opt, rootMenu, originalEvent) => {
            this.onAddNode(ENodeType.POINT);
          }
        },
        sep2: sep,
        remove: removeItem
      };
    }
    if (category === ETechCategory.POINT) {
      const data = this.selectData;
      const frontSpaces = '\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0';
      const behindSpaces = '\u00A0\u00A0\u00A0\u00A0';
      let generalSelected = frontSpaces;
      let gMSelected = frontSpaces;
      let keySelected = frontSpaces;
      let coreSelected = frontSpaces;
      switch (data.tech_type) {
        case this.TECH_TYPE.GENERAL.value:
          generalSelected = '√' + behindSpaces;
          break;
        case this.TECH_TYPE.UNIVERSAL.value:
          gMSelected = '√' + behindSpaces;
          break;
        case this.TECH_TYPE.KEY.value:
          keySelected = '√' + behindSpaces;
          break;
        case this.TECH_TYPE.CORE.value:
          coreSelected = '√' + behindSpaces;
          break;
      }
      let notPlanningSelected = frontSpaces;
      let underDevelopmentSelected = frontSpaces;
      let purchasedSelected = frontSpaces;
      switch (data.tech_status) {
        case this.TECH_STATUS.UNPLANNED.value:
          notPlanningSelected = '√' + behindSpaces;
          break;
        case this.TECH_STATUS.BEING_DEVELOPED.value:
          underDevelopmentSelected = '√' + behindSpaces;
          break;
        case this.TECH_STATUS.PURCHASED.value:
          purchasedSelected = '√' + behindSpaces;
          break;
      }
      let inlandSelected = frontSpaces;
      let industrySelected = frontSpaces;
      let internationalSelected = frontSpaces;
      switch (data.industry_status) {
        case this.TECH_SITUATION.DOMESTIC_ADVANCED.value:
          inlandSelected = '√' + behindSpaces;
          break;
        case this.TECH_SITUATION.INDUSTRY_ADVANCED.value:
          industrySelected = '√' + behindSpaces;
          break;
        case this.TECH_SITUATION.INTERNATIONAL_ADVANCED.value:
          internationalSelected = '√' + behindSpaces;
          break;
      }
      const updateData: INodeData = {};
      items = {
        setTechType: {
          name: 'Technical Type',
          // icon: 'fa-dot-circle-o',
          icon: (opt, $itemElement, itemKey, item) => {
            $itemElement.html('<span class="mdi mdi-plus-circle"></span>');
            return 'context-menu-icon-add11';
          },
          callback: async (itemKey, opt, rootMenu, originalEvent) => {

          },
          items: {
            general: {
              name: generalSelected + this.TECH_TYPE.GENERAL.key,
              callback: (itemKey, opt, rootMenu, originalEvent) => {
                updateData.tech_type = this.TECH_TYPE.GENERAL.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            gm: {
              name: gMSelected + this.TECH_TYPE.UNIVERSAL.key,
              callback: () => {
                updateData.tech_type = this.TECH_TYPE.UNIVERSAL.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            key: {
              name: keySelected + this.TECH_TYPE.KEY.key,
              callback: () => {
                updateData.tech_type = this.TECH_TYPE.KEY.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            core: {
              name: coreSelected + this.TECH_TYPE.CORE.key,
              callback: () => {
                updateData.tech_type = this.TECH_TYPE.CORE.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            }
          }
        },
        sep1: sep,
        techStatus: {
          name: 'Technical Status',
          icon: (opt, $itemElement, itemKey, item) => {
            $itemElement.html('<span class="mdi mdi-plus-circle"></span>');
            return 'context-menu-icon-add22';
          },
          // icon: 'fa-dot-circle-o',
          callback: async (itemKey, opt, rootMenu, originalEvent) => {

          },
          items: {
            notPlanning: {
              name: notPlanningSelected + this.TECH_STATUS.UNPLANNED.key,
              callback: (itemKey, opt, rootMenu, originalEvent) => {
                updateData.tech_status = this.TECH_STATUS.UNPLANNED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            underDevelopment: {
              name: underDevelopmentSelected + this.TECH_STATUS.BEING_DEVELOPED.key,
              callback: () => {
                updateData.tech_status = this.TECH_STATUS.BEING_DEVELOPED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            purchased: {
              name: purchasedSelected + this.TECH_STATUS.PURCHASED.key,
              callback: () => {
                updateData.tech_status = this.TECH_STATUS.PURCHASED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            }
          }
        },
        sep2: sep,
        industryStatus: {
          name: 'Technical Situation',
          icon: (opt, $itemElement, itemKey, item) => {
            $itemElement.html('<span class="mdi mdi-plus-circle"></span>');
            return 'context-menu-icon-add33';
          },
          // icon: 'fa-dot-circle-o',
          callback: async (itemKey, opt, rootMenu, originalEvent) => {

          },
          items: {
            inland: {
              name: inlandSelected + this.TECH_SITUATION.DOMESTIC_ADVANCED.key,
              callback: (itemKey, opt, rootMenu, originalEvent) => {
                updateData.industry_status = this.TECH_SITUATION.DOMESTIC_ADVANCED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            industry: {
              name: industrySelected + this.TECH_SITUATION.INDUSTRY_ADVANCED.key,
              callback: () => {
                updateData.industry_status = this.TECH_SITUATION.INDUSTRY_ADVANCED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            },
            international: {
              name: internationalSelected + this.TECH_SITUATION.INTERNATIONAL_ADVANCED.key,
              callback: () => {
                updateData.industry_status = this.TECH_SITUATION.INTERNATIONAL_ADVANCED.value;
                this.updateNode(updateData, EUpdateType.SIMPLE);
              }
            }
          }
        },
        sep3: sep,
        remove: removeItem
      };
    }
    return items;
  }