Bootstrap File Input Demo bootstrap-fileinput

Thankful to Krajee!
to get more out of us.

NOTE: The plugins on this site, strive to use a lot of CSS3 and HTML5 features in addition to JQuery. Hence, one may find either CSS3, HTML5 or a mix of both to achieve a plugin's requirements in many implementations.

An enhanced HTML 5 file input for Bootstrap 3.x with file preview for various files, offers multiple selection, and more. The plugin allows you a simple way to setup an advanced file picker/upload control built to work specially with Bootstrap CSS3 styles. It enhances the file input functionality further, by offering support to preview a wide variety of files i.e. images, text, html, video, audio, flash, and objects. In addition, it includes AJAX based uploads, dragging & dropping files, viewing upload progress, and selectively previewing, adding, or deleting files.

This plugin was initially inspired by this blog article and Jasny's File Input plugin. But the plugin has now matured with various additional features and enhancements to be a complete (yet simple) file management tool and solution for web developers.

With release v4.0.0, the plugin now supports AJAX based uploads using HTML 5 FormData and XHR2 protocol, which is supported in most modern browsers. It also has inbuilt support for AJAX based file deletion from the server. This thereby allows powerful features to append, add, remove files on the fly. The plugin also has added DRAG & DROP support for ajax uploads. In the event, the browser does not support FormData or XHR2, the plugin degrades it to a normal form submission.

Note

You can refer this webtip for an example of processing ajax based uploads using PHP.

Automatically convert a file input to a bootstrap file input widget by setting its class as file

Hide file preview thumbnails

Use file input attributes (e.g. multiple upload) for setting input behavior and data attributes to control plugin options. For example, hide/show display of upload button and caption.

Set the file input widget to be readonly or disabled

Initialize file input widget via javascript. Hide the caption and display widget with only buttons. You can add the file-loading class to show a spinning indicator, while the plugin loads.

Change size of whole widget (e.g. bootstrap input group styling) and set max files count allowed to 10.
// Automatically convert a file input to a bootstrap file input widget
// by setting its class as 'file'
<input id="input-1" type="file" class="file">

// Hide file preview thumbnails
<input id="input-1a" type="file" class="file" data-show-preview="false">

// Use file input attributes (e.g. multiple upload) for setting input behavior and data attributes to 
// control plugin options. For example, hide/show display of upload button and caption.
<input id="input-2" type="file" class="file" multiple="true" data-show-upload="false" data-show-caption="true">

// Set the file input widget to be readonly or disabled
 <input id="input-3a" type="file" class="file" readonly="true">
 <input id="input-3b" type="file" class="file" disabled="true">

// Initialize file input widget via javascript. Hide the caption and display widget with only buttons.
<input id="input-4" type="file" multiple="true">
/* Javascript call to initialize plugin with your desired options */
$("#input-4").fileinput({showCaption: false}); 

// Change size of whole widget (e.g. bootstrap input group styling)  and set max files count 
// allowed to 10.
<input id="input-5" type="file" multiple="true">
/* Javascript call to initialize plugin with your desired options */
$("#input-5").fileinput({showUpload: false, maxFileCount: 10, mainClass: "input-group-lg"});

Set maximum file upload size to 100 KB. Display preview on load with preset files/images and captions with overwriteInitial set to false. So the initial preview is always displayed when additional files are overwritten (useful for multiple upload) scenario.

Display preview on load with preset files/images and captions with overwriteInitial set to true.

Display the widget as a single block button

Show only image files for selection & preview. Control button labels, styles, and icons for the browse, upload, and remove buttons.

Preview section control. Change preview background and allow text files ONLY for selection as well as preview.

Advanced customization using templates. For example, change position of buttons from right to left.


Using plugin methods to alter input at runtime. For example, click the Modify button to disable the plugin and change plugin options.

Allow only image and video file types to be uploaded. You can configure the condition for validating the file types using fileTypeSettings.

Allow only specific file extensions.

Disable preview and customize your own error container and messages.
// Set maximum file upload size to 100 KB. Display preview on load with preset files/images and captions
// with `overwriteInitial` set to false. So the initial preview is always displayed when additional files 
// are overwritten (useful for multiple upload) scenario.
<input id="input-24" type="file" multiple="true">
$("#input-24").fileinput({
    initialPreview: [
        "<img src='/images/moon.jpg' class='file-preview-image' alt='The Moon' title='The Moon'>",
        "<img src='/images/earth.jpg' class='file-preview-image' alt='The Earth' title='The Earth'>",
    ],
    overwriteInitial: false,
    maxFileSize: 100,
    initialCaption: "The Moon and the Earth"
});

