void ControlTreeDataLoader.LoadData() { Attributes.Add( uniqueIdentifierAttribute, UniqueUdentifier ); Attributes.Add( parmetersAttribute, Parameters ); // This gives us some ability to be slightly more strongly typed, allowing us to change the actual attribute names here while not breaking script. EwfPage.Instance.ClientScript.RegisterClientScriptBlock( GetType(), uniqueIdentifierAttribute, @"uniqueIdentifierAttribute = '{0}';".FormatWith( uniqueIdentifierAttribute ), true ); EwfPage.Instance.ClientScript.RegisterClientScriptBlock( GetType(), parmetersAttribute, @"parameters = '{0}';".FormatWith( parmetersAttribute ), true ); // Provides a handle to the upload service for the script. EwfPage.Instance.ClientScript.RegisterClientScriptBlock( GetType(), "uploadServicePath", @"uploadServicePath = '{0}';".FormatWith( ResolveClientUrl( "~/Ewf/FileUploader/Upload.aspx" ) ), true ); // Handle to the path of the progress image. jquery.progressbar needs to know where the images are to be used. // Just because this appears above the definition of jquery.progressbar doesn't mean it appears before // it in the resulting document, which causes the progressbar file to consider it undefined. To fix this, // I wrapped the jquery.progressbar file in a $(document).ready() call so that it is not defined until the // entire document loads, where imagesPath will be already defined, no matter its position. EwfPage.Instance.ClientScript.RegisterClientScriptBlock( GetType(), "imagesPath", @"imagesPath = '{0}';".FormatWith( ResolveClientUrl( "~/Ewf/FileUploader/" ) ), true ); // NOTE: So this won't work if this control is used in a user control... var encryptedFullyQualifiedName = EncryptionOps.GetEncryptedString( EncryptionOps.GenerateInitVector(), EwfPage.Instance.GetType().BaseType.FullName ); EwfPage.Instance.ClientScript.RegisterClientScriptBlock( GetType(), "pageHandle", @"pageHandle = '{0}';".FormatWith( encryptedFullyQualifiedName ), true ); EwfPage.Instance.ClientScript.RegisterClientScriptInclude( GetType(), "ClientSide", this.GetClientUrl( "~/Ewf/FileUploader/ClientSide.js" ) ); EwfPage.Instance.ClientScript.RegisterClientScriptInclude( GetType(), "jquery.progressbar", this.GetClientUrl( "~/Ewf/FileUploader/jquery.progressbar.min.js" ) ); // Choose between dropping files onto the page or browse for them. var chooseUploadMethod = SelectList.CreateRadioList( SelectList.GetTrueFalseItems( "Drag and drop files", "Browse for files" ), true, useHorizontalLayout: true ); var dragFilesHerePanel = new Panel { CssClass = "dropZone" }.AddControlsReturnThis( new Paragraph( "Drop files here" ) { CssClass = "dropFilesHereMessage" } ); // Not using an ASP.NET control because I want full control without any magic. var browseForFiles = new WebControl( HtmlTextWriterTag.Input ); browseForFiles.Attributes.Add( "type", "file" ); browseForFiles.Attributes.Add( "multiple", "multiple" ); browseForFiles.Attributes.Add( "onchange", @"inputChanged(this);" ); chooseUploadMethod.AddDisplayLink( ( true as bool? ).ToSingleElementArray(), true, dragFilesHerePanel.ToSingleElementArray() ); chooseUploadMethod.AddDisplayLink( ( false as bool? ).ToSingleElementArray(), true, browseForFiles.ToSingleElementArray() ); var uploadPending = new Section( "Files to be uploaded", new Control[] { new Panel { CssClass = "queuedFilesContentArea" }.AddControlsReturnThis( new Paragraph( "No files are currently in the queue." ) ), new Panel { CssClass = "upload-count" } }, style: SectionStyle.Box ) { CssClass = "queuedFiles" }; Controls.Add( new Section( new Control[] { new Panel { CssClass = "ewfErrorMessageListBlock" }, chooseUploadMethod, new Panel { CssClass = "dropWrapper" }.AddControlsReturnThis( dragFilesHerePanel ), browseForFiles, uploadPending, new CustomButton( () => @"uploadButtonClicked(this);" ) { ActionControlStyle = new ButtonActionControlStyle( "Begin upload" ), CssClass = "beginUploadButton" } }, style: SectionStyle.Box ) { CssClass = "upload-box" } ); }