<%@ Page Title="Folder Drop" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Folder Drop - AjaxUploader v5.2 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Folder Drop</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Directory / Folder Upload</div> <div class="demo-card-body"> <p class="demo-description"> Upload an entire folder by dropping it onto the drop zone or using the
 folder browse dialog. All files within the directory are uploaded.
 </p> <div class="demo-expect"><strong>What you should see:</strong> drop a whole folder and the tree is enumerated with relative paths preserved, so structure can be rebuilt server-side.</div> <style> .folder-zone {
 border: 2px dashed #d1d5db; border-radius: 0.75rem;
 padding: 2rem 1.5rem; text-align: center;
 background: #fafafa; transition: border-color 0.3s;
 }
 .folder-zone.drag-over { border-color: #f59e0b; background: #fffbeb; }
 .folder-icon { font-size: 2.5rem; margin-bottom: 0.5rem; }
 .folder-files { margin-top: 1rem; font-size: 0.8rem; color: #6b7280; max-height: 150px; overflow-y: auto; }
 </style> <div id="folderZone" class="folder-zone"> <div class="folder-icon"></div> <div>Drop a folder here or click to browse a directory</div> </div> <div id="folderUploader" style="margin-top:0.5rem;"></div> <div class="folder-files" id="folderFiles"></div> <div class="code-panel"> <pre><code>AjaxUploader.create(el, {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 multiple: true,
 autoUpload: true,
 dropTarget: zone,
 webkitdirectory: true,
 onTaskComplete: function(task) {
 // task.relativePath: 'folder/sub/name.ext' - also sent to the server
 // (relativePath form field / chunk-complete body) and surfaced in the
 // FileUploaded event as e.RelativePath for tree-preserving saves.
 log((task.relativePath || task.fileName) + ' uploaded');
 }
});</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> (function () {
 var zone = document.getElementById('folderZone');
 var files = document.getElementById('folderFiles');
 var host = document.getElementById('folderUploader');
 var counter = 0;
 if (!zone) return;
 zone.addEventListener('dragenter', function (e) { e.preventDefault(); counter++; zone.classList.add('drag-over'); });
 zone.addEventListener('dragleave', function () { counter--; if (counter <= 0) { counter = 0; zone.classList.remove('drag-over'); } });
 zone.addEventListener('dragover', function (e) { e.preventDefault(); });
 zone.addEventListener('drop', function () { counter = 0; zone.classList.remove('drag-over'); });

 if (!host || !window.AjaxUploader || typeof AjaxUploader.create !== 'function') return;
 AjaxUploader.create(host, {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 multiple: true,
 autoUpload: true,
 dropTarget: zone,
 webkitdirectory: true,
 onTaskStart: function (task) {
 var p = document.createElement('div');
 p.textContent = task.fileName + ' (uploading...)';
 p.id = 'folder-' + task.id;
 if (files) files.appendChild(p);
 },
 onTaskComplete: function (task) {
 var p = document.getElementById('folder-' + task.id);
 if (p) p.textContent = (task.relativePath || task.fileName) + ' (done - path preserved)';
 }
 });
 })();
</script>
</asp:Content>
