<%@ Page Title="Custom Progress UI" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Custom Progress UI - AjaxUploader v5.0 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Custom Progress UI</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Fully Custom Progress Rendering</div> <div class="demo-card-body"> <p class="demo-description"> Build a completely custom progress display with file icon, name,
 size, progress bar, and action buttons rendered via JavaScript.
 </p> <style> .custom-progress-list { margin-top: 1rem; }
 .cp-item {
 display: flex; align-items: center; gap: 0.75rem;
 padding: 0.6rem 0.75rem; margin-bottom: 0.5rem;
 border: 1px solid #e5e7eb; border-radius: 0.5rem;
 background: #fafafa;
 }
 .cp-icon { font-size: 1.4rem; }
 .cp-info { flex: 1; min-width: 0; }
 .cp-name { font-size: 0.85rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
 .cp-size { font-size: 0.7rem; color: #9ca3af; }
 .cp-bar { width: 100px; height: 6px; background: #e5e7eb; border-radius: 3px; overflow: hidden; }
 .cp-bar-fill { height: 100%; width: 0%; background: #3b82f6; transition: width 0.2s; }
 .cp-status { font-size: 0.75rem; width: 60px; text-align: right; }
 .cp-status.done { color: #10b981; font-weight: 600; }
 .cp-status.error { color: #ef4444; }
 </style> <div id="cpUploader"></div> <div class="custom-progress-list" id="cpList"></div> <div class="code-panel"> <pre><code>onTaskStart: function(task) {
 // build custom row: icon + name + size + bar + status
 list.appendChild(createCustomRow(task));
},
onTaskProgress: function(task, pct) {
 row.querySelector('.bar-fill').style.width = pct + '%';
 row.querySelector('.status').textContent = Math.round(pct) + '%';
},
onTaskComplete: function(task) {
 row.querySelector('.status').textContent = 'Done';
}</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> (function () {
 var list = document.getElementById('cpList');
 function fmtSize(b) {
 if (b >= 1048576) return (b / 1048576).toFixed(1) + ' MB';
 return (b / 1024).toFixed(0) + ' KB';
 }
 AjaxUploader.create(document.getElementById('cpUploader'), {
 uploadUrl: '<%= ResolveUrl("~/ajaxupload.axd/upload") %>',
 multiple: true,
 autoUpload: true,
 onTaskStart: function (task) {
 var el = document.createElement('div');
 el.className = 'cp-item'; el.id = 'cp-' + task.id;
 el.innerHTML = '<span class="cp-icon"></span>'
 + '<div class="cp-info"><div class="cp-name">' + task.fileName + '</div>'
 + '<div class="cp-size">' + fmtSize(task.fileSize || 0) + '</div></div>'
 + '<div class="cp-bar"><div class="cp-bar-fill"></div></div>'
 + '<span class="cp-status">0%</span>';
 list.appendChild(el);
 },
 onTaskProgress: function (task, pct) {
 var el = document.getElementById('cp-' + task.id);
 if (!el) return;
 el.querySelector('.cp-bar-fill').style.width = pct + '%';
 el.querySelector('.cp-status').textContent = Math.round(pct) + '%';
 },
 onTaskComplete: function (task) {
 var el = document.getElementById('cp-' + task.id);
 if (!el) return;
 el.querySelector('.cp-bar-fill').style.width = '100%';
 el.querySelector('.cp-bar-fill').style.background = '#10b981';
 var s = el.querySelector('.cp-status');
 s.textContent = 'Done'; s.className = 'cp-status done';
 },
 onTaskError: function (task, err) {
 var el = document.getElementById('cp-' + task.id);
 if (!el) return;
 var s = el.querySelector('.cp-status');
 s.textContent = 'Error'; s.className = 'cp-status error';
 }
 });
 })();
</script>
</asp:Content>