// Display preview on load with preset files/images and captions
// with `overwriteInitial` set to true.
<input id="input-25" type="file" multiple="true">
$("#input-25").fileinput({
    initialPreview: [
        "<img src='/images/moon.jpg' class='file-preview-image' alt='The Moon' title='The Moon'>",
        "<img src='/images/earth.jpg' class='file-preview-image' alt='The Earth' title='The Earth'>",
    ],
    overwriteInitial: true,
    initialCaption: "The Moon and the Earth"
});

// Display the widget as a single block button
<input id="input-20" type="file">
/* Initialize your widget via javascript as follows */
$("#input-20").fileinput({
	browseClass: "btn btn-primary btn-block",
	showCaption: false,
	showRemove: false,
	showUpload: false
});

// Show only image files for selection & preview. Control button labels, styles, 
// and icons for the browse, upload, and remove buttons.
<input id="input-21" type="file" accept="image/*" >
<script>
/* Initialize your widget via javascript as follows */
$("#input-21").fileinput({
	previewFileType: "image",
	browseClass: "btn btn-success",
	browseLabel: "Pick Image",
	browseIcon: '<i class="glyphicon glyphicon-picture"></i>',
	removeClass: "btn btn-danger",
	removeLabel: "Delete",
	removeIcon: '<i class="glyphicon glyphicon-trash"></i>',
	uploadClass: "btn btn-info",
	uploadLabel: "Upload",
	uploadIcon: '<i class="glyphicon glyphicon-upload"></i>',
});
</script>

// Preview section control. Change preview background and allow text files ONLY 
// for selection as well as preview.
<input id="input-22" type="file" class="file-loading" accept="text/plain" multiple=true>
<script>
$("#input-22").fileinput({
    previewFileType: "text",
    allowedFileExtensions: ["txt", "md", "ini", "text"],
    previewClass: "bg-warning"
});
</script>
 
// Advanced customization using templates. For example, change position of buttons 
// from right to left.
<input id="input-23" type="file" multiple="true">
<script>
$("#input-23").fileinput({
	showUpload: false,
	layoutTemplates: {
        main1: "{preview}\n" +
        "<div class=\'input-group {class}\'>\n" +
        "   <div class=\'input-group-btn\'>\n" +
        "       {browse}\n" +
        "       {upload}\n" +
        "       {remove}\n" +
        "   </div>\n" +
        "   {caption}\n" +
        "</div>"
    }
});
</script>

// Using plugin methods to alter input at runtime. For example, click the 
// Modify button to disable the plugin and change plugin options.
<input id="input-40" type="file" class="file" multiple=true>
<script>
$(".btn-modify").on("click", function() {
    $btn = $(this);
    if ($btn.text() == "Modify") {
        $("#input-40").fileinput("disable");
        $btn.html("Revert");
        alert("Hurray! I have disabled the input and hidden the upload button.");
    }
    else {
        $("#input-40").fileinput("enable");
        $btn.html("Modify");
        alert("Hurray! I have reverted back the input to enabled with the upload button.");
    }
});
</script>

// Allow only image and video file types to be uploaded. You can configure 
// the condition for validating the file types using `fileTypeSettings`.
<input id="input-41" type="file" multiple=true>
<script>
$("#input-41").fileinput({
    maxFileCount: 10,
    allowedFileTypes: ["image", "video"]
});
</script>

// Allow only specific file extensions to be uploaded. 
<input id="input-42" type="file" multiple=true>
<script>
$("#input-42").fileinput({
    maxFileCount: 10,
    allowedFileExtensions: ["jpg", "gif", "png", "txt"]
});
</script>

// Disable preview and customize your own error container and messages.
<input id="input-43" type="file" multiple=true>
<div id="errorBlock43" class="help-block"></div>
<script>
$("#input-43").fileinput({
    showPreview: false,
    allowedFileExtensions: ["zip", "rar", "gz", "tgz"],
    elErrorContainer: "#errorBlock43"
    // you can configure `msgErrorClass` and `msgInvalidFileExtension` as well
});
</script>

You need to setup the server methods to parse and return the right response via AJAX. You can setup uploads in two modes as described below.

