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

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.

主站蜘蛛池模板: 定南县| 布尔津县| 林周县| 神木县| 冕宁县| 怀宁县| 朝阳县| 聂拉木县| 南昌县| 阿拉善左旗| 安平县| 衡阳县| 喀喇沁旗| 班戈县| 惠安县| 六枝特区| 常宁市| 元谋县| 密山市| 西安市| 大同县| 克什克腾旗| 裕民县| 准格尔旗| 青州市| 汕头市| 宁明县| 中宁县| 常熟市| 无锡市| 德庆县| 灵宝市| 韶关市| 增城市| 广元市| 建始县| 衡南县| 徐州市| 浮山县| 四子王旗| 鸡泽县|