## Fileuploader Documentation

Welcome to Fileuploader's documentation.

Fileuploader is a beautiful and powerful HTML5 file upload plugin. A jQuery, PHP and Node.js tool that transforms the standard file input into a revolutionary and fancy field on your page. The Fileuploader Javascript plugin works for servers based on ASP.NET, C#, Python and others that supports standard HTML form file uploads as well.

The documentation describes all options and features so you will see that the Fileuploader can be easily implemented in many systems. In average, you need less than five minutes to link the plugin files into your HTML page to get your new file input working.

### What's included

Checkout the files that you'll see upon downloading.

- dist
  - font
  - jquery.fileuploader.min.css
  - jquery.fileuploader.min.js
- examples
- src
  - php
    - class.fileuploader.php
  - node
    - fileuploader.js
    - package.json
  - thirdparty
    - s3
  - jquery.fileuploader.sass
  - jquery.fileuploader.js
- documentation.html

### Contact Us

Please don't hesitate to contact us with any regarding questions or other business inquiries using live chat or write an email to contact@innostudio.de. We are looking forward to answer your questions within 24 hours.

### Getting started

Get started with the installation instructions.

## Installation

Get the plugin zip file on the download page. We have to install Fileuploader by linking in our document `<head>` the css and js files from dist folder. Also don't forget to load jQuery library.

    <!-- font -->
    <link href="dist/font/font-fileuploader.css" media="all" rel="stylesheet">

    <!-- css -->
    <link href="dist/jquery.fileuploader.min.css" media="all" rel="stylesheet">

    <!-- js -->
    <script src="//code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
    <script src="dist/jquery.fileuploader.min.js" type="text/javascript"></script>

With the files in place we can now set up the Fileuploader instance.

## How to use

Create a standard HTML form element. In this form we will have our file input and maybe other fields. We don't need to put the file input into a `<form>` element if we want to upload the files separately using Ajax.

    <form action="submit.php" method="post" enctype="multipart/form-data">
        <!-- file input -->
        <input type="file" name="files">

        <input type="submit">
    </form>

Select a file input element with a jQuery selector and call the `fileuploader` method.

    <script type="text/javascript">
        $(document).ready(function() {
            $('input[name="files"]').fileuploader({
                // Options will go here
            });
        });
    </script>

While using a Node.js server or others besides PHP, consider to set the option `inputNameBrackets: false`.

Now when we have the first view of Fileuploader working, we can configurate it using the examples or the options section.

## Examples

In the following examples we collected different usages of the Fileuploader. Don't forget that some examples have subfolders for different modes and that you can combine examples together. Please check all .css, .js and .php files from the examples.

Check also the Inspect Element tool (Network, Sources and Console tab) in your browser to understand the configuration much easier.

Modes:

- Default
- Add More
- Ajax mode
- Drag&Drop with form submit

Themes:

- Default
- One-button
- Drag&Drop
- Drop-In
- Box-After
- Thumbnails

Preloaded files:

- Preloaded files

Image editor:

- Image editor in a form
- Image editor with ajax
- Client-side image editor

File sorter:

- File sorter in a form
- File sorter with ajax

Others:

- Gallery
- Avatar example
- Custom file name
- PDF viewer
- API methods
- Generated input with PHP

## Options

Available options are listed below. Remember! In all text options you can use Text Variables or functions which are returning text.

### Validations

Note! to set the same validations on the backend.

1. limit of the choosen and preloaded files `{null, Number}`

    // if null - has no limits
    // example: 3
    limit: null

2. maximal size in MB of the choosen and preloaded files together `{null, Number}`

    // if null - has no limits
    // example: 3
    maxSize: null

3. maximal size of each choosen file in MB `{null, Number}`

    // if null - has no limits
    // example: 3
    fileMaxSize: null

4. allowed extensions or file types `{null, Array}`

    // if null - has no limits
    // example: ['jpg', 'jpeg', 'png', 'text/plain', 'audio/*']
    extensions: null

5. disallowed extensions or file types `{null, Array}`

    // if null - has no limits
    // example: ['jpg', 'jpeg', 'png', 'text/plain', 'audio/*']
    disallowedExtensions: null

We can use the `onFilesCheck` callback from the callbacks section to add our own validation function.

### Templates

1. add theme class name to fileuploader `{null, String}`

    // the class name will be: fileuploader-theme-default
    theme: 'default'

2. change the file input `{Boolean, String, Function, jQuery Object}`

    // example: true
    // example: ' ' - no input
    // example: '<div>Click me</div>'
    // example: function(options) { return '<div>Click me</div>'; }
    // example: $('.selector')
    changeInput: true

