{"_id":"54d847c125e90a0d00db551f","version":{"_id":"54d5635532d98b0d00384afb","project":"54d53c7b23010a0d001aca0c","__v":10,"forked_from":"54d53c7c23010a0d001aca0f","createdAt":"2015-02-07T00:59:01.934Z","releaseDate":"2015-02-07T00:59:01.934Z","categories":["54d5635632d98b0d00384afc","54d5635632d98b0d00384afd","54d5635632d98b0d00384afe","54d5635632d98b0d00384aff","54d5635632d98b0d00384b00","54d5635632d98b0d00384b01","54d5635632d98b0d00384b02","54d652097e05890d006f153e","54dd1315ca1e5219007e9daa","54e21e2b22de1c230094b147","54e68e62a43fe13500db3879","54fa1d3fe7a0ba2f00306309","551c453a23a1ee190034d19a","551df586e52a0b23000c62b6","551f39be6886f8230055f02a","55a6720751457325000e4d97"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.1.0","version":"0.1"},"project":"54d53c7b23010a0d001aca0c","__v":96,"category":{"_id":"54dd1315ca1e5219007e9daa","pages":["54dd1324ca1e5219007e9dac","54e26fe6dd4c990d00479bef","5516e2d97f5d0919007d0701"],"version":"54d5635532d98b0d00384afb","project":"54d53c7b23010a0d001aca0c","__v":3,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-02-12T20:54:45.914Z","from_sync":false,"order":8,"slug":"user-interface","title":"User Interface"},"parentDoc":null,"user":"54cfa8e1a8a4fd0d00b7fd1d","updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-02-09T05:38:09.639Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"A straightforward way to interact with the user is through dialogs. Cloud9 comes with a set of common dialogs that will make it easy to add basic interaction to your plugin. The set of common dialogs is used throughout Cloud9 by the core plugins and using them will give the user a consistent experience.\n\nThis guide will go over each of the common dialogs and provide code examples accompanied by screenshots to get you started using dialogs. It's also pretty easy to create dialogs of your own. We'll add a guide on that in the future. For now use the mailinglist to ask questions or check out [the source](https://github.com/c9/core/tree/master/plugins/c9.ide.dialog.common).\n\n- [dialog.alert](#dialog-alert)\n- [dialog.confirm](#dialog-confirm)\n- [dialog.question](#dialog-question)\n- [dialog.error](#dialog-error)\n- [dialog.notification](#dialog-notification)\n- [notification.bubble](#notification-bubble)\n- [dialog.filechange](#dialog-filechange)\n- [dialog.fileoverwrite](#dialog-fileoverwrite)\n- [dialog.fileremove](#dialog-fileremove)\n- [dialog.file](#dialog-file)\n\n# dialog.alert\n\nUse the alert dialog to notify users of something that happened, similar to the native `window.alert()` function in the browser. The user can close the window by clicking an `OK`. You can set the title a heading and the body of the window and use both plain text and html for the content. \n\nHere's a simple example\n```\nvar alert = imports[\"dialog.alert\"].show;\nalert(\"Success!\");\n```\n\nAnd one a bit more elaborate:\n```\nalert(\"Download\", \n    \"Download success!\", \n    \"You have successfully download this file\",\n    function(){\n        console.log(\"The user has closed the alert\");\n    });\n```\n\nYou can also show a \"don't show this message again\" checkbox that will allow the user to silence future messages. In the example below, we're using the settings plugin to store the choice of the user.\n```\nvar alertDialog = imports[\"dialog.alert\"];\n\nif (settings.getBool(\"user/my-plugin/:::at:::no-alert\"))\n    return;\n\nalertDialog.show(\"Terminal\", \n    \"Do you want to close this terminal?\", \n    \"Closing the terminal will stop <strong>all the running processes</strong> in that session.\",\n    function(){\n        if (alertDialog.dontShow)\n            settings.set(\"user/my-plugin/@no-alert\", true);\n    }, {\n        isHTML: true,\n        showDontShow: true\n    });\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/rV63KW03Q9Wx23aeD5G3_2015-02-13_2123.png\",\n        \"2015-02-13_2123.png\",\n        \"785\",\n        \"200\",\n        \"#797979\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.confirm\n\nUse the confirm dialog to ask users of to confirm an action, similar to the native `window.confirm()` function in the browser. The user can confirm by clicking the `OK` button or pressing 'Cancel' otherwise. Similar to the alert dialog, you can set the title a heading and the body of the window and use both plain text and html for the content.\n\n```\nvar confirm = imports[\"dialog.confirm\"].show;\n\nconfirm(\"Save changes?\",\n    \"Do you want to save these changes?\",\n    \"The file 'stuff.js' has changed. Click OK to save the changes?\",\n    function(){\n        console.log(\"The user confirmed\");\n    },\n    function(){\n        console.log(\"The user cancelled\");\n    });\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/tfs59NrhSzuCiOTdZ5S3_2015-02-13_2126.png\",\n        \"2015-02-13_2126.png\",\n        \"735\",\n        \"188\",\n        \"#8cb474\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.question\n\nUse the question dialog to ask yes/no questions to users. The dialog optionally also allows yes to all and no to all. Similar to the alert dialog, you can set the title a heading and the body of the window and use both plain text and html for the content.\n\n```\nvar question = imports[\"dialog.question\"].show;\n\nquestion(\"Editor\",\n    \"Would you like to delete the selected items?\",\n    \"Click Yes to delete the selected items\",\n    function(){\n        console.log(\"The user clicked Yes\");\n    },\n    function(){\n        console.log(\"The user clicked No\");\n    });\n```\n\nHere's a more complex example enabling the yes to all buttons:\n```\nvar questionDialog = imports[\"dialog.question\"];\n\nquestionDialog.show(\"my-plugin\",\n    \"The file 'blah.js' has changed.\",\n    \"Would you like to update 'blah.js' to the latest version?\",\n    function(all){\n        var button = \"Yes\" + (all ? \" to All\" : \"\");\n        console.log(\"The user clicked \" + button);\n    },\n    function(all){\n        var button = \"No\" + (all ? \" to All\" : \"\");\n        console.log(\"The user clicked \" + button);\n    }, {\n        all: true,\n        cancel: true\n    });\n```\n\nThe question dialog supports the `dontAsk`, similar to the `dontShow` in the alert dialog. The question dialog has several other features and APIs that you can find in [the reference guide](https://docs.c9.io/api/#!/api/dialog.question).\n\n*For a complex example check out how the question dialog is used in [the watcher gui plugin](https://github.com/c9/core/blob/master/plugins/c9.ide.watcher/gui.js)*\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/BiyOiaJoTi8J3IqWY3Sg_2015-02-13_2128.png\",\n        \"2015-02-13_2128.png\",\n        \"735\",\n        \"185\",\n        \"#8ab470\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.error\n\nUse the error dialog to notify users of an action that has failed. The error dialog display a small banner at the top of the page that can automatically hide after a while. It can also be closed by the user.\n\n```\nvar showError = imports[\"dialog.error\"].show;\n\nif (err) \n    return showError(\"Something terrible has happened!\");\n```\n\nYou can set the 2nd argument to the amount of milliseconds that you'd like the error to be shown to the user. By default this is set to 15000 (15 seconds).\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/FB8MtsFrRM278jiJECQC_2015-02-13_2131.png\",\n        \"2015-02-13_2131.png\",\n        \"735\",\n        \"103\",\n        \"#c83717\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.notification\n\nUse the notification dialog to notify users of a special state that the IDE is in. The notification dialog display a space at the upmost top of the UI of an arbitrary height that is very hard to miss by the user. Only use the notification dialog for very important states. For instance, we use it for the Read-Only mode and the Debug mode of the IDE. The user can optionally close the notification. You are solely responsible for the styling of the notification through css.\n\n```\nvar notify = imports[\"dialog.notification\"].show;\n\nvar showCloseButton = true;\nnotify(\"<div class='mybar'>Consider yourself notified!</div>\", showCloseButton);\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/SnOqgbBTnSmGAnDSsb9w_2015-02-13_2134.png\",\n        \"2015-02-13_2134.png\",\n        \"735\",\n        \"119\",\n        \"#fba42c\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# notification.bubble\n\nAnother type of notification is the `notification.bubble` which acts similar to growl on OSX, displaying a bubble in the top right corner of the screen.\n\n```\nvar bubble = imports[\"notification.bubble\"];\n\nbubble.popup(\"The user just came online\", true, function(){\n    console.log(\"The bubble was closed\");\n});\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/XORYS8eTQ2KlaU5CgREQ_2015-02-13_2135.png\",\n        \"2015-02-13_2135.png\",\n        \"735\",\n        \"128\",\n        \"#3f8c40\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n*Note that only 4 bubbles are allowed on the screen at one time and that the user can configure their IDE to not show the bubbles at all.*\n\n# dialog.filechange\n\nUse the filechange dialog to notify a user of changes to a file that needs updating. The dialog optionally also allows a 'to all' checkbox and a merge button. Similar to the alert dialog, you can set the title and the heading of the window.\n\n```\nvar filechangeDialog = imports[\"dialog.filechange\"];\n\nfilechangeDialog.show(\"File changed\", \n    \"File 'people.js' has changed\", \n    function(all){\n        console.log(\"Use local copy\" + (all ? \" for all\" : \"\"));\n    }, \n    function(all){\n        console.log(\"Use remote copy\" + (all ? \" for all\" : \"\"));\n    }, \n    function(all){\n        console.log(\"Merge files\" + (all ? \" for all\" : \"\"));\n    }, {\n        all: true,\n        merge: true\n    });\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/tI9oC2jRTiUEL8CpJQaw_2015-02-13_2141.png\",\n        \"2015-02-13_2141.png\",\n        \"735\",\n        \"224\",\n        \"#5c9c6c\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.fileoverwrite\n\nUse the fileoverwrite dialog to ask a user to overwrite a file or any other content. The dialog optionally also allows overwrite all, skip all and a cancel button. Similar to the alert dialog, you can set the title, heading and the body of the window.\n\n```\nvar fileoverwriteDialog = imports[\"dialog.fileoverwrite\"];\n\nfileoverwriteDialog.show(\"Uploading\", \n    \"File 'people.js' already exists\", \n    \"Would you like to overwrite 'people.js'?\",\n    function(all){\n        console.log(\"Overwrite\" + (all ? \" for all\" : \"\"));\n    }, \n    function(all){\n        console.log(\"Skip\" + (all ? \" for all\" : \"\"));\n    }, {\n        all: true,\n        cancel: true\n    });\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ZZTEBWeS6uXiMsnF3ERg_2015-02-13_2144.png\",\n        \"2015-02-13_2144.png\",\n        \"735\",\n        \"185\",\n        \"#86b268\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.fileremove\n\nUse the fileremove dialog to remove a set of files. Unlike the other dialogs, this dialog expect to be passed an array of [stat objects](https://docs.c9.io/api/#!/api/fs-method-stat) and doesn't allow much configuration.\n\n```\nvar fileremoveDialog = imports[\"dialog.fileremove\"];\n\nfs.readdir(\"/\", function(err, files){\n    if (err) return console.error(err);\n    \n    fileremoveDialog.show(files, function(file){\n        fs.unlink(file.path, function(err){\n            console.log(\"Removed \", file.path);\n        });\n    });\n});\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/eLMLhdLRFaepNH4KIJ5Q_2015-02-13_2149.png\",\n        \"2015-02-13_2149.png\",\n        \"735\",\n        \"188\",\n        \"#86b071\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]\n# dialog.file\n\nUse the file dialog to have a user pick a file path or directory path. Similar to those offered by most operating systems, the file dialog allows a user to navigate the file system and find a folder and optionally a filename to open, save or otherwise. You can set the caption of the button to specify the action that is involved. The result of the dialog is a path to use in your action. Cloud9 uses this dialog for the Save As functionality as well as choosing the directory in the run panel.\n\n```\nvar fileDialog = imports[\"dialog.file\"];\n\nfileDialog.show(\"Save something\", \"/example/test.js\", \n    function(path, stat, done){\n        console.log(\"Chosen path is \", path, \" and is currently a \", stat.mime);\n    }, \n    function(){\n        console.log(\"Action cancelled\");\n    }, {\n        createFolderButton: true,\n        showFilesCheckbox: true,\n        hideFileInput: false,\n        chooseCaption: \"Save\"\n    });\n```\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/4uBOm3UAQ76hhDdV8OxC_2015-02-13_2152.png\",\n        \"2015-02-13_2152.png\",\n        \"735\",\n        \"419\",\n        \"#74a1d4\",\n        \"\"\n      ]\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"using-dialogs","type":"basic","title":"Built-in Dialogs"}
A straightforward way to interact with the user is through dialogs. Cloud9 comes with a set of common dialogs that will make it easy to add basic interaction to your plugin. The set of common dialogs is used throughout Cloud9 by the core plugins and using them will give the user a consistent experience. This guide will go over each of the common dialogs and provide code examples accompanied by screenshots to get you started using dialogs. It's also pretty easy to create dialogs of your own. We'll add a guide on that in the future. For now use the mailinglist to ask questions or check out [the source](https://github.com/c9/core/tree/master/plugins/c9.ide.dialog.common). - [dialog.alert](#dialog-alert) - [dialog.confirm](#dialog-confirm) - [dialog.question](#dialog-question) - [dialog.error](#dialog-error) - [dialog.notification](#dialog-notification) - [notification.bubble](#notification-bubble) - [dialog.filechange](#dialog-filechange) - [dialog.fileoverwrite](#dialog-fileoverwrite) - [dialog.fileremove](#dialog-fileremove) - [dialog.file](#dialog-file) # dialog.alert Use the alert dialog to notify users of something that happened, similar to the native `window.alert()` function in the browser. The user can close the window by clicking an `OK`. You can set the title a heading and the body of the window and use both plain text and html for the content. Here's a simple example ``` var alert = imports["dialog.alert"].show; alert("Success!"); ``` And one a bit more elaborate: ``` alert("Download", "Download success!", "You have successfully download this file", function(){ console.log("The user has closed the alert"); }); ``` You can also show a "don't show this message again" checkbox that will allow the user to silence future messages. In the example below, we're using the settings plugin to store the choice of the user. ``` var alertDialog = imports["dialog.alert"]; if (settings.getBool("user/my-plugin/@no-alert")) return; alertDialog.show("Terminal", "Do you want to close this terminal?", "Closing the terminal will stop <strong>all the running processes</strong> in that session.", function(){ if (alertDialog.dontShow) settings.set("user/my-plugin/@no-alert", true); }, { isHTML: true, showDontShow: true }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/rV63KW03Q9Wx23aeD5G3_2015-02-13_2123.png", "2015-02-13_2123.png", "785", "200", "#797979", "" ] } ] } [/block] # dialog.confirm Use the confirm dialog to ask users of to confirm an action, similar to the native `window.confirm()` function in the browser. The user can confirm by clicking the `OK` button or pressing 'Cancel' otherwise. Similar to the alert dialog, you can set the title a heading and the body of the window and use both plain text and html for the content. ``` var confirm = imports["dialog.confirm"].show; confirm("Save changes?", "Do you want to save these changes?", "The file 'stuff.js' has changed. Click OK to save the changes?", function(){ console.log("The user confirmed"); }, function(){ console.log("The user cancelled"); }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/tfs59NrhSzuCiOTdZ5S3_2015-02-13_2126.png", "2015-02-13_2126.png", "735", "188", "#8cb474", "" ] } ] } [/block] # dialog.question Use the question dialog to ask yes/no questions to users. The dialog optionally also allows yes to all and no to all. Similar to the alert dialog, you can set the title a heading and the body of the window and use both plain text and html for the content. ``` var question = imports["dialog.question"].show; question("Editor", "Would you like to delete the selected items?", "Click Yes to delete the selected items", function(){ console.log("The user clicked Yes"); }, function(){ console.log("The user clicked No"); }); ``` Here's a more complex example enabling the yes to all buttons: ``` var questionDialog = imports["dialog.question"]; questionDialog.show("my-plugin", "The file 'blah.js' has changed.", "Would you like to update 'blah.js' to the latest version?", function(all){ var button = "Yes" + (all ? " to All" : ""); console.log("The user clicked " + button); }, function(all){ var button = "No" + (all ? " to All" : ""); console.log("The user clicked " + button); }, { all: true, cancel: true }); ``` The question dialog supports the `dontAsk`, similar to the `dontShow` in the alert dialog. The question dialog has several other features and APIs that you can find in [the reference guide](https://docs.c9.io/api/#!/api/dialog.question). *For a complex example check out how the question dialog is used in [the watcher gui plugin](https://github.com/c9/core/blob/master/plugins/c9.ide.watcher/gui.js)* [block:image] { "images": [ { "image": [ "https://files.readme.io/BiyOiaJoTi8J3IqWY3Sg_2015-02-13_2128.png", "2015-02-13_2128.png", "735", "185", "#8ab470", "" ] } ] } [/block] # dialog.error Use the error dialog to notify users of an action that has failed. The error dialog display a small banner at the top of the page that can automatically hide after a while. It can also be closed by the user. ``` var showError = imports["dialog.error"].show; if (err) return showError("Something terrible has happened!"); ``` You can set the 2nd argument to the amount of milliseconds that you'd like the error to be shown to the user. By default this is set to 15000 (15 seconds). [block:image] { "images": [ { "image": [ "https://files.readme.io/FB8MtsFrRM278jiJECQC_2015-02-13_2131.png", "2015-02-13_2131.png", "735", "103", "#c83717", "" ] } ] } [/block] # dialog.notification Use the notification dialog to notify users of a special state that the IDE is in. The notification dialog display a space at the upmost top of the UI of an arbitrary height that is very hard to miss by the user. Only use the notification dialog for very important states. For instance, we use it for the Read-Only mode and the Debug mode of the IDE. The user can optionally close the notification. You are solely responsible for the styling of the notification through css. ``` var notify = imports["dialog.notification"].show; var showCloseButton = true; notify("<div class='mybar'>Consider yourself notified!</div>", showCloseButton); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/SnOqgbBTnSmGAnDSsb9w_2015-02-13_2134.png", "2015-02-13_2134.png", "735", "119", "#fba42c", "" ] } ] } [/block] # notification.bubble Another type of notification is the `notification.bubble` which acts similar to growl on OSX, displaying a bubble in the top right corner of the screen. ``` var bubble = imports["notification.bubble"]; bubble.popup("The user just came online", true, function(){ console.log("The bubble was closed"); }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/XORYS8eTQ2KlaU5CgREQ_2015-02-13_2135.png", "2015-02-13_2135.png", "735", "128", "#3f8c40", "" ] } ] } [/block] *Note that only 4 bubbles are allowed on the screen at one time and that the user can configure their IDE to not show the bubbles at all.* # dialog.filechange Use the filechange dialog to notify a user of changes to a file that needs updating. The dialog optionally also allows a 'to all' checkbox and a merge button. Similar to the alert dialog, you can set the title and the heading of the window. ``` var filechangeDialog = imports["dialog.filechange"]; filechangeDialog.show("File changed", "File 'people.js' has changed", function(all){ console.log("Use local copy" + (all ? " for all" : "")); }, function(all){ console.log("Use remote copy" + (all ? " for all" : "")); }, function(all){ console.log("Merge files" + (all ? " for all" : "")); }, { all: true, merge: true }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/tI9oC2jRTiUEL8CpJQaw_2015-02-13_2141.png", "2015-02-13_2141.png", "735", "224", "#5c9c6c", "" ] } ] } [/block] # dialog.fileoverwrite Use the fileoverwrite dialog to ask a user to overwrite a file or any other content. The dialog optionally also allows overwrite all, skip all and a cancel button. Similar to the alert dialog, you can set the title, heading and the body of the window. ``` var fileoverwriteDialog = imports["dialog.fileoverwrite"]; fileoverwriteDialog.show("Uploading", "File 'people.js' already exists", "Would you like to overwrite 'people.js'?", function(all){ console.log("Overwrite" + (all ? " for all" : "")); }, function(all){ console.log("Skip" + (all ? " for all" : "")); }, { all: true, cancel: true }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/ZZTEBWeS6uXiMsnF3ERg_2015-02-13_2144.png", "2015-02-13_2144.png", "735", "185", "#86b268", "" ] } ] } [/block] # dialog.fileremove Use the fileremove dialog to remove a set of files. Unlike the other dialogs, this dialog expect to be passed an array of [stat objects](https://docs.c9.io/api/#!/api/fs-method-stat) and doesn't allow much configuration. ``` var fileremoveDialog = imports["dialog.fileremove"]; fs.readdir("/", function(err, files){ if (err) return console.error(err); fileremoveDialog.show(files, function(file){ fs.unlink(file.path, function(err){ console.log("Removed ", file.path); }); }); }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/eLMLhdLRFaepNH4KIJ5Q_2015-02-13_2149.png", "2015-02-13_2149.png", "735", "188", "#86b071", "" ] } ] } [/block] # dialog.file Use the file dialog to have a user pick a file path or directory path. Similar to those offered by most operating systems, the file dialog allows a user to navigate the file system and find a folder and optionally a filename to open, save or otherwise. You can set the caption of the button to specify the action that is involved. The result of the dialog is a path to use in your action. Cloud9 uses this dialog for the Save As functionality as well as choosing the directory in the run panel. ``` var fileDialog = imports["dialog.file"]; fileDialog.show("Save something", "/example/test.js", function(path, stat, done){ console.log("Chosen path is ", path, " and is currently a ", stat.mime); }, function(){ console.log("Action cancelled"); }, { createFolderButton: true, showFilesCheckbox: true, hideFileInput: false, chooseCaption: "Save" }); ``` [block:image] { "images": [ { "image": [ "https://files.readme.io/4uBOm3UAQ76hhDdV8OxC_2015-02-13_2152.png", "2015-02-13_2152.png", "735", "419", "#74a1d4", "" ] } ] } [/block]