This is the default mode, whereby the uploadAsync property is set to true. When uploading multiple files, the asynchronous mode allows triggering parallel server calls for each file upload. You can control the maximum number of files allowed at a time to be uploaded by setting the maxFileCount property. In asynchronous mode, progress of each thumbnail in the preview is validated and updated.


Receiving Data (on server)

Your server method as set in uploadUrl receives the following data from the plugin

  1. file data: This data is sent to the server in a format very similar to the form file input. For example in PHP you can read this data as $_FILES['input-name'], where input-name is the name attribute of your input. If you do not set a name attribute for your input, the name is defaulted to file_data. Note that multiple file uploads require that you set multiple property to true for your input. So in PHP you would receive the file data as $_FILES['file_data']

  2. extra data: The plugin can send additional data to your server method. This can be done by setting uploadExtraData as an associative array object in key value pairs. So if you have setup uploadExtraData={id:'kv-1'}, in PHP you can read this data as $_POST['id'].


Sending Data (from server)

Your server method as set in uploadUrl must send data back as a json encoded object. In this case you can send these 4 pieces of information. Note that in asynchronous mode, you will ALWAYS receive ONE FILE record from the server - so adjust your code accordingly.

  • error: string, which will be the error message for the entire batch upload and will help the plugin to identify error in the file upload. For example the response from server would be sent as {error: 'You are not allowed to upload such a file.'}. Note: The plugin will automatically validate and display ajax exception errors.

  • initialPreview: array, the list of image files or any HTML markup to point to your uploaded files. You will always send ONE row in this array - because you will always receive ONE file with the upload in asynchronous mode. If this property is set, the plugin will automatically replace the files dynamically in the preview content after upload success. The configuration for this is similar to the initialPreview option setting. For example:

    initialPreview: [
        '<img src='/images/desert.jpg' class='file-preview-image' alt='Desert' title='Desert'>',
    ],
    
  • initialPreviewConfig: array, the configuration to identify properties for each file markup in initialPreview item (that is setup as part of initialPreview). You will always send ONE row in this array - because you will always receive ONE file with the upload in asynchronous mode. If this property is set, the plugin will automatically replace the files dynamically in the preview content after upload success. The configuration for this is similar to the initialPreviewConfig option setting. For example:

    initialPreviewConfig: [
        {
            caption: 'desert.jpg', 
            width: '120px', 
            url: 'http://localhost/avatar/delete', // server delete action 
            key: 100, 
            extra: {id: 100}
        }
    ]
    
  • initialPreviewThumbTags: array, an array of objects corresponding to replacing tags within each initial preview thumbnail. The initial preview thumbnails set via initialPreview will read this configuration for replacing tags.

    // change thumbnail footer template
    // set initial preview template tags
    initialPreviewThumbTags:[
        {
            '{CUSTOM_TAG_NEW}': ' ',
            '{CUSTOM_TAG_INIT}': 'lt;span class=\'custom-css\'>CUSTOM MARKUPlt;/span>'
        }
    ];
    
  • append: boolean, whether to append the content to the initialPreview if you already set an initialPreview on INIT. If not set this defaults to true. If set to false, the plugin will overwrite the initialPreview content.

IMPORTANT

  • You MUST send a valid JSON response from your server, else the upload process will fail. Even if you do not encounter any error, you must at least send an empty JSON object {} from your server.

  • To trap and display a validation error, your JSON response data must include the error key, whose value will be the error HTML markup to display. This is to be setup as mentioned above.

  • You can also send in additional keys or data with your JSON response, for you to process them for advanced cases using events like fileuploaded.

In this mode, the uploadAsync property is set to false. This will trigger just one batch upload call to the server and send files from client to server as an array object. Even in this mode, you can control the maximum number of files allowed at a time to be uploaded by setting the maxFileCount property. However, in synchronous mode, progress will be only at a overall level. Progress of each thumbnail in the preview is not exactly validated and updated. However, the plugin offers you a method of identifying upload errors faced for each file.


Receiving Data (on server)

Your server method as set in uploadUrl receives the following data from the plugin

  1. file data: This data is sent to the server in a format very similar to the form file input. For example in PHP you can read this data as $_FILES['input-name'], where input-name is the name attribute of your input. Also as in asynchronous mode before, if you do not set a name attribute for your input, the name is defaulted to file_data. You must set your input name as an array format as mentioned in this web tip, in addition to setting multiple property to true. If you do not set your input name as an array format, you would receive only the first file on your server. In PHP you would receive the file data as $_FILES['input-name'], which will be an array of file objects.

  2. extra data: The plugin can send additional data to your server method. This can be done by setting uploadExtraData as an associative array object in key value pairs. So if you have setup uploadExtraData={id:'kv-1'}, in PHP you can read this data as $_POST['id'].