3. thumbnails for files `{null, Object}`

    thumbnails: {
        // thumbnails list HTML {String, Function}
        // example: '<ul></ul>'
        // example: function(options) { return '<ul></ul>'; }
        box: '<div class="fileuploader-items">' +
                '<ul class="fileuploader-items-list"></ul>' +
            '</div>',

        // append thumbnails list to selector {null, String, jQuery Object}
        // example: 'body'
        boxAppendTo: null,

        // thumbnails for the choosen files {String, Function}
        // example: '<li>${name}</li>'
        // example: function(item) { return '<li>' + item.name + '</li>'; }
        item: '<li class="fileuploader-item">' +
           '<div class="columns">' +
               '<div class="column-thumbnail">${image}<span class="fileuploader-action-popup"></span></div>' +
               '<div class="column-title">' +
                   '<div title="${name}">${name}</div>' +
                   '<span>${size2}</span>' +
               '</div>' +
               '<div class="column-actions">' +
                   '<button class="fileuploader-action fileuploader-action-remove" title="${captions.remove}"><i class="fileuploader-icon-remove"></i></a>' +
               '</div>' +
           '</div>' +
           '<div class="progress-bar2">${progressBar}<span></span></div>' +
        '</li>',

        // thumbnails for the preloaded files {String, Function}
        // example: '<li>${name}</li>'
        // example: function(item) { return '<li>' + item.name + '</li>'; }
        item2: '<li class="fileuploader-item">' +
            '<div class="columns">' +
                '<div class="column-thumbnail">${image}<span class="fileuploader-action-popup"></span></div>' +
                '<div class="column-title">' +
                    '<a href="${file}" target="_blank">' +
                        '<div title="${name}">${name}</div>' +
                        '<span>${size2}</span>' +
                    '</a>' +
                '</div>' +
                '<div class="column-actions">' +
                    '<a href="${file}" class="fileuploader-action fileuploader-action-download" title="${captions.download}" download><i class="fileuploader-icon-download"></i></a>' +
                    '<button class="fileuploader-action fileuploader-action-remove" title="${captions.remove}"><i class="fileuploader-icon-remove"></i></a>' +
                '</div>' +
            '</div>' +
        '</li>',

        // thumbnails selectors
        _selectors: {
            list: '.fileuploader-items-list',
            item: '.fileuploader-item',
            start: '.fileuploader-action-start',
            retry: '.fileuploader-action-retry',
            remove: '.fileuploader-action-remove',
            sorter: '.fileuploader-action-sort',
            popup: '.fileuploader-popup-preview',
            popup_open: '.fileuploader-action-popup'
        },

        // insert the thumbnail's item at the begining of the list? {Boolean}
        itemPrepend: false,

        // show a confirmation dialog by removing a file? {Boolean}
        // it will not be shown in upload mode by canceling an upload
        // you can call your own dialog box using dialogs option
        removeConfirmation: true,

        // render the image thumbnail? {Boolean}
        // if false, it will generate an icon(you can also hide it with css)
        // if false, you can use the API method item.renderThumbnail() to render it (check thumbnails example)
        startImageRenderer: true,

        // render the images synchron {Boolean}
        // used to improve the browser speed
        synchronImages: true,

        // read image using URL createObjectURL method {Boolean}
        // if false, it will use readAsDataURL
        useObjectUrl: false,

        // render the image in a canvas element {Boolean, Object}
        // if true, it will generate an image with the css sizes from the parent element of ${image}
        // you can also set the width and the height in the object {width: 96, height: 96}
        canvasImage: true,

        // render thumbnail for video files? {Boolean}
        videoThumbnail: false,

        // fix exif orientation {Boolean}
        exif: true,

        // Callback fired before adding the list element
        beforeShow: null,

        // Callback fired after adding the item element
        onItemShow: null,

        // Callback fired after removing the item element
        // by default we will animate the removing action
        onItemRemove: function(html) {
            html.children().animate({'opacity': 0}, 200, function() {
                setTimeout(function() {
                    html.slideUp(200, function() {
                        html.remove();
                    });
                }, 100);
            });
        },

        // Callback fired after the item image was loaded or a image file is invalid
        // default - null
        onImageLoaded: function(item, listEl, parentEl, newInputEl, inputEl) {
            // invalid image?
            if (item.image.hasClass('fileuploader-no-thumbnail')) {
                // callback goes here
            }

            // check image size and ratio?
            if (item.reader.node && item.reader.width > 1920 && item.reader.height > 1080 && item.reader.ratio != '16:9') {
                // callback goes here
            }
        },

        // item popup preview {Object}
        popup: {
            // popup append to container {String, jQuery Object}
            container: 'body',

            // enable arrows {Boolean}
            arrows: true,

            // loop the arrows {Boolean}
            loop: true,

            // popup HTML {String, Function}
            template: function(data) { return '<div class="fileuploader-popup-preview">' +
              '<button class="fileuploader-popup-move" data-action="prev"><i class="fileuploader-icon-arrow-left"></i></button>' +
              '<div class="fileuploader-popup-node ${format}">' +
                  '${reader.node}' +
              '</div>' +
              '<div class="fileuploader-popup-content">' +
                  '<div class="fileuploader-popup-footer">' +
                      '<ul class="fileuploader-popup-tools">' +
                          (data.format == 'image' && data.reader.node && data.editor ? (data.editor.cropper ? '<li>' +
                              '<button data-action="crop">' +
                                  '<i class="fileuploader-icon-crop"></i> ${captions.crop}' +
                              '</button>' +
                          '</li>' : '') +
                          (data.editor.rotate ? '<li>' +
                              '<button data-action="rotate-cw">' +
                                  '<i class="fileuploader-icon-rotate"></i> ${captions.rotate}' +
                              '</button>' +
                          '</li>' : '') : ''
                          ) +
                          (data.format == 'image' ?
                          '<li class="fileuploader-popup-zoomer">' +
                              '<button data-action="zoom-out">&minus;</button>' +
                              '<input type="range" min="0" max="100">' +
                              '<button data-action="zoom-in">&plus;</button>' +
                              '<span></span> ' +
                          '</li>' : ''
                          ) +
                          (data.data.url ? '<li>' +
                              '<a href="'+ data.file +'" data-action target="_blank">' +
                                  '<i class="fileuploader-icon-external"></i> ${captions.open}' +
                              '</a>' +
                          '</li>' : ''
                          ) +
                          '<li>' +
                              '<button data-action="remove">' +
                                  '<i class="fileuploader-icon-trash"></i> ${captions.remove}' +
                              '</button>' +
                          '</li>' +
                      '</ul>' +
                  '</div>' +
                  '<div class="fileuploader-popup-header">' +
                      '<ul class="fileuploader-popup-meta">' +
                          '<li>' +
                              '<span>${captions.name}:</span>' +
                              '<h5>${name}</h5>' +
                          '</li>' +
                          '<li>' +
                              '<span>${captions.type}:</span>' +
                              '<h5>${extension.toUpperCase()}</h5>' +
                          '</li>' +
                          '<li>' +
                              '<span>${captions.size}:</span>' +
                              '<h5>${size2}</h5>' +
                          '</li>' +
                          (data.reader && data.reader.width ? '<li>' +
                              '<span>${captions.dimensions}:</span>' +
                              '<h5>${reader.width}x${reader.height}px</h5>' +
                          '</li>' : ''
                          ) +
                          (data.reader && data.reader.duration ? '<li>' +
                              '<span>${captions.duration}:</span>' +
                              '<h5>${reader.duration2}</h5>' +
                          '</li>' : ''
                          ) +
                      '</ul>' +
                      '<div class="fileuploader-popup-info"></div>' +
                      '<ul class="fileuploader-popup-buttons">' +
                          '<li><button class="fileuploader-popup-button" data-action="cancel">${captions.cancel}</a></li>' +
                          (data.editor ? '<li><button class="fileuploader-popup-button button-success" data-action="save">${captions.confirm}</button></li>' : ''
                          ) +
                      '</ul>' +
                  '</div>' +
              '</div>' +
              '<button class="fileuploader-popup-move" data-action="next"><i class="fileuploader-icon-arrow-right"></i></button>' +
          '</div>'; },

            // Callback fired after creating the popup
            // we will trigger by default buttons with custom actions
            onShow: function(item) {
                item.popup.html.on('click', '[data-action="remove"]', function(e) {
                    item.popup.close();
                    item.remove();
                }).on('click', '[data-action="cancel"]', function(e) {
                    item.popup.close();
                }).on('click', '[data-action="save"]', function(e) {
                    if (item.editor)
                        item.editor.save();
                    if (item.popup.close)
                        item.popup.close();
                });
            },

            // Callback fired after closing the popup
            onHide: null
        }
    }

### Drag&Drop

1. enable the Drag&Drop feature `{null, Object}`
This feature is not available in all browser without using the Ajax mode or Drag&Drop with form submit example.

    // by default - true
    dragDrop: {
        // set the drop container {null, String, jQuery Object}
        // example: 'body'
        container: null,

        // Callback fired on entering with dragging files the drop container
        onDragEnter: function(event, listEl, parentEl, newInputEl, inputEl) {
            // callback will go here
        },

        // Callback fired on leaving with dragging files the drop container
        onDragLeave: function(event, listEl, parentEl, newInputEl, inputEl) {
            // callback will go here
        },

        // Callback fired on dropping the files in the drop container
        onDrop: function(event, listEl, parentEl, newInputEl, inputEl) {
            // callback will go here
        }
    }

### Ajax

