Skip to content

Commit

Permalink
first release
Browse files Browse the repository at this point in the history
  • Loading branch information
migliori committed Oct 23, 2019
1 parent 816bf9e commit 4fad80b
Show file tree
Hide file tree
Showing 57 changed files with 7,776 additions and 2 deletions.
167 changes: 165 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,165 @@
# bootstrap-4-file-tree
Recovers directories and files recursively with Ajax from a main directory and displays the tree structure. The script called with Ajax is provided in several server languages: PHP, ASP, Node.js, ... Programmed in pure Javascript / CSS without dependency.
# File Tree Generator

## Table of contents

* [Overview](#overview)
* [Quick start](#quick-start)
* [Options](#options)
* [How to customize the HTML/ CSS](#how-to-customize-the-html-css)
* [Connnectors](#connnectors)
* [Contribute](#contribute)
* [Versionning](#versionning)
* [Authors](#authors)
* [License](#license)

## Overview

**File Tree Generator** is a Javascript plugin built to **browse folders** and **select files**.

It retrieves directories and files recursively with Ajax from a main directory and displays the tree structure. You can browse and select, then do any stuff with the choosen file.

File Tree Generator is programmed in **pure Javascript** (compiled TypeScript) and **doesn't require any dependency**.

a **PHP connector** is provided to retrieve the main directory content, you can write your own in any server language (NodeJS, ASP, ...).

The default template is built with Bootstrap 4, but Bootstrap is **not required** at all. You can easily **add your own HTML/CSS template** and change markup to fit your needs.

## Quick start

* Upload the *dist* folder on your server
* add the HTML markup on your page:

```html
<!--
This is a minimal example.
You can change anything here,
The File Tree Generator requires only a main wrapper
with .ft-tree and .ft-explorer inside.
-->
<div id="custom-id">
<div class="ft-tree"></div>
<div class="ft-explorer"></div>
</div>
```

* add the Javascript code:

```javascript
<script src="dist/js/file-tree.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {

var options = {
mainDir: '/path/to/directory',
elementClick: function (filePath, fileName) {
// do anything you want
},
cancelBtnClick: function (filePath, fileName) {
// do anything you want
},
okBtnClick: function (filePath, fileName) {
// do anything you want
}
};

var ft = new fileTree('file-tree-wrapper', options);
});
</script>
```

## Options

Name | type | Default Value | Description
---- | ---- | ----- | -------
connector | string | 'php' | connector file extension in `dist/connectors/connector.[ext]`
explorerMode | string | 'list' | 'list' or 'grid'
extensions | array | ['.*'] | Array with the authorized file extensions
mainDir | string | 'demo-files' | main directory id
maxDeph | number | 3 | deph of the folders to browse from the main directory
cancelBtn | boolean | true | add a cancel button or not
okBtn | boolean | true | add an OK button or not
template | string | 'bootstrap4' | name of the HTML/CSS template files in *dist/templates/*
elementClick | function | `function (filePath, fileName) {console.log(filePath); console.log(fileName);}` | callback function called when the user clicks any file in the explorer
cancelBtnClick | function | `function () { console.log('Cancel'); }` | callback function called when the user clicks the explorer *cancel* button
okBtnClick | function | `function (filePath, fileName) {console.log(filePath); console.log(fileName);}` | callback function called when the user clicks the explorer *OK* button

## How to customize the HTML/ CSS

The template files are used to generate the File Explorer html code.

They are located in *dist/templates/*

### To create your own templates

* Create your HTML file + your css file with the same name for both in *dist/templates/*
* Your HTML template **MUST**:
* include exactly the same *&lt;template&gt;* tags with the exact IDs as the default Bootstrap 4 template.
ie:

```html
<template id="explorer-mode">...</template>
```

* Each *&lt;template&gt;* tag MUST include elements having the prefixed CSS classes `ft-`

* Load your template using the *template* option:

```javascript
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var options = {
// ...
template: 'your-custom-template'
};
var ft = new fileTree('file-tree-wrapper', options);
});
</script>
```

You can use any HTML structure, any element, as long as the templates are all present with their respective IDs, and all the necessary prefixed classes are present in each of them.

**WARNING**: if there's a missing *&lt;template&gt;* tag or a missing prefixed class, Javascript will throw the following console error:

```javascript
'Augh, there was an error!'
```

## Connnectors

The default connector is written in PHP.
You can write your own in any server language (nodeJs, ASP, ...). ie:

* create your connector file named *dist/connectors.connector.asp*
* Load it using the *connector* option:

```javascript
<script>
document.addEventListener("DOMContentLoaded", function(event) {

var options = {
// ...
connector: 'asp'
};

var ft = new fileTree('file-tree-wrapper', options);
});
</script>
```

## Contribute

Any new connector or cool template is welcome!

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/migliori/file-tree-generator/tags).

## Authors

* **Gilles Migliori** - _Initial work_ - [Migliori](https://github.com/migliori)

## License

This project is licensed under the GNU GENERAL PUBLIC LICENSE - see the [LICENSE](LICENSE) file for details
58 changes: 58 additions & 0 deletions demo-1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!doctype html>
<html lang="en">

<head>
<title>File Tree Generator Demo</title>
<meta name="description" content="Retrieves directories and files recursively with Ajax from a main directory and displays the tree structure. Programmed in pure Javascript / CSS without any dependency. PHP connector is provided, you can write your own in any server language (NodeJS, ASP, ...)">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>

<body>

<h1 class="pt-5 text-center">File Tree Generator Demo</h1>

<div class="d-flex mx-auto justify-content-center my-3" role="group">
<a href="#" class="btn btn-secondary mr-4 disabled">Demo 1</a>
<a href="demo-2.html" class="btn btn-primary">Demo 2</a>
</div>

<p class="text-center">Documentation &amp; Download: <a href="https://github.com/migliori/file-tree-generator" title="File Tree Generator">https://github.com/migliori/file-tree-generator</a></p>
<div class="py-2 mb-4 text-center text-muted border">
<p id="ft-output" class="small mb-0">&nbsp;<br>&nbsp;</p>
</div>
<div class="container" id="file-tree-wrapper">
<div class="row">
<div class="col-sm-3 ft-tree"></div>
<div class="col-sm-9 ft-explorer"></div>
</div>
</div>

<p class="text-center"><a href="https://www.miglisoft.com/">@miglisoft</a></p>

<script src="dist/js/file-tree.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {

var options = {
mainDir: 'demo-files',
elementClick: function (filePath, fileName) {
document.getElementById('ft-output').innerHTML = '<strong>filePath</strong>: ' + filePath + ',<br><strong>fileName</strong>: ' + fileName;
},
cancelBtnClick: function (filePath, fileName) {
alert('Cancelled');
},
okBtnClick: function (filePath, fileName) {
alert('filePath: ' + filePath + ' - fileName: ' + fileName);
}
};

var ft = new fileTree('file-tree-wrapper', options);
});
</script>
</body>

</html>
85 changes: 85 additions & 0 deletions demo-2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!doctype html>
<html lang="en">

<head>
<title>File Tree Generator Demo 2 - Bootstrap modal Image Picker</title>
<meta name="description" content="Retrieves directories and files recursively with Ajax from a main directory and displays the tree structure. Programmed in pure Javascript / CSS without any dependency. PHP connector is provided, you can write your own in any server language (NodeJS, ASP, ...)">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>

<body>

<h1 class="pt-5 text-center">File Tree Generator Demo 2 - Bootstrap modal Image Picker</h1>

<div class="d-flex mx-auto justify-content-center my-3" role="group">
<a href="demo-1.html" class="btn btn-primary mr-4">Demo 1</a>
<a href="#" class="btn btn-secondary disabled">Demo 2</a>
</div>

<p class="text-center">Documentation &amp; Download: <a href="https://github.com/migliori/file-tree-generator" title="File Tree Generator">https://github.com/migliori/file-tree-generator</a></p>
<!-- Button trigger modal -->
<div class="text-center my-5">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#file-tree-modal">Choose an image</button>
</div>

<!-- Output image -->
<div id="ft-output" class="text-center my-5"></div>

<!-- Modal -->
<div class="modal fade" id="file-tree-modal" tabindex="-1" role="dialog" aria-labelledby="file-tree-modal-label" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">

<h5 class="modal-title" id="file-tree-modal-label">Choose an image</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="container" id="file-tree-wrapper">
<div class="row">
<div class="col-sm-3 ft-tree"></div>
<div class="col-sm-9 ft-explorer"></div>
</div>
</div>
</div>
</div>
</div>
</div>

<p class="text-center"><a href="https://www.miglisoft.com/">@miglisoft</a></p>

<script src="dist/js/file-tree.js"></script>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script>
$(document).ready(function() {

var options = {
mainDir: 'demo-files',
explorerMode: 'grid',
extensions: ['.jpg', '.jpeg', '.png'],
elementClick: function (filePath, fileName) {
},
cancelBtnClick: function (filePath, fileName) {
$('#file-tree-modal').modal('hide');
},
okBtnClick: function (filePath, fileName) {
$('#ft-output').html('<img src="/' + filePath + '" class="img-fluid img-thumbnail" alt="">');
$('#file-tree-modal').modal('hide');
}
};

var ft = new fileTree('file-tree-wrapper', options);
});
</script>
</body>

</html>
Binary file added demo-files/So Much Trouble In The World.mp3
Binary file not shown.
Binary file added demo-files/animals/animal-brown-horse.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/archive-document.zip
Binary file not shown.
Binary file added demo-files/art-creative-metal-creativity.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/blue-abstract-glass-balls.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/books-magazines-building-school.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/city-houses-village-buildings.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/construction-work-carpenter-tools.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/nature/dawn-nature-sunset-trees.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/nature/nature-sky-sunset-sun.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/nature/wood-nature-forest-bridge.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo-files/open-office-document.odt
Binary file not shown.
Binary file added demo-files/pdf-document.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions demo-files/unknown file.url
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://www.phpcrudgenerator.com/
Empty file added demo-files/web-page.html
Empty file.
Binary file added demo-files/word-document.doc
Binary file not shown.
67 changes: 67 additions & 0 deletions dist/connectors/connector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
//
// jQuery File Tree PHP Connector
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
// 1.00 - released (24 March 2008)
//
// Output a list of files for jQuery File Tree
//

$root = rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$main_dir = $root . rtrim(urldecode($_POST['dir']), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$authorized_ext = array_values(json_decode(stripslashes($_POST['ext'])));
if (file_exists($main_dir)) {
$filedata = scan_recursively($main_dir, $authorized_ext);
echo json_encode($filedata);
} else {
echo 'cannot open dir ' . $main_dir;
}

function scan_recursively($source_dir, $authorized_ext, $directory_depth = 5, $hidden = false)
{
if ($fp = @opendir($source_dir)) {
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, '/').'/';

while (false !== ($file = readdir($fp))) {
// Remove '.', '..', and hidden files [optional]
if (! trim($file, '.') or ($hidden == false && $file[0] == '.')) {
continue;
}

if (($directory_depth < 1 or $new_depth > 0) && @is_dir($source_dir.$file)) {
$filedata[$file] = scan_recursively($source_dir.$file.'/', $authorized_ext, $new_depth, $hidden);
} else if(is_authorized($file, $authorized_ext)) {
$filedata[] = array(
'ext' => pathinfo($file, PATHINFO_EXTENSION),
'name' => $file,
'size' => filesize($source_dir.$file)
);
}
}

closedir($fp);
return $filedata;
}
echo 'can not open dir';
return false;
}

function is_authorized($file, $authorized_ext) {
$ext = '.' . pathinfo($file, PATHINFO_EXTENSION);
if ($authorized_ext[0] === '.*' || in_array($ext, $authorized_ext)) {
return true;
}

return false;
}
Binary file added dist/icons/fonts/file-tree-icons.eot
Binary file not shown.
Loading

0 comments on commit 4fad80b

Please sign in to comment.