Sending Data (from server)

In synchronous mode as well, the uploadUrl must send data back as a json encoded object. In this case you send these 5 pieces of information.

  • error: string, which will be the error message for the entire batch upload and will help the plugin to identify error in the file upload.

  • errorkeys: array, the keys (zero-based indexes for the file data received) for the files that have errored out. Based on this data, the plugin will automatically set the thumbnails and each individual preview file to error out.

  • initialPreview: array, the list of image files or any HTML markup to point to your uploaded files. If this property is set, the plugin will automatically replace the files dynamically in the preview content after upload success. The configuration for this is similar to the initialPreview option setting. For example:

    initialPreview: [
        '<img src='/images/desert.jpg' class='file-preview-image' alt='Desert' title='Desert'>',
        '<img src='/images/jellyfish.jpg' class='file-preview-image' alt='Jelly Fish' title='Jelly Fish'>',
    ],
    
  • initialPreviewConfig: array, the configuration to identify properties for each file markup in initialPreview item (that is setup as part of initialPreview). If this property is set, the plugin will automatically replace the files dynamically in the preview content after upload success. The configuration for this is similar to the initialPreviewConfig option setting. For example:

    initialPreviewConfig: [
        {
            caption: 'desert.jpg', 
            width: '120px', 
            url: 'http://localhost/avatar/delete', // server delete action 
            key: 100, 
            extra: {id: 100}
        },
        {
            caption: 'jellyfish.jpg', 
            width: '120px', 
            url: 'http://localhost/avatar/delete', // server delete action 
            key: 101, 
            extra: function() { 
                return {id: $('#id').val()};
            },
        }
    ]
    
  • initialPreviewThumbTags: array, an array of objects corresponding to replacing tags within each initial preview thumbnail. The initial preview thumbnails set via initialPreview will read this configuration for replacing tags.

    // change thumbnail footer template
    // set initial preview template tags
    initialPreviewThumbTags:[
        {
            '{CUSTOM_TAG_NEW}': ' ',
            '{CUSTOM_TAG_INIT}': 'lt;span class=\'custom-css\'>CUSTOM MARKUP 1lt;/span>'
        },
        {
            '{CUSTOM_TAG_NEW}': ' ',
            '{CUSTOM_TAG_INIT}': 'lt;span class=\'custom-css\'>CUSTOM MARKUP 2lt;/span>'
        }
    ];
    
  • append: boolean, whether to append the content to the initialPreview if you already set an initialPreview on INIT. If not set this defaults to true. If set to false, the plugin will overwrite the initialPreview content.

For example the response from server would be sent as {error: 'You have faced errors in 4 files.', errorkeys: [0, 3, 4, 5]}. Note: The plugin will automatically validate and display ajax exception errors.

IMPORTANT

  • You MUST send a valid JSON response from your server, else the upload process will fail. Even if you do not encounter any error, you must at least send an empty JSON object {} from your server.

  • To trap and display a validation error, your JSON response data must include the error key, whose value will be the error HTML markup to display. In addition, you must typically also send the errorkeys for synchronous mode to identify the keys for files which faced errors. This is to be setup as mentioned above.

  • You can also send in additional keys or data with your JSON response, for you to process them for advanced cases using events like filebatchuploadsuccess.

Asynchronous / Parallel AJAX based uploads with drag and drop functionality. Just set the uploadUrl data property and multiple to true. Note that the file input name attribute for multiple uploads should be setup as a array format. You can modify files selected before upload i.e. append or delete. For this example below, you can read the uploaded files on your server for the input name kartik-input-700.

<input id="input-700" name="kartik-input-700[]" type="file" multiple class="file-loading">
<script>
$("#input-700").fileinput({
    uploadUrl: "http://localhost/file-upload-single/1", // server upload action
    uploadAsync: true,
    maxFileCount: 5
});
</script>

Synchronous / Sequential AJAX based uploads (only one server ajax method called) with drag and drop functionality. Very similar to scenario 1 - however you set the uploadAsync property to false in this case. For this example below, you can read the uploaded files on your server for the input name kartik-input-701.

<input id="input-701" name="kartik-input-701[]" type="file" multiple=true class="file-loading">
<script>
$("#input-701").fileinput({
    uploadUrl: "http://localhost/file-upload-batch/1", // server upload action
    uploadAsync: true,
    maxFileCount: 5
});
</script>

