Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to open a "Select folder" dialog from NodeJS (server-side, not browser)?

Why would you want to show a file/folder dialog on the server-side?

I'm building a project that is intended to be ran locally (both the Node server-side part and client-side in the browser), where I'd like to be able to select a path, add it to some list or JSON file, and then maintain some projects in it (webpack'ing, read files, serve via express, etc).

Mostly just for personal use, for now anyways.

The reason I ask to do this via Node instead of the browser is so I can somehow get around the security implications in modern browsers that prevents, upon selecting a folder, from revealing the full local folder paths on the client-side (from an <input> tag).

Not only that, but I also:

  • DON'T need to upload any files, or
  • DON'T need the list of files contained in the selected folder.

I just need:

  • a way to pick a folder in a user-friendly manner, and...
  • submit it's path to the server
  • (or have the server prompt for it, and store it somewhere).

Take this input tag for example:

<input id="open-project" type="file" />

This will result this type of popup, which is great for digging into folders, pasting portions of paths to quickly navigate where you need, go to your Quick Access / Favorites, etc...

Shows the Open file dialog

But it's intended for selecting files, with no paths exposed, nothing useful to pass on to the server.

However...

If you switch it to this...

<input id="open-project" type="file" webkitdirectory directory />

You end up with this dreadful dialog box, which assumes you want to upload ALL THE FILES contained in the folder.

enter image description here

enter image description here


So it doesn't really look like <input> is the way to go.

Maybe there's an existing module that does this on the server-side? That way I could:

  • 'Invoke' it from the client-side, via AJAX for example
  • which would then trigger it on the server
  • and then show me the folder-select prompt

Or...

Make, a... tree-view in the browser... that communicates back-and-forth with the node side to dig down the local filesystem...

Any suggestions?

like image 758
chamberlainpi Avatar asked Aug 02 '18 14:08

chamberlainpi


People also ask

How do I read a directory in node JS?

The fs. readdir() method is used to asynchronously read the contents of a given directory. The callback of this method returns an array of all the file names in the directory. The options argument can be used to change the format in which the files are returned from the method.

How node JS works on server-side?

Node. js is a JavaScript framework for writing server-side applications. In its simplest form it allows you to trigger small JavaScript programs from the command line without any browser involved. For example, assuming node is installed if you write a JavaScript program in a file called hello.


1 Answers

I've accomplished this by spawning a child powershell process, and passing that value back up to the parent. This would only work on a Windows server, but something like this should work:

let psScript = `
Function Select-FolderDialog
{
    param([string]$Description="Select Folder",[string]$RootFolder="Desktop")

 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
     Out-Null     

   $objForm = New-Object System.Windows.Forms.FolderBrowserDialog
        $objForm.Rootfolder = $RootFolder
        $objForm.Description = $Description
        $Show = $objForm.ShowDialog()
        If ($Show -eq "OK")
        {
            Return $objForm.SelectedPath
        }
        Else
        {
            Write-Error "Operation cancelled by user."
        }
    }

$folder = Select-FolderDialog # the variable contains user folder selection
write-host $folder
`

That's essentially the script that you need to prompt for folder location, then write it to the host (similar to a console.log)

then you'd need to execute this script and handle the output:

var spawn = require("child_process").spawn,child;
child = spawn("powershell.exe",psScript);
child.stdout.on("data",function(data){
    console.log("Powershell Data: " + data);
});
child.stderr.on("data",function(data){
    //this script block will get the output of the PS script
    console.log("Powershell Errors: " + data);
});
child.on("exit",function(){
    console.log("Powershell Script finished");
});
child.stdin.end(); //end input
like image 62
Roger Hernandez Avatar answered Sep 17 '22 15:09

Roger Hernandez