1. enable the ajax feature to upload files separately to server `{null, Object}`

    // by default - null
    upload: {
        // upload URL {String}
        url: 'upload.php',

        // upload data {null, Object}
        // you can also change this Object in beforeSend callback
        // example: { option_1: '1', option_2: '2' }
        data: null,

        // upload type {String}
        // for more details http://api.jquery.com/jquery.ajax/
        type: 'POST',

        // upload enctype {String}
        // for more details http://api.jquery.com/jquery.ajax/
        enctype: 'multipart/form-data',

        // auto-start file upload {Boolean}
        // if false, you can use the API methods - item.upload.send() to trigger upload for each file
        // if false, you can use the upload button - check custom file name example
        start: true,

        // upload the files synchron {Boolean}
        synchron: true,

        // upload large files in chunks {false, Number}
        // set file chunk size in MB as Number (ex: 4)
        chunk: false,

        // Callback fired before uploading a file
        // by returning false, you can prevent the upload
        beforeSend: function(item, listEl, parentEl, newInputEl, inputEl) {
            // example:
            // here you can extend the upload data
            item.upload.data.new_data_attribute = 'nice';

            // example:
            // here you can create upload headers
            item.upload.headers = {
                "Authorization": "Basic " + btoa(username + ":" + password)
            };

            return true;
        },

        // Callback fired if the upload succeeds
        // we will add by default a success icon and fadeOut the progressbar
        onSuccess: function(data, item, listEl, parentEl, newInputEl, inputEl, textStatus, jqXHR) {
            item.html.find('.fileuploader-action-remove').addClass('fileuploader-action-success');

            setTimeout(function() {
                item.html.find('.progress-bar2').fadeOut(400);
            }, 400);
        },

        // Callback fired if the upload failed
        // we will set by default the progressbar to 0% and if it wasn't cancelled, we will add a retry button
        onError: function(item, listEl, parentEl, newInputEl, inputEl, jqXHR, textStatus, errorThrown) {
            var progressBar = item.html.find('.progress-bar2');

            if(progressBar.length > 0) {
                progressBar.find('span').html(0 + "%");
                progressBar.find('.fileuploader-progressbar .bar').width(0 + "%");
                item.html.find('.progress-bar2').fadeOut(400);
            }

            item.upload.status != 'cancelled' && item.html.find('.fileuploader-action-retry').length == 0 ? item.html.find('.column-actions').prepend(
                '<a class="fileuploader-action fileuploader-action-retry" title="Retry"><i></i></a>'
            ) : null;
        },

        // Callback fired while upload the file
        // we will set by default the progressbar width and percentage
        /* data = {
            loaded: ...,
            loadedInFormat: ...,
            total: ...,
            totalInFormat: ...,
            percentage: ...,
            secondsElapsed: ...,
            secondsElapsedInFormat:...,
            bytesPerSecond: ...,
            bytesPerSecondInFormat: ...,
            remainingBytes: ...,
            remainingBytesInFormat: ...,
            secondsRemaining: ...,
            secondsRemainingInFormat: ...
        } */
        onProgress: function(data, item, listEl, parentEl, newInputEl, inputEl) {
            var progressBar = item.html.find('.progress-bar2');

            if(progressBar.length > 0) {
                progressBar.show();
                progressBar.find('span').html(data.percentage + "%");
                progressBar.find('.fileuploader-progressbar .bar').width(data.percentage + "%");
            }
        },

        // Callback fired after all files were uploaded
        onComplete: function(listEl, parentEl, newInputEl, inputEl, jqXHR, textStatus) {
            // callback will go here
        }
    }

### Image editor

enable the image editor feature `{Boolean, Object}`

    // by default - false
    editor: {
        // editor cropper
        cropper: {
            // cropper ratio
            // example: null
            // example: '1:1'
            // example: '16:9'
            // you can also write your own
            ratio: null,

            // cropper minWidth in pixels
            // size is adjusted with the image natural width
            minWidth: null,

            // cropper minHeight in pixels
            // size is adjusted with the image natural height
            minHeight: null,

            // cropper maxWidth in pixels
            // size is adjusted with the image natural width
            maxWidth: null,

            // cropper maxHeight in pixels
            // size is adjusted with the image natural height
            maxHeight: null,

            // show cropper grid
            showGrid: true
        },

        // editor on save quality (0 - 100)
        // only for client-side resizing
        quality: null,

        // editor on save maxWidth in pixels
        // only for client-side resizing
        maxWidth: null,

        // editor on save maxHeight in pixels
        // only for client-size resizing
        maxHeight: null,

        // Callback fired after saving the image in editor
        onSave: function(blobOrDataUrl, item, listEl, parentEl, newInputEl, inputEl) {
            // callback will go here
        }
    }

### Sorter

enable the sorting feature `{Boolean, Object}`

    // see also thumbnails._selectors.sorter in the options
    // by default - false
    sorter: {
        // selector exclude on drag (ex: 'input, textarea')
        selectorExclude: null,

        // placeholder html
        // null - will clone the item without content
        placeholder: null,

        // scroll container on drag
        scrollContainer: window,

        // callback fired after sorting, adding and removing a file
        onSort: function(list, listEl, parentEl, newInputEl, inputEl) {
            // your callback goes here
        }
    }

### Preload files

preload files to preview and edit them `{null, Array}`

    /* [{
        name: 'filename1.txt', // file name
        size: 1024, // file size in bytes
        type: 'text/plain', // file MIME type
        file: 'uploads/filename1.txt', // file path
        local: '../uploads/filename1.txt', // file path in listInput (optional)
        data: {
            thumbnail: 'uploads/filename1_thumbnail.jpg', // item custom thumbnail (optional)
            readerCrossOrigin: 'anonymous', // fix image cross-origin issue (optional)
            readerForce: true, // prevent the browser cache of the image (optional)
            readerSkip: true, // skip file from reading by rendering a thumbnail (optional)
            popup: false, // remove the popup for this file (optional)
            listProps: {}, // custom key: value attributes in the fileuploader's list (optional)

            your_own_attribute: 'your own value'
        }
    }] */
    files: null

### Callbacks

    // Callback fired when fileuploader is not supported in your browser
    onSupportError: function(parentEl, inputEl) {
        // callback will go here
    },

    // Callback fired before rendering the fileuploader elements
    // by returning false, you will prevent the rendering
    beforeRender: function(parentEl, inputEl) {
        // callback will go here

        return true;
    },

    // Callback fired after rendering the fileuploader elements
    afterRender: function(listEl, parentEl, newInputEl, inputEl) {
        // callback will go here
    },

    // Callback fired after selecting the files from computer but only before processing them
    // by returning false, you will prevent the processing of the files but they will remain in the input
    beforeSelect: function(files, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here

        return true;
    },

    // Callback fired on checking for warnings the choosed files
    // by returning false, you will prevent the files from adding/upload
    onFilesCheck: function(files, options, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here

        return true;
    },

    // Callback fired on rendering a file
    onFileRead: function(item, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here
    },

    // Callback fired on selecting and processing a file
    onSelect: function(item, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here
    },

    // Callback fired after selecting and processing of all files
    afterSelect: function(listEl, parentEl, newInputEl, inputEl) {
        // callback will go here
    },

    // Callback fired after generating a list input. Needs to return an array!
    onListInput: function(list, fileList, listInputEl, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here

        return list;
    },

    // Callback fired after deleting a file
    // by returning false, you can prevent a file from removing
    onRemove: function(item, listEl, parentEl, newInputEl, inputEl) {
        // callback will go here

        return true;
    },

    // Callback fired when fileuploader has no files
    onEmpty: function(listEl, parentEl, newInputEl, inputEl) {
        // callback will go here
    }

### Languages

Use captions option to translate the text `{String, Object}`

Available languages are: `cz`, `de`, `dk`, `en`, `es`, `fr`, `it`, `lv`, `nl`, `pl`, `pt`, `ro`, `ru`, `tr`.

    captions: 'en'