Initial Preview Configuration for AJAX based uploads along with initial preview delete button and methods. The overwriteInitial property is set to false. This scenario also shows additional extra data you can send with the file uploaded to the server by configuring uploadExtraData. This scenario also shows how you can setup minimum file count (2 for this case) to make your file input mandatory to have the minimum number of files.

<input id="input-702" name="kartik-input-702[]" type="file" multiple=true class="file-loading">
<script>
$("#input-702").fileinput({
    uploadUrl: "http://localhost/file-upload-single/1", // server upload action
    uploadAsync: true,
    minFileCount: 1,
    maxFileCount: 5,
    overwriteInitial: false,
    initialPreview: [
        "<img src='http://lorempixel.com/200/150/people/1'>",
        "<img src='http://lorempixel.com/200/150/people/2'>",
    ],
    initialPreviewConfig: [
        {caption: "People-1.jpg", width: "120px", url: "/site/file-delete", key: 1},
        {caption: "People-2.jpg", width: "120px", url: "/site/file-delete", key: 2}, 
    ],
    uploadExtraData: {
        img_key: "1000",
        img_keywords: "happy, nature",
    }
});
</script>

Extension of scenario 1 for asynchronous uploads - in which you can dynamically setup the initialPreview and initialPreviewConfig immediately after upload at runtime. For this you must return the initialPreview, initialPreviewConfig, and append properties within a JSON object from your server. TIP: Try uploading each file through upload icon in the thumbnail and you can see each thumbnail getting replaced by the server generated file link. Refer to the documentation for receiving data on server or sending data from server in asynchronous mode.

Note

For these demo scenarios, the server code actually does not store / upload the files on the server and returns a dummy set of images for testing.

<input id="input-703" name="kartik-input-703[]" type="file" multiple class="file-loading">
<script>
$("#input-703").fileinput({
    uploadUrl: "/file-upload-single/2",
    uploadAsync: true,
    minFileCount: 1,
    maxFileCount: 5
});
</script>
<?php
// ...
// SERVER CODE that processes ajax upload and returns a JSON response. Your server action 
// must return a json object containing initialPreview, initialPreviewConfig, & append.
// An example for PHP Server code is mentioned below.
// ...
$key = '<code to parse your image key>';
$url = '<your server action to delete the file>';
echo json_encode([
    'initialPreview' => [
        "<img src='http://path.to.uploaded.file/{$key}.jpg' class='file-preview-image'>",
    ],
    'initialPreviewConfig' => [
        ['caption' => "Sport-{$key}.jpg", 'width' => '120px', 'url' => $url, 'key' => $key],
    ],
    'append' => true // whether to append these configurations to initialPreview.
                     // if set to false it will overwrite initial preview
                     // if set to true it will append to initial preview
                     // if this propery not set or passed, it will default to true.
]);
?>

Extension of scenario 2 for synchronous batch uploads - in which you can dynamically setup the initialPreview and initialPreviewConfig immediately after upload at runtime. For this you must return the initialPreview, initialPreviewConfig, and append properties within a JSON object from your server. Refer to the documentation for receiving data on server or sending data from server in synchronous mode.

Note

For these demo scenarios, the server code actually does not store / upload the files on the server and returns a dummy set of images for testing.

<input id="input-704" name="kartik-input-704[]" type="file" multiple=true class="file-loading">
<script>
$("#input-704").fileinput({
    uploadUrl: "http://localhost/file-upload-batch/2", // server upload action
    uploadAsync: false,
    minFileCount: 1,
    maxFileCount: 5
});
</script>
<?php
// ...
// SERVER CODE that processes ajax upload and returns a JSON response. Your server action 
// must return a json object containing initialPreview, initialPreviewConfig, & append.
// An example for PHP Server code is mentioned below.
// ...
$p1 = $p2 = [];
if (empty($_FILES['kartik-input-704']['name'])) {
    echo '{}';
    return;
}
for ($i = 0; $i < count($_FILES['kartik-input-704']['name']); $i++) {
    $j = $i + 1;
    $key = '<code to parse your image key>';
    $url = '<your server action to delete the file>';
    $p1[$i] = "<img src='http://path.to.uploaded.file/{$key}.jpg' class='file-preview-image'>",;
    $p2[$i] = ['caption' => "Animal-{$j}.jpg", 'width' => '120px', 'url' => $url, 'key' => $key];
}
echo json_encode([
    'initialPreview' => $p1, 
    'initialPreviewConfig' => $p2,   
    'append' => true // whether to append these configurations to initialPreview.
                     // if set to false it will overwrite initial preview
                     // if set to true it will append to initial preview
                     // if this propery not set or passed, it will default to true.
 ]);
