12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Atom Shellでファイルを選択ボタンが使えない件

Posted at

input type="file"が使えない

Atom Shellで前回の記事でkoaが使えるようになったので、express4のアップロードのkoa版を作ろうとしたらハマった。

何と、input type="file"が使えない。

何とかAtom Shellでファイルを選択ボタンを作る方法

幸い、Atom Shellにはファイルダイアログを開くAPIは用意されているので、これを使う。しかし、これはmain.js側のために用意されているもので、index.html側(レンダラー側)では直接扱えない模様。そこでIPCを使ってmain.js側と.html側で内部通信させて、ダイアログの表示要求とファイルの選択結果の受け渡しを行うことで、ファイルを選択ボタンの代替実装が行えた。

package.json
{
  "name"    : "your-app",
  "version" : "0.1.0",
  "main"    : "main.js"
}
main.js
var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.
var dialog = require('dialog');
var ipc = require('ipc');

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  if (process.platform != 'darwin')
    app.quit();
});

// This method will be called when atom-shell has done everything
// initialization and ready for creating browser windows.
app.on('ready', function() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600
  });

  ipc.on('openFileDialog', function(event, arg) {
    // レンダラー側からのファイルオープンダイアログ表示要求イベント受信時の処理
    dialog.showOpenDialog({
      properties: ['openFile', 'multiSelections']
    }, function(filePath) {
      console.log("filePath = " + filePath);
      event.sender.send('asynchronous-reply', filePath);
    });
    event.returnValue = "OK";
  });

  // and load the index.html of the app.
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});
index.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
</head>

<body>
  <h1>Hello World!</h1>
  We are using node.js
  <script>
    document.write(process.version)
  </script>
  and atom-shell
  <script>
    document.write(process.versions['atom-shell'])
  </script>.
  <button id="fileOpenBtn">ファイルを選択</button>
  <div id="out"></div>
  <!-- 以下のフォームはAtom Shellでは利用できない模様 -->
  <form method="post" enctype="multipart/form-data" action="http://localhost:3000/">
    <input type="file" name="fileName">
    <input type="submit" name="upload">
  </form>
  <script>
    var ipc = require('ipc');

    ipc.on('asynchronous-reply', function(arg) {
      // main.jsでファイルオープンダイアログでファイル選択後に呼ばれる。
      // argにmain.jsでセットしたファイルパスが入っている。
      console.log("fileName = " + arg);
      var out = document.getElementById("out");
      out.innerHTML = "fileName = " + arg;
    });

    var fileOpenBtn = document.getElementById("fileOpenBtn");
    fileOpenBtn.addEventListener("click", function() {
      // main.js側に同期イベントを送る。
      ipc.sendSync('openFileDialog');
    });
  </script>

</body>

</html>

まとめ

Atom Shellで簡単にHTML5でデスクトップアプリを実装できると思いきや、
Atom Shell固有の実装が必要な事がわかった。

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?