Define your own texts. This is also the default option.

    captions: {
        button: function(options) {
            return 'Browse ' + (options.limit == 1 ? 'file' : 'files');
        },
        feedback: function(options) {
            return 'Choose ' + (options.limit == 1 ? 'file' : 'files') + ' to upload';
        },
        feedback2: function(options) {
            return options.length + ' ' + (options.length > 1 ? 'files were' : 'file was') + ' chosen';
        },
        confirm: 'Confirm',
        cancel: 'Cancel',
        name: 'Name',
        type: 'Type',
        size: 'Size',
        dimensions: 'Dimensions',
        duration: 'Duration',
        crop: 'Crop',
        rotate: 'Rotate',
        sort: 'Sort',
        download: 'Download',
        remove: 'Delete',
        drop: 'Drop the files here to Upload',
        paste: '<div class="fileuploader-pending-loader"></div> Pasting a file, click here to cancel.',
        removeConfirmation: 'Are you sure you want to remove this file?',
        errors: {
            filesLimit: function(options) {
                return 'Only ${limit} ' + (options.limit == 1 ? 'file' : 'files') + ' can be uploaded.'
            },
            filesType: 'Only ${extensions} files are allowed to be uploaded.',
            fileSize: '${name} is too large! Please choose a file up to ${fileMaxSize}MB.',
            filesSizeAll: 'The chosen files are too large! Please select files up to ${maxSize} MB.',
            fileName: 'A file with the same name ${name} is already selected.',
            remoteFile: 'Remote files are not allowed.',
            folderUpload: 'Folders are not allowed.'
        }
    }

### Others

enable addMore mode to add files from different folders `{Boolean}`

    addMore: false

add brackets at the end of the input name by multiple files `{Boolean}`

    // specially for PHP, set false for ASP.NET, C#, Node.js and others
    inputNameBrackets: true

allow duplicated names of files `{Object}`

    // this option is fixing iPhone `picture.jpg` issue
    // this feature is available only in upload mode
    // set on true only if are changing the file name after uploading
    skipFileNameCheck: false

upload image from clipboard `{null, Number in ms}`

    // the input should be completely into view by pasting
    // this feature is available only in upload mode
    clipboardPaste: 2000

input with the listed files `{Boolean, String}`

    // this list is an input[type="hidden"]
    // this list will be generated from each choosed/preloaded file name in a JSON format. You can use the onListInput callback to manipulate this list
    // use item.data.listProps = {my_own_property: 'my own value'} to add your own attributes to the list
    // files in this list that are obejcts like '{file: "0://file_name.ext"}' are showing to PHP that they are choosed and should be uploaded
    // if you've preloaded some files on the server-side, PHP will check if each preloaded file is in this list, if not, PHP will set them as removed.
    // example: true
    // example: 'custom_listInput_name'
    listInput: true

enable Api methods `{Boolean}`

    // after enable, use the code below to get Api methods
    // var api = $.fileuploader.getInstance(input_element);
    enableApi: false

file reader timeout `{Object}`

    reader: {
        // file reader timeout for the thumbnails {Number}
        thumbnailTimeout: 5000,

        // file reader timeout for the popup preview {Number}
        timeout: 12000,

        // file reader maxSize in Mb {Number}
        maxSize: 20
    },

dialogs `{Object}`

    // made to let you customizing the standard Javascript dialogs
    // this dialogs are used by showing a file warning or confirming a file remove
    dialogs: {

        // alert dialog
        alert: function(text) {
            return alert(text);
        },

        // confirm dialog
        confirm: function(text, callback) {
            confirm(text) ? callback() : null;
        }
    }

## Input attributes

You can configurate the Fileuploader not only in Javascript but also setting some input attributes in HTML.
Example: `<input type="file" name="files" data-fileuploader-limit="2">`

    <!-- limit option {Number} -->
    data-fileuploader-limit="2"

    <!-- maxSize option {Number} -->
    data-fileuploader-maxSize="3"

    <!-- fileMaxSize option {Number} -->
    data-fileuploader-fileMaxSize="1"

    <!-- extensions option {Comma spliced String} -->
    data-fileuploader-extensions="jpg, png, gif"

    <!-- theme option {String} -->
    data-fileuploader-theme="default"

    <!-- listInput option {String} -->
    data-fileuploader-listInput="myCustomName"

    <!-- files option {JSON String} -->
    data-fileuploader-files='"[{"name":"filename1.txt","size":1024,"type":"text/plain","file":"uploads/filename1.txt"}]"'

## Text variables

The inline text variables are available in each text option. Writin ${variable_name} to transform it.
Example: `'Only ${limit} files are allowed to be uploaded.'`

    <!-- limit option -->
    <!-- always available -->
    ${limit}

    <!-- maxSize option -->
    <!-- always available -->
    ${maxSize}

    <!-- fileMaxSize option -->
    <!-- always available -->
    ${fileMaxSize}

    <!-- extensions option -->
    <!-- always available -->
    ${extensions}

    <!-- number of choosed/preloaded files -->
    <!-- only for captions.feedback and captions.feedback2 -->
    ${length}

    <!-- file name -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${name}

    <!-- file title (file name without extension) -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${title}

    <!-- file extension -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${extension}

    <!-- file size -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${size}

    <!-- file size (formatted in bytes, kbs, mbs...) -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${size2}

    <!-- file type (audio/mp3) -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${type}

    <!-- file format (audio) -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${format}

    <!-- file data -->
    <!-- only in thumbnails.item, thumbnails.item2, captions.removeConfirmation, captions.errors.fileSize and captions.errors.fileName -->
    ${data.my_custom_data_key}

    <!-- file icon HTML element -->
    <!-- remember that a file-like icon is also available, just remove the comments in css file from the line /* item icon like file */ -->
    <!-- file icon HTML element -->
    <!-- only in thumbnails.item and thumbnails.item2 -->
    ${icon}

    <!-- file thumbnail / file icon (for not image files) holder HTML element -->
    <!-- only in thumbnails.item and thumbnails.item2 -->
    ${image}

## Api

Available methods are listed below.
Don't forget that you will need to set `enableApi: true` to activate the Api methods.

    var api = $.fileuploader.getInstance(file_input_element);

    // open browser file explorer to choosed files
    api.open();

    // get Fileuploader options
    api.getOptions();

    // get Fileuploader parent element
    api.getParentEl();

    // get Fileuploader input element
    api.getInputEl();

    // get Fileuploader new/generated input element
    api.getNewInputEl();

    // get Fileuploader thumbnails list element
    api.getListEl();

    // get Fileuploader listInput element
    api.getListInputEl();

    // get Fileuploader file items
    api.getFiles();

    // get Fileuploader choosed file items
    api.getChoosedFiles();

    // get Fileuploader preloaded file items
    api.getAppendedFiles();

    // get Fileuploader uploaded file items
    api.getUploadedFiles();

    // get Fileuploader list of files using custom key
    // @param toJSON {Boolean} - Parse the Array to JSON?
    // @param customItemKey {String} - Generate a list with only a file attribute (ex: name, url)?
    api.getFileList(toJSON, customItemKey);

    // update the Fileuploader list of files
    api.updateFileList();

    // set Fileuploader option
    api.setOption(key, value);

    // get an Fileuploader item data by giving an item HTML element
    api.findFile(itemHtmlElement);

    // create a file from data or dataURI and add to the plugin (only in upload mode)
    // @param data {String} - text or dataURI string
    // @param type {String} - file type (ex: image/png)
    // @param custom_name {null, String} - custom file name (ex: picture.png)
    api.add(data, type, custom_name);

    // append file (Object) or files(Array with Objects)
    api.append(file);

    // update file by giving the item Object and new data Object
    api.update(item, data);

    // remove an item by giving an item Object or item HTML element
    api.remove(item);

    // reset the Fileuploader input
    api.reset();

    // start the upload of the files
    api.uploadStart();

    // disable Fileuploader input
    api.disable(also_lock_item_remove_startUpload_retry_action);

    // enable Fileuploader input
    api.enable();

    // return true if there are no files
    api.isEmpty();

    // return true if the input is disabled
    api.isDisabled();

    // return true if the input is rendered
    api.isRendered();

    // return the plugin mode ('default', 'addMore', 'upload')
    api.getPluginMode();

    // generate a text with variables
    api.assets.textParse(myText, myObjectWithVariables);

    // destroy Fileuploader
    api.destroy();

