{"id":16217389,"url":"https://github.com/sukima/confirmed","last_synced_at":"2025-10-25T15:36:15.498Z","repository":{"id":47414482,"uuid":"98926218","full_name":"sukima/confirmed","owner":"sukima","description":"A framework agnostic asynchronous confirmation module.","archived":false,"fork":false,"pushed_at":"2023-01-04T21:50:05.000Z","size":294,"stargazers_count":3,"open_issues_count":9,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T17:56:42.721Z","etag":null,"topics":["confirmation","dialog","javascript","node","node-module","npm"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sukima.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-31T20:18:14.000Z","updated_at":"2019-11-20T16:01:47.000Z","dependencies_parsed_at":"2023-02-02T21:15:39.998Z","dependency_job_id":null,"html_url":"https://github.com/sukima/confirmed","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sukima%2Fconfirmed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sukima%2Fconfirmed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sukima%2Fconfirmed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sukima%2Fconfirmed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sukima","download_url":"https://codeload.github.com/sukima/confirmed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243982182,"owners_count":20378605,"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":["confirmation","dialog","javascript","node","node-module","npm"],"created_at":"2024-10-10T11:44:53.236Z","updated_at":"2025-10-25T15:36:05.490Z","avatar_url":"https://github.com/sukima.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Confirmed\n\nA framework agnostic asynchronous confirmation module.\n\nA very simple *promise-like* API for easily showing a confirmation and\nresolving to the result of the user input. Its main goal is to replace or\nenhance the typical `window.confirm` and many adhoc event based solutions (see\nexample below).\n\nSpecial thanks to [FunnelCloud Inc.](http://funnelcloud.io/) for graciously\nproviding inspiration, R+D, and support.\n\nLicense: MIT\n\n## Install\n\nNode.js:\n\n    npm install confirmed\n\nOR\n\n    yarn add confirmed\n\nBrowser:\n\n```html\n\u003cscript type=\"text/javascript\" src=\"/path/to/module/dist/confirmer.js\"\u003e\u003c/script\u003e\n```\n\nThe `dist/confirmer.js` is a UMD module compatible with Node.js, AMD\n(require.js), and as a browser global.\n\n## Requirements\n\nThis package uses promises. You environment will need to have a `Promise`\nimplementation. Most modern browsers and later versions of Node have such. If\nyou use this in an environment that does not you will need to include a\npolyfill.\n\n## Usage\n\nMuch like the `Promise` API the constructor for the `Confirmer` takes\na function. That function is passed a resolver object which has four functions\non it that you can use to *fulfill* the `Confirmer`.\n\n```js\nnew Confirmer(function (resolver) {\n  // Affirm confirmation\n  resolver.confirm();\n  // Reject confirmation\n  resolver.reject();\n  // Cancel confirmation\n  resolver.cancel();\n  // Reject with an Error\n  resolver.error(new Error());\n  // Register a disposer function to clean up resources\n  // Same as onDone but in the initializer function closure\n  resolver.dispose(function () { … });\n})\n```\n\nEach state can take an optional value. The `Confirmer` is a wrapper around\na `Promise` and can be treated as a promise. For example to capture any errors\nor exceptions you may trigger you would use the `catch()` function.\n\n```js\nnew Confirmer(function (resolver) { … })\n  .catch(function (reason) { console.error(reason); });\n```\n\nThe `then()` function will be passed the underlying data object:\n\n```js\nnew Confirmer(function (resolver) { … })\n  .then(function (result) {\n    console.log(result.reason);\n    console.log(result.value);\n  });\n```\n\nThe `reason` being one of `rejected`, `confirmed`, or `cancelled`. And the\n`value` is the value passed to one of the resolver functions.\n\n## API\n\n\u003ca name=\"Confirmer\"\u003e\u003c/a\u003e\n\n### Confirmer\nThe main class is referred to as `Confirmer` though the packaging is called\n`confirmed` This is simply to prevent an NPM name collision but the proper\nterm for this utility is `Confirmer` and is referenced as such in this\ndocumentation.\n\n**Kind**: global class  \n\n* [Confirmer](#Confirmer)\n    * [new Confirmer(initFn)](#new_Confirmer_new)\n    * _instance_\n        * [.onConfirmed(fn)](#Confirmer+onConfirmed) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\n        * [.onRejected(fn)](#Confirmer+onRejected) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\n        * [.onCancelled(fn)](#Confirmer+onCancelled) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\n        * ~~[.onCanceled()](#Confirmer+onCanceled)~~\n        * [.onDone(fn)](#Confirmer+onDone) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\n        * [.then(onFulfilled, onRejected)](#Confirmer+then) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n        * [.catch(onRejected)](#Confirmer+catch) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n    * _static_\n        * [.resolve(result)](#Confirmer.resolve) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\n\n\n* * *\n\n\u003ca name=\"new_Confirmer_new\"\u003e\u003c/a\u003e\n\n#### new Confirmer(initFn)\nMuch like the `Promise` API the constructor for the `Confirmer` takes a\nfunction. That function is passed a resolver object which has three\nfunctions on it that you can use to *fulfill* the `Confirmer`, one\nfunction to register an error, and a disposer function to clean up\nresources is needed. Each fulfillment function can take an optional value.\n\n#### Example\n```js\nnew Confirmer(function (resolver) {\n  // Affirm confirmation\n  resolver.confirm();\n  // Reject confirmation\n  resolver.reject();\n  // Cancel confirmation\n  resolver.cancel();\n  // Reject with an Error\n  resolver.error(new Error());\n  // Register a disposer function to clean up resources\n  // Same as onDone but in the initializer function closure\n  resolver.dispose(function () { … });\n});\n```\n\n**Params**\n\n- initFn \u003ccode\u003efunction\u003c/code\u003e - The initializer function\n\n\n* * *\n\n\u003ca name=\"Confirmer+onConfirmed\"\u003e\u003c/a\u003e\n\n#### confirmer.onConfirmed(fn) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\nRegister callback that is called when `resolver.confirm()` is triggered.\nUsed to denote that the user has confirmed in some way. (\"OK\" button,\ncorrect login credentials, etc.)\n\nIf the callback returns a new Confirmer the result will be that new\nConfirmer allowing the callback to change the fulfillment reason as part\nof the chaining. If it is simply a scalar value the fulfillment reason\nwith remain the same but the value will change.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Returns**: [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) - A new Confirmer instance for chaining  \n**Params**\n\n- fn \u003ccode\u003efunction\u003c/code\u003e - callback function called when Confirmer is confirmed\n\n\n* * *\n\n\u003ca name=\"Confirmer+onRejected\"\u003e\u003c/a\u003e\n\n#### confirmer.onRejected(fn) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\nRegister callback that is called when `resolver.rejected()` is triggered.\nUsed to denote that the user has performed an action that denied the\nconfirmation. (\"No\" button, bad password, etc.)\n\nIf the callback returns a new Confirmer the result will be that new\nConfirmer allowing the callback to change the fulfillment reason as part\nof the chaining. If it is simply a scalar value the fulfillment reason\nwith remain the same but the value will change.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Returns**: [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) - A new Confirmer instance for chaining  \n**Params**\n\n- fn \u003ccode\u003efunction\u003c/code\u003e - callback function called when Confirmer is rejected\n\n\n* * *\n\n\u003ca name=\"Confirmer+onCancelled\"\u003e\u003c/a\u003e\n\n#### confirmer.onCancelled(fn) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\nRegister callback that is called when `resolver.cancel()` is triggered.\nUsed to denote that the confirmation was cancelled and perhaps should do\nnothing.\n\nIf the callback returns a new Confirmer the result will be that new\nConfirmer allowing the callback to change the fulfillment reason as part\nof the chaining. If it is simply a scalar value the fulfillment reason\nwith remain the same but the value will change.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Returns**: [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) - A new Confirmer instance for chaining  \n**Params**\n\n- fn \u003ccode\u003efunction\u003c/code\u003e - callback function called when Confirmer is cancelled\n\n\n* * *\n\n\u003ca name=\"Confirmer+onCanceled\"\u003e\u003c/a\u003e\n\n#### ~~confirmer.onCanceled()~~\n***Deprecated***\n\nSpelling error; use `onCancelled`.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n\n* * *\n\n\u003ca name=\"Confirmer+onDone\"\u003e\u003c/a\u003e\n\n#### confirmer.onDone(fn) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\nRegister a callback that is called when any of the resolver functions are\ntriggered. This is used for clean up like closing the dialog and removing\nstale event handlers. This is also called if the `resolver.error()` is\ntriggered or something throws an exception in the initialization function\n(which can be captured by the `catch()` function just like a promise).\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Returns**: [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) - A new Confirmer instance for chaining  \n**Params**\n\n- fn \u003ccode\u003efunction\u003c/code\u003e - callback function called when Confirmer is resolved/errored\n\n\n* * *\n\n\u003ca name=\"Confirmer+then\"\u003e\u003c/a\u003e\n\n#### confirmer.then(onFulfilled, onRejected) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\nCast to a `Promise`. Will proxy to the internal promise `then()` method.\nSince the result is a Promise it will not chain as Confirmer after this.\n\nThe result of a fulfilled promise is an Object with `reason` and `value`\nproperties. See [resolve](#Confirmer.resolve) for more details of this\ninternal object.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Params**\n\n- onFulfilled \u003ccode\u003efunction\u003c/code\u003e - callback when internal promise is fulfilled\n- onRejected \u003ccode\u003efunction\u003c/code\u003e - callback when internal promise is rejected\n\n\n* * *\n\n\u003ca name=\"Confirmer+catch\"\u003e\u003c/a\u003e\n\n#### confirmer.catch(onRejected) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\nCast to a `Promise`. Will proxy to the internal promise `catch()` method.\nSince the result is a Promise it will not chain as Confirmer after this.\n\n**Kind**: instance method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Params**\n\n- onRejected \u003ccode\u003efunction\u003c/code\u003e - callback when internal promise is rejected\n\n\n* * *\n\n\u003ca name=\"Confirmer.resolve\"\u003e\u003c/a\u003e\n\n#### Confirmer.resolve(result) ⇒ [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)\nLow level utility to construct a new `Confirmer` with a fulfillment. It is\ndesigned to easily wrap the internal promise/resolution in a `Confirmer`\nobject.\n\n* if a `Confirmer` is passed it will be returned\n* if a `Promise` is passed it will become the internal promise of a new Confirmer\n* if an `Object` is passed it will become the fulfilled value of the internal promise of a new Confirmer\n\n**Warning:** Any other type will cause the Confirmer to reject with an\nerror.\n\nThe internal fulfillment value (either directly of as the result of a\npromise resolution) must be an Object with these properties:\n\n* reason `String` - the reason for the fulfillment. One of \"confirmed\", \"cancelled\", or \"rejected\".\n* value `Any` - the value associated (optional)\n\n**Kind**: static method of [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer)  \n**Returns**: [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) - a new Confirmer that has/will be resolved to the result  \n**Params**\n\n- result [\u003ccode\u003eConfirmer\u003c/code\u003e](#Confirmer) | \u003ccode\u003ePromise\u003c/code\u003e | \u003ccode\u003eObject\u003c/code\u003e - the result the new Confirmer should resolve to\n\n\n* * *\n\n\n## Examples\n\nThe following are example situations that I've run into and how this module can\nhelp reason about them.\n\n### Basic `window.confirm`\n\nIn this example we will wrap the `window.confirm`. Although this is **not**\nasynchronous it does illustrate the API.\n\n```js\nnew Confirmer(function (resolver) {\n  if (confirm('Whould you like to do this?')) {\n    resolver.confirm();\n  } else {\n    resolver.cancel();\n  }\n})\n  .onConfirmed(function () { console.log('Ok! let\\'s crack on!'); })\n  .onCancelled(function () { console.log('Maybe next time then?'); })\n  .onDone(function () { console.log('Confirm completed') });\n```\n\n### jQuery dialog\n\nHere we show how to toggle a modal dialog with jQuery.\n\n```js\nnew Confirmer(function (resolver) {\n  $('#modal-dialog button.yes').one('click', resolver.confirm);\n  $('#modal-dialog button.no').one('click', resolver.cancel);\n  $('#modal-dialog').show();\n})\n  .onConfirmed(function () { console.log('Ok! let\\'s crack on!'); })\n  .onCancelled(function () { console.log('Maybe next time then?'); })\n  .onDone(function () {\n    $('#modal-dialog button').off('click');\n    $('#modal-dialog').hide();\n  });\n```\n\n### Password prompt\n\nMaybe the resolution of the confirmation needs more logic. For example asking\nfor a password.\n\n```js\nnew Confirmer(function (resolver) {\n  function checkPassword() {\n    var passwd = $('#password-dialog input.passord').val();\n    if (passwd === 'password') {\n      resolver.confirm(123);\n    } else {\n      resolver.reject('incorrect password');\n    }\n  }\n  $('#password-dialog button.ok').one('click', checkPassword);\n  $('#password-dialog button.cancel').one('click', resolver.cancel);\n  $('#password-dialog').show();\n})\n  .onConfirmed(function (userID) {\n    console.log('User ' + userID + ', you may proceed.');\n  })\n  .onRejected(function (message) {\n    console.log('Access denied: ' + message);\n  })\n  .onDone(function () {\n    $('#password-dialog input.passord').val('');\n    $('#modal-dialog button').off('click');\n    $('#password-dialog').hide();\n  });\n```\n\n## Auto closing message box\n\nHere is an example of a message box that auto closes after 5 seconds.\n\nNotice that you can call the resolver functions multiple times and only the\nfirst one wins.\n\n```js\nnew Confirmer(function (resolver) {\n  setTimeout(resolver.cancel, 5000);\n  $('#modal-dialog button.ok').one('click', resolver.confirm);\n  $('#modal-dialog').show();\n}).onDone(function () {\n  $('#modal-dialog button').off('click');\n  $('#modal-dialog').hide();\n});\n```\n\n## Vanilla DOM Events (using the dispose function)\n\nBecause vanilla DOM events are a common area for memory leaks the expectation\nis that when you `addEventListener` you have a corresponding\n`removeEventListener`. Unfortunately this requires a reference to the event\nhandler function. This is typically accomplished using named functions.\nHowever, that also adds scope problems and more boilerplate. Some attempt to\nuse `arguments.callee`, some use `var _this = this`, and some use outer scoped\nvariables. This example takes advantage of the `dispose` API to make disposing\nresources in a cleaner (read prettier) way.\n\n```js\nlet dialog = document.getElementById('modal-dialog');\nlet buttonYes = dialog.querySelector('button.yes');\nlet buttonNo = dialog.querySelector('button.no');\n\nnew Confirmer(function (resolver) {\n  buttonYes.addEventListener('click', resolver.confirm);\n  buttonNo.addEventListener('click', resolver.cancel);\n  resolver.dispose(function () {\n    buttonYes.removeEventListener('click', resolver.confirm);\n    buttonNo.removeEventListener('click', resolver.cancel);\n  });\n  dialog.style.display = 'block';\n})\n  .onConfirmed(function () { console.log('Ok! let\\'s crack on!'); })\n  .onCancelled(function () { console.log('Maybe next time then?'); })\n  .onDone(function () { dialog.style.display = 'none'; });\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsukima%2Fconfirmed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsukima%2Fconfirmed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsukima%2Fconfirmed/lists"}