David Sterngast · Jun 20, 2018

How to add Javascript code to csp file down load application.

When I down load a file using a csp page, the application  shows  the percentage as  37 %, 74 %, and 100 %.    I am trying to make changes to the application that it shows one percentage after each read.  The first time it reads, it would display 37%.   The next run would replace

37 %  with 74 % and so on until it completes its download.   I have tried adding javascript code to the application  however it doesn't work.   For example when I enter &js('alert');, the application displays it value on the screen.  Also, I tryed putting it between two scripts tags and it doesn't work.

I can use html however I cannot update the line after it displays information.   Does anybody know how I can use javascript code with cache method?   

Below is my code:


<form enctype="multipart/form-data" method="post" action="upload20180615.csp">
    Enter a file to upload here: <input type=file size=30 name=FileStream>
    <hr />
    <ul><input type="submit" value="Upload file"></ul>

<csp:if condition='($data(%request.MimeData("FileStream",1)))'>
    <h2>Saving file...</h2>
    <h0 style="background-color:MediumSeaGreen;">Process status: </h0>
    <script language="Cache" runat="server">
        Set data=%request.MimeData("FileStream",1)
        Set stream=##class(%FileBinaryStream).%New()
        Set D=%request.MimeData("FileStream",1).FileName ;selected file
        Set Size=%request.MimeData("FileStream",1).Size 
        ;Set file=##class(%File).%New(D)
        L="" I=1:1:10 T=$P(D,"\",I) T=""  L=Q        
        DIR="F:\a misc\"
        X=$ZF(-1,"MKDIR """_DIR_"""")
        ;retrieve the file and place in the new placeo
        Do stream.LinkToFile(DIR_FILE)
        Set RTotal = 0
        While (data.AtEnd'=1) {
        Set len=32000
         Set x=data.Read(.len)
         Set RTotal=RTotal+len
         Set Percent = ((RTotal / Size) * 100) \ 1
         Do stream.Write(x)
         ;Write "<h>"_Percent_" % </h>"
          d=Percent s:$l(d)=2 d=" "_d=d_" %"
           ;Write "<h style=background-color:rgb(60,179,113);>"_Percent_" % </h>"
           ;&js< alert('hi') >
            &html< <h>#(d)#</h> >

Set Status = stream.SaveStream()
        If (Status = 1) {
            Write "<h2>Uploaded!</h2>"            
        Else {
            Write "<h2>Saving failed!</h2>"


3 0 4 546


You try to upload a file and JS Code a the same time during your SUBMIT action.
so your &js< ...> lands every 32000 characters inside your file.

&js<..> is just a hidden WRITE and allows javascript syntax checking inside the <.. >


&js<alert('Unable to create user.');> 

is identic to 

Write "alert('Unable to create user.');",!

So your concept doesn't work that way
You would require a second independent JS routine in a browser to call for progress using CSP hyperevent.

Why you don't call a method and into this method you show the message with &JS<>, you was try this?

Hi David

I think this is a feature(?) of the way Javascript and the upload work in any browser - running JS or an upload blocks any UI updating

so it's not possible to do easily or at all - I think


Try the following example of uploading multiple files at once, showing the progress for each file you upload (without form, submit, iframe, jQuery, flash, java, reloading/redrawing the page):

<!DOCTYPE html>
    <title>Upload multiple files using XMLHttpRequest</title>

    <style type="text/css">
    .ok {

    #dropZone {
      width: 360px;
      height: 125px;
      borderdashed 2px #ccc;
      background-color: #fefefe;
      color: #ccc;
      padding: 125px 0 0 0;
<body onload="onloadHandler()">
<div id="dropZone">Drag and drop files here or use the button below</div>
  Select files
  <input type="file" id="fileToUpload" onchange="fileSelected(document.getElementById('fileToUpload').files)" multiple="multiple" />
<button type="button" title="Clearing the queue" onclick="clearList();">Clear</button>
<button type="button" title="Upload files to the server" onclick="upFile();">Upload</button>
<div id="holder"></div>
<script language="javascript">
function clearList()

function fileSelected(files){
  var holder document.getElementById('holder');
  for (var = 0; i files.length; i++) {
    var file files[i];

    var fileSize = 0;
    if (file.size > 1024 * 1024)
      fileSize (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() 'Mbyte';
      fileSize (Math.round(file.size * 100 / 1024/ 100).toString() 'Kbyte';
    var divInfo document.createElement('div');' ('+file.type+') - '+fileSize;

    var divProgN document.createElement('div');'progressNumber'+i;

    var prog document.createElement('progress');'progressValue'+i;


function upFile()
  while (fileQueue.length > 0) {
    var item=fileQueue.pop();

function onloadHandler() {
  if (typeof FileReader == "undefined") alert('Sorry, your browser does not support File API, so this demo will not work correctly');
  fileQueue new Array();

  uploadFile function (file, i) {
    var xhr new XMLHttpRequest(), upload xhr.upload, fd new FormData();
    fd.append('fUpload', file);

    function (evt) {
      if (evt.lengthComputable) {
        var percentComplete Math.round(evt.loaded * 100 /;

        document.getElementById('progressNumber'+i).innerHTML percentComplete.toString() '%';
        document.getElementById('progressValue'+i).value percentComplete;
      else {
        document.getElementById('progressNumber'+i).innerHTML 'Cannot calculate';
    }, false);
    upload.addEventListener('load'function (ev) {
      var c=document.getElementById('progressNumber'+i);
    }, false);
    upload.addEventListener('error'function (ev) {alert('An error occurred while trying to upload the file.');}, false);
    upload.addEventListener('abort'function (ev) {alert('The upload was cancelled by the user or the browser reset the connection.');}, false);'POST',window.location.href);
  dropZone.addEventListener('dragenter',  function(ev){
  }, false);
  dropZone.addEventListener('dragleave',  function(ev){
  }, false);
  dropZone.addEventListener('dragover',  function(ev){
  }, false);
  dropZone.addEventListener('drop',  function(ev){
  }, false);
<script language="Cache" method="OnPreHTTP" arguments="" returntype="%Boolean">
  #dim stream As %CSP.BinaryStream=%request.GetMimeData("fUpload")
  i $IsObject(stream{
    // make with the resulting file useful work
    ;s ^tmp($i(^tmp),"filename")=stream.FileName
    ;s ^tmp($i(^tmp),"filesize")=stream.Size
    q $$$NO
  q $$$YES