### Item methods

    // remove item
    item.remove();

    // render thumbnail
    item.renderThumbnail(custom_src_or_update?);

    // item upload - !only if upload is enabled
    /* start upload */
    item.upload.send();

    /* cancel upload */
    item.upload.cancel();

    /* retry upload if failed */
    item.upload.retry();

    /* resend upload */
    item.upload.resend();

    // popup - !only if popup is enabled
    /* open popup */
    item.popup.open();

    /* close popup - !only if popup is openend */
    item.popup.close();

    // item file reader
    /* read file in browser
       @param callback {null, Function}
       @param type {null, String} - read type ['astext', 'image', 'audio', 'video']
       @param force {Boolean} - ignore reader cache */
    item.reader.read(callback, type, force);

    // item image editor - !only if editor is enabled
    /* rotate image */
    item.editor.rotate();

    /* show cropping tools in the popup */
    item.editor.cropper();

    /* save edited image
       @param callback {null, Function}
       @param toBlob {Boolean} - save canvas as Blob or just as dataURL?
       @param mimeType {null, String} - save image format 'image/jpeg' or 'image/png'
       @param preventThumbnailRender {Boolean} - do not render thumbnail in HTML after save? */
    item.editor.save(callback, asBlob, mimeType, preventThumbnailRender);

## PHP

Fileuploader includes also a PHP class that uploads, validates, removes, sorts, edits the images, creates thumbnails and uploads large files in chunks to server. All this stuff can be also done on the client-side but the server keeps everything safer.

Our php file upload helper uses the following php-standard extensions:

- GD
- Exif
- Fileinfo

### Installation

1. Copy class.fileuploader.php from src folder to your server.
2. Configurate in the php.ini file the following options according your needs: `file_uploads`, `upload_max_filesize`, `max_file_uploads`, `post_max_size` and `memory_limit`

### How to use

Include the class.fileuploader.php into your php file and initialize it by writing in arguments the file input's name (e.g. `'files'`) and the options in an `array`.

    <?php
        include('class.fileuploader.php');

        // initialize the FileUploader
        $FileUploader = new FileUploader('files', array(
            // Options will go here
        ));

        // call to upload the files
        $upload = $FileUploader->upload();

        if($upload['isSuccess']) {
            // get the uploaded files
            $files = $upload['files'];
        } else {
            // get the warnings
            $warnings = $upload['warnings'];
        }
    ?>

### Options

All available options are listed below.

    array (
        // limit of files {null, Number}
        // also with the preloaded files
        // if null - has no limits
        // example: 3
        'limit' => null,

        // file's maximal size in MB {null, Number}
        // also with the preloaded files
        // if null - has no limits
        // example: 2
        'maxSize' => null,

        // each file's maximal size in MB {null, Number}
        // if null - has no limits
        // example: 2
        'fileMaxSize' => null,

        // allowed extensions or file types {null, Array}
        // if null - has no limits
        // example: ['jpg', 'jpeg', 'png', 'text/plain', 'audio/*']
        'extensions' => null,

    	// disallowed extensions or file types {null, Array}
        // if null - has no limits
        // example: ['php', 'application/*', 'text/plain']
        'disallowedExtensions' => ['htaccess', 'php', 'php3', 'php4', 'php5', 'phtml'],

        // check if file input exists ($_FILES[ file_input_name ]) {Boolean}
        // check if files were choosed (minimum 1 file should be choosed)
        'required' => false,

        // upload directory {String}
        // note that main directory is the directory where you are initializing the FileUploader class
        // example: '../uploads/'
        'uploadDir' => 'uploads/',

        // file title {String, Array, Function}
        // example: 'name' - original file name
        // example: 'auto' - random text from 12 letters
        // example: 'my_custom_filename' - custom file name
        // example: 'my_custom_filename_{random}' - my_custom_filename_(+ random text from 12 letters)
        // '{random} {file_name} {file_size} {timestamp} {date} {format} {extension} {index}' - variables that can be used to generate a new file name
        // example: array('auto', 12, true) - [0] is a string as in the examples above [1] is the length of the random string [2] force extension change if in [0] founded
    	// example: function($item) { return array('file_{random}', 12); }
        'title' => ['auto', 12],

        // replace the file with the same name? {Boolean}
        // if it will be false - will automatically generate a new file name with (1,2,3...) at the end of the file name
        'replace' => false,

        // image editor {null, Boolean, Array}
        // default: null
    	// set null, true or Array and the Exif issue will be fixed
        // set false to disable
        'editor' => array(
            // image maxWidth in pixels {null, Number}
            'maxWidth' => null,
            // image maxHeight in pixels {null, Number}
            'maxHeight' => null,
            // crop image {Boolean}
            'crop' => false,
            // image quality after save {Number}
            'quality' => 90
        ),

        // input with the listed files {Boolean, String}
        // this list is an input[type="hidden"]
        // this list is important to store your files with the attributes and to check which file shouldn't be uploaded or need to be removed
        // example: true
        // example: 'custom_listInput_name'
        'listInput' => true,

        // preloaded files {null, Array with arrays}
        // it is important to declare them if you want to check the right limit and maxSize options; by preloaded files; by generating an input
        // please follow this structure for each file:
        /* array(
            "name" => 'filename1.txt',
            "type" => FileUploader::mime_content_type('../uploads/filename1.txt'),
            "size" => filesize('../uploads/filename1.txt'),
            "file" => '../uploads/filename1.txt', // should the same as on the front-end
            "relative_file" => '../uploads/filename1.txt', // use this file by editing
            "data" => array(
                "url" => 'http://localhost/example/uploads/filename1.txt',
                "my_own_attribute" => "my own value",
                "listProps" => array(
                    "file_id" => 240 // property to be stored in the listInput
                )
            )
        ) */
        'files' => null,

        // move_uploaded_file {function}
        // prevent default php upload method and use yours
        // @param $temp_name {String} PHP file temp_name
        // @param $destination {String} file upload destination
        // @return {Boolean}
        'move_uploaded_file' => function($temp_name, $destination, $item) {
            return move_uploaded_file($temp_name, $destination);
        },

        // validate_file {function}
        // custom file validation function
        // @param $file {Array} Fileuploader file array
        // @param $options {Array} Fileuploader options
        // @return {Boolean or String}
        'validate_file' => function($file, $options) {
            $isValid = true;

            if ($isValid) {
                return true;
            } else {
                return "Wrong file!";
            }
        }
    )

### Methods

