{"id":18389569,"url":"https://github.com/anseki/jquery-contextmenu-common","last_synced_at":"2025-04-07T02:34:30.596Z","repository":{"id":57282074,"uuid":"53491619","full_name":"anseki/jquery-contextmenu-common","owner":"anseki","description":"jQuery plugin to add common checkable menu items `checkbox` and `radio` and more features to jQuery.contextMenu.","archived":false,"fork":false,"pushed_at":"2022-08-19T03:17:18.000Z","size":174,"stargazers_count":9,"open_issues_count":0,"forks_count":4,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-26T17:48:49.721Z","etag":null,"topics":["checkbox","context-menu","contextmenu","jquery","jquery-plugin","radio"],"latest_commit_sha":null,"homepage":"http://anseki.github.io/jquery-contextmenu-common/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anseki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-09T11:12:45.000Z","updated_at":"2024-10-23T12:32:22.000Z","dependencies_parsed_at":"2022-08-31T04:21:52.195Z","dependency_job_id":null,"html_url":"https://github.com/anseki/jquery-contextmenu-common","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Fjquery-contextmenu-common","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Fjquery-contextmenu-common/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Fjquery-contextmenu-common/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anseki%2Fjquery-contextmenu-common/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anseki","download_url":"https://codeload.github.com/anseki/jquery-contextmenu-common/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247477377,"owners_count":20945226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["checkbox","context-menu","contextmenu","jquery","jquery-plugin","radio"],"created_at":"2024-11-06T01:43:45.254Z","updated_at":"2025-04-07T02:34:25.586Z","avatar_url":"https://github.com/anseki.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jQuery.contextMenuCommon\n\n[![npm](https://img.shields.io/npm/v/jquery-contextmenu-common.svg)](https://www.npmjs.com/package/jquery-contextmenu-common) [![GitHub issues](https://img.shields.io/github/issues/anseki/jquery-contextmenu-common.svg)](https://github.com/anseki/jquery-contextmenu-common/issues) [![David](https://img.shields.io/david/anseki/jquery-contextmenu-common.svg)](package.json) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\njQuery plugin to add common checkable menu items `checkbox` and `radio` and more features to jQuery.contextMenu.\n\n[![s01](s01.png)](https://anseki.github.io/jquery-contextmenu-common/)\n\n**See \u003ca href=\"https://anseki.github.io/jquery-contextmenu-common/\"\u003eDEMO\u003c/a\u003e**\n\nA very useful jQuery plugin [jQuery.contextMenu](https://swisnl.github.io/jQuery-contextMenu/) supports `text`, `textarea`, `checkbox`, `radio`, etc., as `item.type`. Those allow you to embed form elements in the menu.  \nThose may be useful in special cases, aside from whether users welcome a form that appears via right-click or not.  \nBut two types `checkbox` and `radio` are very popular UI many apps need, and behavior of those differs from that of common menu UI many apps have because those are embedded form elements. For example, those get a focus and tab-stop, a user can't make the focus move through to other menu items by pressing arrow keys. And also, those don't keep own state by itself, the states are cleared when the menu is reopened.\n\nThis jQuery.contextMenuCommon plugin wraps jQuery.contextMenu, and adds `checkbox` and `radio` menu types that work like common menu UI users usually use. Also, it supports sub-labels such as shortcut-keys, dynamic changing, and so on.\n\n- `checkbox` and `radio` menu types like common menu UI are supported.\n- [Font Awesome](https://fortawesome.github.io/Font-Awesome/) icons are supported.\n- Disabled menu items are grayed-out like common menu UI. Included icons and mouse cursor are also controlled.\n- Sub-label like displaying shortcut-keys by common menu UI is supported.\n\n## Usage\n\nLoad jQuery.contextMenuCommon (2 files `css` and `js`) after jQuery.contextMenu.\n\n```html\n\u003clink href=\"dist/fixed/jquery.contextMenu.min.css\" rel=\"stylesheet\"\u003e\n\u003clink href=\"dist/jquery.contextMenuCommon.min.css\" rel=\"stylesheet\"\u003e\n\n\u003cscript src=\"dist/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"dist/jquery-ui-position.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"dist/fixed/jquery.contextMenu.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"dist/jquery.contextMenuCommon.min.js\"\u003e\u003c/script\u003e\n```\n\nSince jQuery.contextMenuCommon wraps jQuery.contextMenu, it works as jQuery.contextMenu completely, except additional features. See [jQuery.contextMenu Documentation](https://swisnl.github.io/jQuery-contextMenu/docs.html) for basic usage.\n\nEach item object that is included in `items` in constructor options accepts [`'checkbox'`](#checkbox-type) and [`'radio'`](#radio-type) as value of `type` property.  \nFor example:\n\n```js\n$.contextMenuCommon({\n  selector: '#trigger',\n  items: {\n\n    fontBold: {\n      label: 'Bold Font',\n      type: 'checkbox'\n    },\n\n    fontSize: {\n      label: 'Font Size',\n      items: {\n        size1: {\n          label: 'Small',\n          type: 'radio'\n        },\n        size2: {\n          label: 'Medium',\n          type: 'radio'\n        },\n        size3: {\n          label: 'Large',\n          type: 'radio'\n        }\n      }\n    }\n\n  }\n});\n```\n\nYou can specify a `value` property of each menu item, that value is got when the menu item is in the specified state.  \nThere are two way to get a current value (or state).\n\n- A value of `checked` property of each menu item is updated synchronously with the state that is changed by user or your app.\n- [`value`](#methods_value) method returns a current value.\n\nFor example:\n\n```js\nvar items = {\n\n  fontWeight: {\n    label: 'Bold Font',\n    type: 'checkbox',\n    value: ['normal', 'bold']\n    // For user: \"Do you want Bold Font?\" -\u003e \"Yes\" or \"No\"\n    // For your app: Current value of `fontWeight` -\u003e 'bold' or 'normal'\n  },\n\n  fontSize: {\n    label: 'Font Size',\n    items: {\n      size1: {\n        label: 'Small',\n        type: 'radio',\n        radiogroup: 'fontSize',\n        value: '8pt'\n      },\n      size2: {\n        label: 'Medium',\n        type: 'radio',\n        radiogroup: 'fontSize',\n        value: '12pt',\n        checked: true\n      },\n      size3: {\n        label: 'Large',\n        type: 'radio',\n        radiogroup: 'fontSize',\n        value: '16pt'\n      }\n    }\n    // For user: \"Please choose Font Size\" -\u003e \"Small\", \"Medium\" or \"Large\"\n    // For your app: Current value of `fontSize` -\u003e '8pt', '12pt' or '16pt'\n  }\n\n};\n\n$.contextMenuCommon({selector: '#trigger', items: items});\n\n$('#button').click(function() {\n  console.log('================ Get `checked`');\n  console.log('fontWeight: ' + items.fontWeight.checked);\n  console.log('fontSize size1: ' + items.fontSize.items.size1.checked);\n  console.log('fontSize size2: ' + items.fontSize.items.size2.checked);\n  console.log('fontSize size3: ' + items.fontSize.items.size3.checked);\n  console.log('================ Get value');\n  var $trigger = $('#trigger');\n  console.log('fontWeight: ' + $trigger.contextMenuCommon('value', 'fontWeight'));\n  console.log('fontSize: ' + $trigger.contextMenuCommon('value', 'fontSize'));\n});\n```\n\n## `checkbox` type\n\nA menu item that `'checkbox'` is specified to `type` property works as `checkbox` menu item.  \nFor example:\n\n```js\n// In constructor options\nitems: {\n\n  fontBold: {\n    label: 'Bold Font',\n    type: 'checkbox'\n  }\n\n}\n```\n\nThe `checkbox` menu item accepts following properties:  \n(All properties are optional)\n\n### `checked`\n\n*Alias:* `selected`  \n*Type:* boolean  \n*Default:* `false`\n\nAn initial or current state to indicate whether the checkbox of this menu item is checked or not.  \nThis is updated synchronously with the state that is changed by user or your app.\n\nFor example:\n\n```js\n// In constructor options\nitems: {\n  item: {\n    label: 'Item',\n    type: 'checkbox',\n    checked: true // This checkbox is checked when constructed\n  }\n}\n```\n\n### `value`\n\n*Type:* Array or any  \n*Default:* `[false, true]`\n\nIf something other than an array is specified, it is considered as `[false, \u003csomething\u003e]`.  \nWhen the checkbox of this menu item is checked, [`value`](#methods_value) method returns `value[1]` as a current value, otherwise `value[0]`.\n\nFor example:\n\n```js\n// In constructor options\nitems: {\n  appendTo: {\n    label: 'Add to document',\n    type: 'checkbox',\n    value: [$header, document]\n  }\n}\n// When user checked 'Add to Document', `appendTo` value is `document`.\n// When user did not check it, `appendTo` value is `$header`.\n```\n\nFor example, set reversed booleans, that is, get `true` when the checkbox is not checked, and get `false` when it is checked:\n\n```js\n// In constructor options\nitems: {\n  overwrite: { // This `overwrite` is meaningful name.\n    label: 'Confirm existing file',\n    type: 'checkbox',\n    value: [true, false] // reversed\n  }\n}\n```\n\n## `radio` type\n\nA menu item that `'radio'` is specified to `type` property works as `radio` menu item.  \nFor example:\n\n```js\n// In constructor options\nitems: {\n\n  small: {\n    label: 'Small',\n    type: 'radio'\n  },\n\n  large: {\n    label: 'Large',\n    type: 'radio'\n  }\n\n}\n```\n\nThe `radio` menu item accepts following properties:  \n(All properties are optional)\n\n### `radiogroup`\n\n*Alias:* `radio`  \n*Type:* string  \n*Default:* `undefined`\n\nA string to group the menu items and identify the group.  \nIn one list (i.e. one `items` object's children), items that `radiogroup` is not specified are grouped into one group.  \nFor example, there are five groups:\n\n```js\n// In constructor options\nitems: {\n  a1: {\n    label: 'Group A (1)',\n    type: 'radio'\n  },\n  a2: {\n    label: 'Group A (2)',\n    type: 'radio'\n  },\n  a3: {\n    label: 'Group A (3)',\n    type: 'radio'\n  },\n\n  sep1: { type: 'cm_seperator' },\n\n  b1: {\n    label: 'Group B (1)',\n    type: 'radio',\n    radiogroup: 'groupB'\n  },\n  b2: {\n    label: 'Group B (2)',\n    type: 'radio',\n    radiogroup: 'groupB'\n  },\n  b3: {\n    label: 'Group B (3)',\n    type: 'radio',\n    radiogroup: 'groupB'\n  },\n\n  sep2: { type: 'cm_seperator' },\n\n  c: {\n    label: 'Group C',\n    items: {\n      c1: {\n        label: '(1)',\n        type: 'radio'\n      },\n      c2: {\n        label: '(2)',\n        type: 'radio'\n      },\n      c3: {\n        label: '(3)',\n        type: 'radio'\n      }\n    }\n  },\n\n  sep3: { type: 'cm_seperator' },\n\n  de: {\n    label: 'Group D and E',\n    items: {\n      d1: {\n        label: 'Group D (1)',\n        type: 'radio'\n      },\n      d2: {\n        label: 'Group D (2)',\n        type: 'radio'\n      },\n      d3: {\n        label: 'Group D (3)',\n        type: 'radio'\n      },\n\n      sep4: { type: 'cm_seperator' },\n\n      e1: {\n        label: 'Group E (1)',\n        type: 'radio',\n        radiogroup: 'groupE'\n      },\n      e2: {\n        label: 'Group E (2)',\n        type: 'radio',\n        radiogroup: 'groupE'\n      },\n      e3: {\n        label: 'Group E (3)',\n        type: 'radio',\n        radiogroup: 'groupE'\n      }\n    }\n  }\n}\n```\n\n### `checked`\n\n*Alias:* `selected`  \n*Type:* boolean  \n*Default:* first item in a group is `true`, others are `false`\n\nAn initial or current state to indicate whether the radio of this menu item is checked or not.  \nThis is updated synchronously with the state that is changed by user or your app.  \nOnly a last menu item `true` is specified in a group is checked. By default, a first menu item in a group is checked.\n\nFor example:\n\n```js\n// In constructor options\nitems: {\n  item1: {\n    label: 'Item 1',\n    type: 'radio'\n  },\n  item2: {\n    label: 'Item 2',\n    type: 'radio',\n    checked: true // This radio is checked when constructed\n  },\n  item3: {\n    label: 'Item 3',\n    type: 'radio'\n  }\n}\n```\n\n### `value`\n\n*Type:* any  \n*Default:* zero-based index number in a group\n\nWhen the radio of this menu item is checked, [`value`](#methods_value) method returns `value` as a current value of a group that includes this menu item.  \nIn other words, a current value of a group is a `value` of checked menu item in the group.\n\nFor example:\n\n```js\n// In constructor options\nitems: {\n  a: {\n    label: 'Item A',\n    type: 'radio',\n    value: 'A' // 'A' is returned when this item is checked.\n  },\n  b: {\n    label: 'Item B',\n    type: 'radio' // `1` (index) is returned when this item is checked.\n  },\n  c: {\n    label: 'Item C',\n    type: 'radio',\n    value: 'C' // 'C' is returned when this item is checked.\n  }\n}\n```\n\n## Methods\n\n### \u003ca name=\"methods_value\"\u003e\u003c/a\u003e`value`\n\n```js\ncurrentOrNewValue = $trigger.contextMenuCommon('value', itemKeyOrRadioGroup[, newValue])\n```\n\nReturn a current value of the target. If `newValue` is passed, update a value of the target before return.  \nThe target is a menu item or a group of `radio` menu items `itemKeyOrRadioGroup` indicates. `itemKeyOrRadioGroup` is a key of an `items` object, or a string as [`radiogroup`](#radiogroup). It is discriminated automatically.  \nA returned value differs depending on `checked` state of the target menu item or menu items in the target group.  \nIf `itemKeyOrRadioGroup` indicates a `radio` menu item, a current value of a group that includes that menu item is returned (i.e. it is considered as that `itemKeyOrRadioGroup` indicates the group). Therefore, note that a returned value might be not `value` of the target menu item. (Because a value of a group is a `value` of checked menu item in the group. And another item in that group might be checked.)  \nAlso, `newValue` is a value in `value` array of the target `checkbox` menu item or `value` of any of `radio` menu items in the target group.\n\nFor example:\n\n```js\n$.contextMenuCommon({\n  selector: '#trigger',\n  items: {\n\n    fontWeight: {\n      label: 'Bold Font',\n      type: 'checkbox',\n      value: ['normal', 'bold']\n    },\n\n    fontSize: {\n      label: 'Font Size',\n      items: {\n        size1: {\n          label: 'Small',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '8pt'\n        },\n        size2: {\n          label: 'Medium',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '12pt'\n        },\n        size3: {\n          label: 'Large',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '16pt'\n        }\n      }\n    }\n\n  }\n});\n\nvar $trigger = $('#trigger');\n\n$('#button-get-values').click(function() {\n  console.log('fontWeight: ' + $trigger.contextMenuCommon('value', 'fontWeight'));\n  console.log('fontSize: ' + $trigger.contextMenuCommon('value', 'fontSize'));\n});\n\n$('#button-set-weight').click(function() {\n  $trigger.contextMenuCommon('value', 'fontWeight', 'bold');\n});\n\n$('#button-set-size').click(function() {\n  $trigger.contextMenuCommon('value', 'fontSize', '12pt');\n});\n```\n\n### `click`\n\n```js\n$trigger = $trigger.contextMenuCommon('click', itemKey)\n```\n\nEmulate a click operation by user.  \nThe state of checkbox or radio, `checked` and `value` property are updated.  \nThis is mainly used to toggle the checkbox.\n\nFor example, the following two codes work same:\n\n```js\n$.contextMenuCommon({\n  selector: '#trigger',\n  items: {\n\n    fontWeight: {\n      label: 'Bold Font',\n      type: 'checkbox',\n      value: ['normal', 'bold']\n    },\n\n    fontSize: {\n      label: 'Font Size',\n      items: {\n        size1: {\n          label: 'Small',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '8pt'\n        },\n        size2: {\n          label: 'Medium',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '12pt'\n        },\n        size3: {\n          label: 'Large',\n          type: 'radio',\n          radiogroup: 'fontSize',\n          value: '16pt'\n        }\n      }\n    }\n\n  }\n});\n\nvar $trigger = $('#trigger');\n\n$trigger.contextMenuCommon('click', 'fontWeight');\n$trigger.contextMenuCommon('click', 'size2');\n```\n\n```js\n// ... same to above\n\nvar $trigger = $('#trigger');\n\nvar currentValue = $trigger.contextMenuCommon('value', 'fontWeight');\n$trigger.contextMenuCommon('value', 'fontWeight',\n  currentValue === 'normal' ? 'bold' : 'normal');\n$trigger.contextMenuCommon('value', 'fontSize', '12pt');\n```\n\n## `label`\n\n*Alias:* `name`  \n*Type:* string, jQuery, DOM or Array\n\nA string that is specified to `label` property of a menu item is shown to user on the menu item.  \nIf an array is specified, the second string is shown as sub-label that is positioned to the right of the label. It is usually used to indicate a shortcut-keys of the command.  \nFor example:\n\n```js\n// In constructor options\nitems: {\n  a: {\n    label: 'Create New', // no sub-label\n    icon: 'add'\n  },\n  b: {\n    label: ['Open File...', 'Ctrl+O'],\n    icon: 'fa fa-folder-open-o' // Icon by Font Awesome\n  },\n  c: {\n    label: ['Save', 'Ctrl+S'],\n    icon: 'fa fa-floppy-o' // Icon by Font Awesome\n  },\n  d: {\n    label: ['Save As...', 'Ctrl+Shift+S']\n  },\n  e: {\n    label: ['Quit', '\\u2318Q'], // symbol for OS X\n    icon: 'quit'\n  }\n}\n```\n\nNote that the shortcut-keys are not a access-keys, and jQuery.contextMenuCommon only shows it. And your app has to handle those key events, and so on if your app supports shortcut-keys, because shortcut-keys have to work without depending on the menu.\n\nAlso, you can specify a jQuery object or a DOM element instead of a string to a label and sub-label. It is used to decorate the label or sub-label, change those dynamically, or customize those more, or you can do anything you want. Note that you can also break a layout of the menu easily.  \nFor example:\n\n```js\n// In constructor options\nitems: {\n  a: {\n    label: $('\u003cspan\u003eOpen \u003cstrong\u003eMy\u003c/strong\u003e File...\u003c/span\u003e')\n  },\n  b: {\n    label: ['Save', $('\u003cspan\u003eCtrl+\u003cspan style=\"color: blue;\"\u003eS\u003c/span\u003e\u003c/span\u003e')]\n  }\n}\n```\n\nFor example, change dynamically, and add animation:\n\n```js\nvar label = $('\u003cspan\u003eDownload Data File\u003c/span\u003e'),\n  item, rate, span, isLoading;\n\nfunction progress() {\n  if (!item) {\n    item = label.parent().css({\n      backgroundImage: 'url(\\'data:image/svg+xml;utf8,' +\n        '%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220' +\n        '%200%2025%2025%22%20width%3D%2225%22%20height%3D%2225%22%3E%3Crect%20x%3D%22' +\n        '0%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D' +\n        '%22rgba%28168%2C241%2C163%2C0.8%29%22%2F%3E%3C%2Fsvg%3E\\')',\n      // Chrome does not support adjusting background-size.\n      // backgroundSize: '0 100%',\n      backgroundSize: '0',\n      backgroundRepeat: 'repeat-y'\n    });\n    rate = span = 0;\n  }\n  if ((rate += span) \u003c 100) {\n    span = Math.floor(Math.random() * 26) + 5; // [5, 30]\n    if (span \u003e 100 - rate) { span = 100 - rate; }\n    item.animate({backgroundSize: rate + span + '%'},\n      Math.floor(Math.random() * 2501) + 500, // [500, 3000]\n      progress);\n  } else {\n    isLoading = false;\n    rate = span = 0;\n    label.text('Download Next File');\n  }\n}\n\n$.contextMenuCommon({\n  selector: '#trigger',\n  items: {\n    download: {\n      label: label,\n      icon: 'fa fa-download',\n      callback: function() {\n        if (isLoading) {\n          isLoading = false;\n          label.text('Restart Download');\n          item.stop();\n        } else {\n          isLoading = true;\n          label.text('Stop Download');\n          if (rate === 0 \u0026\u0026 span === 0) { item.css('backgroundSize', '0'); } // next\n          progress();\n        }\n        return false;\n      }\n    }\n  }\n});\n```\n\n## `icon`\n\n`icon` property accepts class names of basic icons, and class names of [Font Awesome](https://fortawesome.github.io/Font-Awesome/) icons such as `fa fa-folder-open-o` also.  \nFor example:\n\n```js\n// In constructor options\nitems: {\n  a: {\n    label: 'Basic Icon',\n    icon: 'edit'\n  },\n  b: {\n    label: 'Font Awesome Icon',\n    icon: 'fa fa-github-alt'\n    // http://fortawesome.github.io/Font-Awesome/icon/github-alt/\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanseki%2Fjquery-contextmenu-common","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanseki%2Fjquery-contextmenu-common","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanseki%2Fjquery-contextmenu-common/lists"}