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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.224.197