All available methods are listed below.

    // get removed list
    // give a String parameter (ex: 'file' or 'name' or 'data.url') to get a file by a custom input attribute. Default is 'file'
    // note that FileUploader will not remove your appended files that were removed on Front-End
    // call this method before $FileUploader->upload();
    // to remove them, please use this example:
    // foreach($FileUploader->getRemovedFiles('file') as $key=>$value) {
    //     unlink('../uploads/' . $value['name']);
    // }
    $FileUploader->getRemovedFiles();

    // call to upload the files
    $upload = $FileUploader->upload();

    // get listInput value
    $FileUploader->getListInput();

    // get the list of the files
    // without parameter it will return an array with appended and uploaded files
    // give a String parameter (ex: 'file' or 'name' or 'data.url') to generate a custom input list of the files
    // example: you can store the files in the MySQL using this function
    // $myFilesForSql = implode('|', $FileUploader->getFileList('name'));
    // $myFilesForSql = json_encode($FileUploader->getFileList('name'));
    $FileUploader->getFileList();

    // get the list of the preloaded files
    $FileUploader->getPreloadedFiles();

    // get the list of the uploaded files
    $FileUploader->getUploadedFiles();

    // resize image
    // example replace image: FileUploader::resize($source, $width = 100);
    // example create thumbnail: FileUploader::resize($source, $width = 100, $height = 100, $destination = 'my_custom_thumbnail_name.jpg', $crop = false, $quality = 90, $rotation = 0);
    FileUploader::resize($source, $width = 100, $height = null, $destination = null);

    // remove old chunked files
    FileUploader::clean_chunked_files($directory = '../uploads/', $time = '-1 hour');

    // get file mime content type
    FileUploader::mime_content_type($file, $nativeFunction = false);

    // get the HTML generated input
    $FileUploader->generateInput();

## Laravel

Laravel basic Contoller to upload files over the form or ajax. Upload files on your Laravel website using our helper.

### Installation

Fileuploader installation instructions:

1. Create a new folder Library in your project's app/ folder
2. Copy class.fileuploader.php from src/php/ into app/Library/
3. Add Fileuploader to the composer

       "autoload": {
       	...

       	"files": [
       		"app/Library/class.fileuploader.php"
       	]
       },

4. Run `composer install`
5. Run `php artisan storage:link` to add the storage folder in public folder

### How to use

The Controller, Blade Template and js files are in examples/thirdparty/laravel/ folder. Please copy themselves or their content to your project. The following instructions are just an example and you might skip some steps:

1.Create the ExampleController.php in app/Http/Controllers/

    <?php
    namespace App\Http\Controllers;

    use Illuminate\Http\Request;
    use \FileUploader;

    class ExampleController extends Controller {

    	/**
    	 * show the form
    	 *
    	 * @return \Illuminate\Contracts\Support\Renderable
    	 */
    	public function index() {
    		return view('home');
    	}

    	/**
    	 * submit the form
    	 *
    	 * @return void
    	 */
    	public function submit(Request $request) {
    		// initialize FileUploader
    		$FileUploader = new FileUploader('files', array(
    			// options
    			'limit' => 4,
    			'uploadDir' => storage_path('app/public/'),
    			'title' => 'auto'
    		));

    		// upload
    		$upload = $FileUploader->upload();
    	}

    	/**
    	 * delete a file
    	 *
    	 * @return void
    	 */
    	public function removeFile(Request $request) {
    		@unlink($_POST['file']);
    		exit;
    	}
    }

2. Create the home.blade.php in app/resources/views/

    <form action="{{ route('example.upload') }}" method="post" enctype="multipart/form-data">
    	{{ csrf_field() }}

    	<input type="file" name="files">
    	<input type="submit">
    </form>

3. Add the route in routes/web.php

    Route::get('/home', 'ExampleController@index');
    Route::post('/upload', 'ExampleController@submit')->name('example.upload');
    Route::post('/ajax_remove_file', 'ExampleController@removeFile');

## Node.js

Fileuploader includes also a Node.js module that uploads, validates, removes, sorts, edits the images, creates thumbnails and uploads large files in chunks to server. All this stuff can be also done on the client-side but the server keeps everything safer.

Our module uses some dependencies to provide the features of multipart/form-data upload, reading file's mime type and image editing.

- multer
- mime-types
- gm

### Installation

1. Copy fileuploader.js and it's package.json from src folder to your server.
2. Run `npm install` in node folder to install all dependencies.
3. (Optional) While using server-side image editing feature (editor option), you will have to download and install GraphicsMagick or in Mac OS X the Homebrew.

### How to use

Require the fileuploader.js into your app file and initialize it by writing in arguments the input file name, the options, request and response object. We will also use the popular Node.js framework Express. Don't forget to take a look at the /examples/nodejs/ folder.

    const express = require('express')
    const fileuploader = require('fileuploader')

    app.post('/upload', function(req, res) {

        // initialize fileuploader
        var uploader = fileuploader('files', {
            // options will go here
        }, req, res)

        // call to process the form (req.body) and to upload the files
        uploader.upload(function(data) {

            if (data.isSuccess) {
                var files = data.files;
            } else {
                var warnings = data.warnings;
            }

            res.end()
        })

    })

    // init server
    app.listen(8000)

### Options

All available options are listed below.

    [
        // limit of files {null, Number}
        // also with the preloaded files
        // important to set 1 if file input has no multiple attribute
        // if null - has no limits
        // example: 3
        limit: null,

        // file's maximal size in MB {null, Number}
        // also with the preloaded files
        // if null - has no limits
        // example: 2
        maxSize: null,

        // each file's maximal size in MB {null, Number}
        // if null - has no limits
        // example: 2
        fileMaxSize: null,

        // allowed extensions or file types {null, Array}
        // if null - has no limits
        // example: ['jpg', 'jpeg', 'png', 'text/plain', 'audio/*']
        extensions: null,

        // disallowed extensions or file types {null, Array}
        // if null - has no limits
        // example: ['jpg', 'jpeg', 'png', 'text/plain', 'audio/*']
        disallowedExtensions: null,

        // check if files were choosed (minimum 1 file should be choosed)
        required: false,

        // upload directory {String}
        // note that main directory is the directory where you are initializing the fileuploader module
        // example: '../uploads/'
        uploadDir: 'uploads/',

        // file title {String, Array}
        // example: 'name' - original file name
        // example: 'auto' - random text from 12 letters
        // example: 'my_custom_filename' - custom file name
        // example: 'my_custom_filename_{random}' - my_custom_filename_(+ random text from 12 letters)
        // '{random} {file_name} {file_size} {timestamp} {date} {extension}' - variables that can be used to generate a new file name
        // example: ['auto', 24] - [0] is a string as in the examples above, [1] is the length of the random string
        title: ['auto', 12],

        // replace the file with the same name? {Boolean}
        // if it will be false - will automatically generate a new file name with (1,2,3...) at the end of the file name
        replace: false,

        // image editor {null, Array}
        editor: {
            // image maxWidth in pixels {null, Number}
            maxWidth: null,
            // image maxHeight in pixels {null, Number}
            maxHeight: null,
            // crop image {Boolean}
            crop: false,
            // image quality after save {Number}
            quality: 90
        },

        // input with the listed files {Boolean, String}
        // this list is an input[type="hidden"]
        // this list is important to store your files with the attributes and to check which file shouldn't be uploaded or need to be removed
        // example: true
        // example: 'custom_listInput_name'
        listInput: true,

        // preloaded files {null, Array with Objects}
        // it is important to declare them if you want to check the right limit and maxSize options; by preloaded files; by generating an input
        // please follow this structure for each file:
        /* [{
            name: 'filename1.txt',
            type: null,
            size: fs.statSync('filename1.txt').size,
            file: 'uploads/filename1.txt', // should the same as on the front-end
            relative_file: 'uploads/filename1.txt', // (optional) use this file by editing
            data: {
                url: 'http://localhost/example/uploads/filename1.txt', // (optional)
                listProps: {
                    file_id: 240 // property to be stored in the listInput
                }, // (optional)
                my_own_attribute: 'my own value'
            }
        }] */
        'files': null,

        // move_uploaded_file {function}
        // prevent default upload method and use yours
        // fileuploader will delete at the end the file.tmp file
        // @return {Boolean}
        move_uploaded_file: function(file) {
            fs.renameSync(file.tmp, file.file);

            return true;
        },

        // validate_file {function}
        // custom file validation function
        // @param file {Object} Fileuploader file object
        // @param options {Object} Fileuploader options
        // @return {Boolean or String}
        validate_file: function(file, options) {
            var isValid = true;

            return isValid ? true : 'Wrong file!';
        }
    ]