?>

Extension of scenario 5 to trigger auto upload immediately after files are dragged & dropped (OR when files are selected via browse button). Note that the filebatchselected event is used to trigger the auto upload. We will HIDE the upload and remove buttons for this scenario. Like scenario 5, this incorporates synchronous batch uploads in which you can dynamically setup the initialPreview and initialPreviewConfig immediately after upload at runtime. For this you must return the initialPreview, initialPreviewConfig, and append properties within a JSON object from your server. Refer to the documentation for receiving data on server or sending data from server in synchronous mode.

Note

For these demo scenarios, the server code actually does not store / upload the files on the server and returns a dummy set of images for testing.

<input id="input-705" name="kartik-input-705[]" type="file" multiple=true class="file-loading">
<script>
var $input = $("#input-705");
$input.fileinput({
    uploadUrl: "http://localhost/file-upload-batch/2", // server upload action
    uploadAsync: false,
    showUpload: false, // hide upload button
    showRemove: false, // hide remove button
    minFileCount: 1,
    maxFileCount: 5
}).on("filebatchselected", function(event, files) {
    // trigger upload method immediately after files are selected
    $input.fileinput("upload");
});
</script>
?>

Extension of scenario 3 to include your own custom thumbnail templates for capturing additional data in each preview thumbnail. This will include an example of setting the layoutTemplates.footer property. The previewThumbTags will be used to replace the tags in the template dynamically at runtime. After upload, the data returned by initialPreview will be replaced by tags from initialPreviewThumbTags. These tags will be an array of tag objects that will be replaced in the thumbnail footer template for each thumbnail in the initial preview.

Note

For these demo scenarios, the server code actually does not store / upload the files on the server and returns a dummy set of images for testing.

<input id="input-706" name="kartik-input-706[]" type="file" multiple=true class="file-loading">
<script>
var $input = $("#input-706");

// custom footer template for the scenario
// the custom tags are in braces
var footerTemplate = '<div class="file-thumbnail-footer">\n' +
'   <div style="margin:5px 0">\n' +
'       <input class="kv-input kv-new form-control input-sm {TAG_CSS_NEW}" value="{caption}" placeholder="Enter caption...">\n' +
'       <input class="kv-input kv-init form-control input-sm {TAG_CSS_INIT}" value="{TAG_VALUE}" placeholder="Enter caption...">\n' +
'   </div>\n' +
'   {actions}\n' +
'</div>';

$input.fileinput({
    uploadUrl: "http://localhost/file-upload-batch/1", // server upload action
    uploadAsync: false,
    overwriteInitial: false,
    minFileCount: 2,
    maxFileCount: 5,
    layoutTemplates: {footer: footerTemplate},
    previewThumbTags: {
        '{TAG_VALUE}': '',        // no value
        '{TAG_CSS_NEW}': '',      // new thumbnail input
        '{TAG_CSS_INIT}': 'hide'  // hide the initial input
    },
    initialPreview: [
        "<img src='http://lorempixel.com/200/150/people/1'>",
        "<img src='http://lorempixel.com/200/150/people/2'>",
    ],
    initialPreviewConfig: [
        {caption: "People-1.jpg", width: "120px", url: "/site/file-delete", key: 1},
        {caption: "People-2.jpg", width: "120px", url: "/site/file-delete", key: 2}, 
    ],
    initialPreviewThumbTags: [
        {'{TAG_VALUE}': 'People-1.jpg', '{TAG_CSS_NEW}': 'hide', '{TAG_CSS_INIT}': ''},
        {
            '{TAG_VALUE}': function() { // callback example
                return 'People-2.jpg';
            },
            '{TAG_CSS_NEW}': 'hide',
            '{TAG_CSS_INIT}': ''
        }
    ],
    uploadExtraData: function() {  // callback example
        var out = {}, key, i = 0;
        $('.kv-input:visible').each(function() {
            $el = $(this);
            key = $el.hasClass('kv-new') ? 'new_' + i : 'init_' + i;
            out[key] = $el.val();
            i++;
        });
        return out;
    }
});
</script>

Note

You can refer this webtip for an example of processing ajax based uploads using PHP.