<%@ Page Title="Per-Chunk Progress" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Per-Chunk Progress - AjaxUploader v5.2 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Per-Chunk Progress</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Per-Chunk Progress Visualization</div> <div class="demo-card-body"> <p class="demo-description"> Visualize the upload progress of each individual chunk in a grid display. Each cell
 represents a chunk and changes color as it progresses from pending to uploading to complete.
 </p> <div id="uploader"></div> <div class="mt-3"> <div class="d-flex gap-3 mb-2 small"> <span><span class="badge bg-secondary">&nbsp;</span> Pending</span> <span><span class="badge bg-primary">&nbsp;</span> Uploading</span> <span><span class="badge bg-success">&nbsp;</span> Complete</span> <span><span class="badge bg-danger">&nbsp;</span> Failed</span> </div> <div id="chunkGrid" style="display:flex;flex-wrap:wrap;gap:4px;"></div> <div id="summary" class="mt-2 text-muted small"></div> </div> <div class="code-panel"> <pre><code>AjaxUploader.create('#uploader', {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 chunkUrl: '<%= ResolveUrl("~/ajaxupload.axd/chunk") %>',
 chunked: true,
 chunkSize: 1 * 1024 * 1024,
 onTaskStart: function(task) {
 var total = Math.ceil(task.total / (1 * 1024 * 1024));
 // Build grid cells for each chunk
 },
 onTaskProgress: function(task) {
 // Update chunk cell colors based on progress
 }
});</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> var grid = document.getElementById('chunkGrid');
 var summary = document.getElementById('summary');
 var chunkSize = 1 * 1024 * 1024;
 var cells = [];

 var uploaderHost = document.getElementById('uploader');
 if (window.AjaxUploader && typeof AjaxUploader.create === 'function' && uploaderHost) {
 AjaxUploader.create(uploaderHost, {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 chunkUrl: '<%= ResolveUrl("~/ajaxupload.axd/chunk") %>',
 chunked: true,
 chunkSize: chunkSize,
 onTaskStart: function(task) {
 if (!grid) return;
 grid.textContent = '';
 cells = [];
 var totalChunks = Math.ceil(task.total / chunkSize);
 for (var i = 0; i < totalChunks; i++) {
 var cell = document.createElement('div');
 cell.style.cssText = 'width:28px;height:28px;border-radius:4px;background:#6c757d;' +
 'display:flex;align-items:center;justify-content:center;color:#fff;font-size:.65rem;';
 cell.textContent = i + 1;
 grid.appendChild(cell);
 cells.push(cell);
 }
 if (summary && window.AjaxUploader && AjaxUploader.formatSize) {
 summary.textContent = totalChunks + ' chunks (' + AjaxUploader.formatSize(chunkSize) + ' each)';
 }
 },
 onTaskProgress: function(task) {
 var completedChunks = Math.floor((task.percent / 100) * cells.length);
 for (var i = 0; i < cells.length; i++) {
 if (i < completedChunks) {
 cells[i].style.background = '#198754';
 } else if (i === completedChunks) {
 cells[i].style.background = '#0d6efd';
 }
 }
 if (summary) {
 summary.textContent = completedChunks + ' / ' + cells.length + ' chunks complete';
 }
 },
 onTaskComplete: function(task) {
 cells.forEach(function(c) { c.style.background = '#198754'; });
 if (summary) {
 summary.textContent = 'All ' + cells.length + ' chunks uploaded successfully.';
 }
 },
 onTaskError: function(task) {
 var idx = Math.floor((task.percent / 100) * cells.length);
 if (cells[idx]) cells[idx].style.background = '#dc3545';
 }
 });
 }
</script>
</asp:Content>