### Methods

All available methods are listed below.

    // get removed list
    // give a String parameter (ex: 'file' or 'name' or 'data.url') to get a file by a custom input attribute. Default is 'file'
    // note that FileUploader will not remove your preloaded files that were removed on front-end
    // to remove them, please use this example:
    // uploader.getRemovedFiles().forEach(function(item, index) {
    //     fs.unlink(item.relative_path || item.file, function(err) {});
    // })
    uploader.getRemovedFiles();

    // call to process the form and to upload the files
    uploader.upload();

    // get listInput value
    uploader.getListInput();

    // get the list of the files
    // without parameter it will return an array with appended and uploaded files
    // give a String parameter (ex: 'file' or 'name' or 'data.url') to generate a custom input list of the files
    // example: you can store the files in the DB using this function
    // var myFilesInlineList = uploader.getFileList('name').join('|');
    // var myFilesJSONList = JSON.stringify(uploader.getFileList('name'));
    uploader.getFileList();

    // get the list of the preloaded files
    uploader.getPreloadedFiles();

    // get the list of the uploaded files
    uploader.getUploadedFiles();

    // resize an image
    // thumbnail example item = data.files[0]: uploader.resize(item.file, 100, 100, '../uploads/thumbs/' + item.name, true)
    // full example: uploader.resize(filename = 'uploads/file.jpg', width = 400, height = 400, destination = 'uploads/file.jpg', crop = true, quality = 90, rotation = 180, callback = function() {})
    uploader.resize('uploads/file.jpg', 800);

    // remove the old unused chunked files
    uploader.cleanChunkedFiles('uploads/', 3600000 /* -1 hour in milliseconds */);

    // get the HTML generated input
    uploader.generateInput();

## Amazon S3

PHP Amazon S3 file upload class is included. Upload Directly to Amazon S3 and manage objects in your buckets using our helper.

### Configuration

Basic Amazon S3 Bucket configuration instructions.

1. Create an IAM user
   1. Access Services menu > IAM > Users > Add user
   2. Give an user name and select Programmatic access as Access type
   3. Permissions > Attach existing policies directly > select AmazonS3FullAccess
   4. Copy the User ARN
2. Create an access key
   1. Open the IAM user > Security credentials > Create access key
   2. Copy Key ID and Secret
3. Create a bucket
4. Configurate the new bucket
   1. Permissions > Bucket policy (replace << >> with your values)

          {
              "Version": "2012-10-17",
              "Id": "Policy1488494182833",
              "Statement": [
                  {
                      "Sid": "MakeItPublic",
                      "Effect": "Allow",
                      "Principal": {
                          "AWS": "<< Copied User ARN >>"
                      },
                      "Action": "s3:*",
                      "Resource": [
                          "arn:aws:s3:::<< Bucket name >>",
                          "arn:aws:s3:::<< Bucket name >>/*"
                      ]
                  }
              ]
          }

   2. CORS configuration

          <?xml version="1.0" encoding="UTF-8"?>
          <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
              <CORSRule>
                  <AllowedOrigin>*</AllowedOrigin>
                  <AllowedMethod>GET</AllowedMethod>
                  <AllowedMethod>POST</AllowedMethod>
                  <AllowedMethod>PUT</AllowedMethod>
                  <MaxAgeSeconds>3000</MaxAgeSeconds>
                  <AllowedHeader>Authorization</AllowedHeader>
              </CORSRule>
          </CORSConfiguration>

### PHP

### Installation

1. Copy fileuploader.s3.php from src/thirdparty/s3/php/ folder to your server.
2. Install official AWS SDK (?)
   1. using `composer require aws/aws-sdk-php`
   2. or download ZIP file

### How to use

Include the class.fileuploader.php, fileuploader.s3.php and aws autoloader into your php file and initialize it like basic Fileuploader by writing in arguments the input file name and the options.
This time you will have to create a `Fileuploader::$S3` object and to add the `auth` array in the options.
Don't forget to take a look at the /examples/thirdparty/s3/ folder.

    require 'vendor/autoload.php';
    require 'class.fileuploader.php';
    require 'fileuploader.s3.php';

    $FileUploader = new FileUploader::$S3('files', array(
        'uploadDir' => '../uploads/',

        // S3 credentials
        'auth' => [
            'bucket' => 'my-bucket',
            'folder' => '/',
            'key' => 'ima_key',
            'secret' => 'ima_secret',
            'region' => 'eu-central-1',
            // 'version' => 'latest', # optional
            // 'endpoint' => 'http://localhost:8000', #optional
        ]
    ));

    // call to upload the files
    $data = $FileUploader->upload();

    // if uploaded and success
    if($data['isSuccess']) {
        echo '<pre>';
        print_r($FileUploader->getFileList());
        echo '</pre>';
    }

#### Or call it separately

    require 'vendor/autoload.php';
    require 'class.fileuploader.php';
    require 'fileuploader.s3.php';

    $S3Client = new FileUploader_S3(array(
        'bucket' => 'my-bucket',
        'folder' => '/',
        'key' => 'ima_key',
        'secret' => 'ima_secret',
        'region' => 'eu-central-1'
    ));

### Methods

All available methods are listed below.

    // get S3 Client
    $FileUploader->getClient();

    // create a bucket
    $FileUploader->createBucket($bucket = 'bucket-name', $location = 'us-east-1', $acl = 'private');

    // set current bucket
    $FileUploader->setBucket($bucket = 'bucket-name');

    // check if bucket exists
    $FileUploader->bucketExists($bucket = 'bucket-name');

    // list the buckets' names
    $FileUploader->listBuckets();

    // create a folder
    $FileUploader->createFolder($path = 'new_folder/', $acl = 'public-read');

    // set current folder
    $FileUploader->setFolder($path = 'my_folder/');

    // check if folder exists
    $FileUploader->folderExists($path = 'my_folder/');

    // list the folders
    $FileUploader->listFolders($path = null);

    // delete a folder
    $FileUploader->deleteFolder($path = 'my_folder/');

    // upload a file
    $FileUploader->uploadFile($tmp = 'path_to_file.jpg', $file = 'file_on_s3.jpg', $acl = 'public-read');

    // check if a file exists
    $FileUploader->fileExists($file = 'file_on_s3.jpg');

    // get file public link
    $FileUploader->getFileUrl($file = 'file_on_s3.jpg');

    // list the files
    $FileUploader->listFiles($path = null);

    // download a file to path
    $FileUploader->downloadFile($file = 'file_on_s3.jpg', $destination = 'path_to_file.jpg');

    // delete a file
    $FileUploader->deleteFile($file = 'file_on_s3.jpg');

## License

A regular license is required if you are using this plugin in one of your personal projects (including sites for your customers) and a commercial license for all commercial applications (including sites, themes and apps you plan to sell).

Sharing the source code or selling it particullary is not allowed.

