官术网_书友最值得收藏!

Using the save dialog

The Electron framework provides support for saving, opening, confirmation, and many more. These dialogs are native to each platform. We are going to use the macOS platform to see the native save dialog that macOS users are familiar with. The same code running on Windows machines triggers Windows-like dialogs.

Let's start by importing a dialog object into the menu.js file from the Electron framework:

const {
app,
Menu,
shell,
ipcMain,
BrowserWindow,
globalShortcut,
dialog
} = require('electron');

You can now use the showSaveDialog method, which requires a parent window object reference and a set of options before it can customize the behavior of the dialog.

In our case, we are going to set the title of the dialog and restrict the format to .md, which is a markdown file extension:

ipcMain.on('save', (event, arg) => {
console.log(`Saving content of the file`);
console.log(arg);

const window = BrowserWindow.getFocusedWindow();
const options = {
title: 'Save markdown file',
filters: [
{
name: 'MyFile',
extensions: ['md']
}
]
};

dialog.showSaveDialog(window, options);
});
You can find out more about dialogs, and a list of available options, in the following Electron documentation: https://electronjs.org/docs/api/dialog.

showSaveDialog receives the third parameter, that is, the callback function that gets invoked if the user closes the dialog with the Save or Cancel button. The first callback parameter provides you with the path of the file to use when saving content.

Let's see how the whole thing works.

  1. Add the console.log the path to output the file name to the terminal window:
dialog.showSaveDialog(window, options, filename => {
console.log(filename);
});
  1. Restart your application, type # hello world, and press Cmd + S or Ctrl + S. You should see the native Save dialog, as shown in the following screenshot:
  1. Change the name to test so that the final filename is test.md and click the Save button.
  2. Switch to the Terminal window and check out the output. It should contain the full path to the file that you have provided via the Save dialog. In this case, for the macOS platform, it should look as follows:
      /Users/<username>/Desktop/test.md

Sometimes, you may see the following message in the Terminal if you are a macOS user:

      objc[4988]: Class FIFinderSyncExtensionHost is implemented in both 
/System/Library/PrivateFrameworks/FinderKit.framework/Versions/
A/FinderKit (0x7fff9c38e210) and
/System/Library/PrivateFrameworks/FileProvider.framework/
OverrideBundles/FinderSyncCollaborationFileProviderOverride.bundle/
Contents/MacOS/FinderSyncCollaborationFileProviderOverride
(0x11ad85dc8).
One of the two will be used. Which one is undefined.

This is a known issue and should be fixed in future versions of macOS and Electron. Don't pay attention to this for the time being.

At this point, we have our keyboard combinations working and the application showing the Save dialog and passing the resulting file path to the main process. Now, we need to save the file.

  1. To deal with files, we need to import the fs object from the Node.js filesystem utils:
      const fs = require('fs');

We are mainly interested in the writeFileSync function, which receives the path to the file and the data and invokes the callback as soon as writing finishes.

  1. The callback returns String or undefined, the path of the file that was chosen by the user if a callback was provided, or if the dialog was canceled, it returns undefined. This is why the null-check is very important.
  2. Check if the filename value has been provided and save the file using the fs.writeFileSync method, as shown in the following code:
      dialog.showSaveDialog(window, options, filename => {
if (filename) {
console.log(`Saving content to the file: ${filename}`);
fs.writeFileSync(filename, arg);
}
});
  1. Restart the application and repeat the previous steps. Type in some text, press the shortcut, and pick the location and name for the file.
  2. This time, however, the file should appear in your filesystem. You can find it using the File browser and open it with the text editor. It should contain the content that you previously typed in:
  1. That's all we need to do. The final implementation of the save event handler is as follows:
      ipcMain.on('save', (event, arg) => {
console.log(`Saving content of the file`);
console.log(arg);

const window = BrowserWindow.getFocusedWindow();
const options = {
title: 'Save markdown file',
filters: [
{
name: 'MyFile',
extensions: ['md']
}
]
};

dialog.showSaveDialog(window, options, filename => {
if (filename) {
console.log(`Saving content to the file: ${filename}`);
fs.writeFileSync(filename, arg);
}
});
});

In this section, we achieved the following:

  • We sent the save event to the client-side (browser).
  • The browser code handles the event, fetches the current value of the text editor, and sends it back to the Node.js side.
  • The Node.js side handles the event and invokes the system save dialog.
  • Once the user defines a file name and clicks Save, the content gets saved to the local filesystem.

Congratulations—you are now able to invoke system-level Save dialogs from your applications! Now, let's learn how to load files from a local system.

主站蜘蛛池模板: 翁源县| 宝坻区| 正阳县| 梁山县| 马公市| 蓝山县| 中宁县| 福鼎市| 神农架林区| 亳州市| 红安县| 师宗县| 专栏| 长岭县| 潍坊市| 茂名市| 循化| 夏邑县| 大名县| 赤城县| 辛集市| 怀柔区| 罗城| 白水县| 大足县| 灵石县| 娄烦县| 海原县| 宣汉县| 武鸣县| 神农架林区| 开平市| 威海市| 香港 | 渑池县| 四子王旗| 阳江市| 应用必备| 苗栗县| 罗山县| 南郑县|