Keep the license and copyright notice included in Fileuploader's CSS and JavaScript files when you use them in your projects.

## Changelog

See the record of all changes made to the project.

### v2.2

- Fixed the cropper for iOS devices
- Fixed image orientaion flip issue
- New popup template
- Popup image zoomer
- Improved popup for mobile devices
- New box-after theme
- New gallery theme
- New avatar theme
- Added `thumbnails.popup.zoomer` option
- Added `editor.cropper.maxWidth` and `editor.cropper.maxHeight` option
- Added `item.data.readerForce` attribute for the preloaded files to prevent the browser cache
- Added `reader.maxSize` option to customize the performance of the browser
- Added `item.local` attribute that will be come as `file` in listInput
- Changed `thumbnails.popup.onShow` callback
- Added `disallowedExtensions` option
- Added dialogs option in the api.assets object
- Set allowed/disallowed type using * like `image/*`
- Fixed sorter function for `itemPrepend` option
- Improved sorter's scrollContainer element
- Fixed scrolling on sort for iOS devices
- Fixed the checking of sorter changes
- Continue the upload on chunks by retry
- The example drag-drop-form is now for unlimited inputs
- Added a MySQL example
- Added Laravel example
- PDF Viewer in the popup: native or `mozilla/pdf.js`
- Now you can set the title option as a function
- Improved file size calculation for validations
- Check the file structure by preloading
- Prevent empty file (file size = 0)
- Escape HTML entities from the file name
- Replaced <a> with <button> in the templates
- `FileUploader::resize` function returns a information about the image size
- Now you can set the input name `new FileUploader(array('my_form', 'files'))` for name="my_form[files]"

### v2.1

- Added node.js module
- Added Amazon S3 class
- Added size and position information by cropping an image
- Fixed `item.upload.data` object
- Fixed crop option for images smaller than maxWidth and maxHeight
- Fixed limit 1 issue on the front-end
- Improved synced image loading for large files
- Added rotate action (without opening the editor)
- Rounded button styles

### v2.0

- Redesign!
- Added dropIn theme
- Added jquery.fileuploader.sass
- Improved documentation
- Fix addMore mode with limit to one file
- Improved editor in the PHP
- listProps are now available in the items array in PHP
- fileuploader font with icons
- dist and src folder in the download zip

### v1.4

- Fixed Exif orientation issue for images (e.g. on iPhone and Samsung)
- `thumbnails.videoThumbnail` option will allow you to choose if you want or not to load thumbnails for video files in browser
- Added `file.data.thumbnail` - now you can load 2 different images for thumbnail and popup (now fileuploader is loading faster)
- Added `api.update(item, data)` method - now you can update an item in the list with the new data
- Some design changes for the popup - now you can also append the popup to the body
- View all type of file in the popup (remove the `file-has-popup` class for an item to disable the preview)
- Added arrows features for the popup
- File reader improvements - now you can also set the reader timeout for a file
- `item.renderThumbnail(true)` will now read again the item.file and will update the thumbnail and the popup
- Drag&Drop feature in a form example

### v1.3

- Image editor feature on front-End. Now you can open a popup and edit the images (click on the thumbnail).
  - added `editor` option
  - `item.editor.rotate(degrees)` method is available
  - `item.editor.rotation` value is available, only after calling the method above
  - `item.editor.cropper(data)` method is available
  - `item.editor.crop` value is available, only after calling the method above
  - `item.editor.save(callback, asBlob, mimeType, preventThumbnailRender)` method is available
- Image editor feature on back-End (we use it to edit the images and to create thumbnails)
  - added `editor` option
  - `FileUploader::resize` method is now available
- File sorter feature. Now you can sort by drag&drop the files
  - add `sorter` option
- List input has now Array-Object format. Now you can send to Back-end your own file parameters (we are using now also for the editor). Add custom values in `item.data.listProps` to have them in the list input
- `item.upload.resend()` method is now available to resend an ajax request
- Improved the image resizer. Images that are resized for canvas in browser have a high quality now
- Added `upload.chunk` option. Slice large files in chunks and upload them to server
- Added `api.add(data, type, custom_name)` api method. Create a file from your string or dataURI and upload to server. Now you can upload WebCam photos or other file types converted into dataURI in browser
- Popup redesign
- Popup text files preview - set file format to `astext` to get it
- `item.reader.ratio` - image and video ratio
- `assets.pxToRatio(width, height)` helper function
- `assets.ratioToPx(width, height, ratio)` helper function
- `item.renderImage` - is now deprecated! Please use `item.renderThumbnail` instead
- `item.data.readerSkip = true` to skip file from rendering
- `item.data.readerCrossOrigin = 'anonymous'` to solve the cross-origin issue
- `captions.close` - is now deprecated! Please use `captions.cancel` instead
- `thumbnails.onImageLoaded` - the callback is triggered now also when the reading of an image failed. Now you can also validate the images
- CSS - brighter main color
- Added jquery.fileuploader.min.css file
- Fixed validaiton check on the php side
- Improvements and fixes

### v1.2

- Added Popup feature. Now you can open a popup for each item (click on the thumbnail).
  - Popup preview for photo, video and audio files
  - `thumbnails.item` and `thumbnails.item2` the line was changed to `<div class="column-thumbnail">${image}<span class="fileuploader-action-popup"></span></div>`
  - added `thumbnails.popup` option
  - added `thumbnails._selectors.popup` and `thumbnails._selectors.popup_open` option
  - `item.popup.open` method is available. After calling this function, the following values are available:
  - `item.popup.html` - Popup HTML element
  - `item.popup.close()` - Popup close method
- Added Reader feature. Now you can read each type of file
  - `item.reader.read(callback)` method is now available. After calling this function, the following values are available:
  - `iteam.reader.node` - img, video and audio HTML node
  - `item.reader.src` - file reader result
  - `item.reader.duration` - video and audio duration
  - `item.reader.duration2` - video and audio formatted duration
  - `item.reader.width` - img and video width
  - `item.reader.height` - img and video height
  - `item.reader.frame` - video thumbnail
- Improved captions for multilangual templates.
  - added `captions.close`
  - added `captions.download`
  - added `captions.remove`
- The `thumbnails.item` and `thumbnails.item2` were some words like Download and Remove replaced with `${captions.download}` and `${captions.remove}`
- Classname `fileupload-no-thumbnail` was renamed to `fileuploader-no-thumbnail`
- Item thumbnail (canvas or img) are now aligned to the center of parent
- Improved Ajax progress handling. Now the progressbar will stay to 99% until the success callback will come.
- `item.renderThumbnail(src)` - now you can send a custom image src to render the thumbnail
- Fixed iPhone issue: "File with the name image.jpg is already selected."
- Improvements and fixes

### v1.0.0.5

- Colored icon in the Drag&drop example
- Fixed validator issue for AddMore option (#10)
- Fixed Clipboardpaste name issue
- Added id key for file data (id is a timestamp that can be used in the templates)
- Improved onListInput callback (now you don't need to create the list, it comes as a function property. Return the list to get the changes)
- updateFileList in Api functions (trigger file list updating)
- uploadStart in Api functions (trigger file upload for all files synchron/asynchron)

### v1.0.0.4

- Removed some commas in js script
- Added Drag&Drop feature in Chrome also for non-upload inputs

### v1.0.0.3

- Fixed <!DOCTYPE> tag in all HTML documents
- Fixed img styles for thumbnails example

### v1.0.0.2

- Fixed Safari issue (#2)

### v1.0

- Initial commit