Question
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>
     
</form>

<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        
        FILE=$P(D,"\",L-1)
                
        DIR="F:\a misc\"
        ;
        FILENAM=$E(FILE,1,$L(FILE)-4)
        FILENAM=$ZSTRIP(FILENAM,"<>","W")
        
        DIR=DIR_FILENAM
        X=$ZF(-1,"MKDIR """_DIR_"""")
        DIR=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<
                >
            &html< <h>#(d)#</h> >
        }

Set Status = stream.SaveStream()
        If (Status = 1) {
            Write "<h2>Uploaded!</h2>"            
        }
        Else {
            Write "<h2>Saving failed!</h2>"
        }
             
}
        
    </script>
</csp:if>
</body>
</html>

 

00
3 0 4 546

Replies

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 <.. >

example:

&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

Peter

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>
  <html>
  <head>
    <title>Upload multiple files using XMLHttpRequest</title>

    <style type="text/css">
    .ok {
      color:green;
    }

    #dropZone {
      width: 360px;
      height: 125px;
      borderdashed 2px #ccc;
      background-color: #fefefe;
      color: #ccc;
      text-aligncenter;
      padding: 125px 0 0 0;
    }
  </style>
    
  </head>
<body onload="onloadHandler()">
<div id="dropZone">Drag and drop files here or use the button below</div>
<div>
  Select files
  <input type="file" id="fileToUpload" onchange="fileSelected(document.getElementById('fileToUpload').files)" multiple="multiple" />
</div>
<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()
{
  fileQueue=[];
  document.getElementById('holder').innerHTML='';
  document.getElementById('fileToUpload').value='';
}

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';
    else
      fileSize (Math.round(file.size * 100 / 1024/ 100).toString() 'Kbyte';
  
    var divInfo document.createElement('div');
    divInfo.innerHTML=file.name+' ('+file.type+') - '+fileSize;
    holder.appendChild(divInfo);

    var divProgN document.createElement('div');
    divProgN.id='progressNumber'+i;
    divProgN.innerHTML='%';
    holder.appendChild(divProgN);

    var prog document.createElement('progress');
    prog.id='progressValue'+i;
    prog.max='100.0';
    prog.value='0';
    holder.appendChild(prog);

    fileQueue.push({i:i,file:file});
  }
}

function upFile()
{
  while (fileQueue.length > 0) {
    var item=fileQueue.pop();
    uploadFile(item.file,item.i);
  }
}

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);

    upload.addEventListener('progress',
    function (evt) {
      if (evt.lengthComputable) {
        var percentComplete Math.round(evt.loaded * 100 / evt.total);

        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);
      c.className='ok';
      c.innerHTML='OK';
    }, 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);
    xhr.open('POST',window.location.href);
    xhr.setRequestHeader('Cache-Control''no-cache');
    xhr.setRequestHeader('X-Requested-With''XMLHttpRequest');
    xhr.send(fd);
  }
  
  dropZone=document.getElementById('dropZone');
  dropZone.addEventListener('dragenter',  function(ev){
    ev.stopPropagation();
    ev.preventDefault();
  }, false);
  dropZone.addEventListener('dragleave',  function(ev){
    ev.stopPropagation();
    ev.preventDefault();
    this.style['backgroundColor''#FEFEFE';
    this.style['borderColor''#CCC';
    this.style['color''#CCC';
  }, false);
  dropZone.addEventListener('dragover',  function(ev){
    ev.stopPropagation();
    ev.preventDefault();
    this.style['backgroundColor''#F0FCF0';
    this.style['borderColor''#3DD13F';
    this.style['color''#3DD13F';
  }, false);
  dropZone.addEventListener('drop',  function(ev){
  ev.stopPropagation();
  ev.preventDefault();
  this.style['backgroundColor''#FEFEFE';
  this.style['borderColor''#CCC';
  this.style['color''#CCC';
  fileSelected(ev.dataTransfer.files);
  }, false);
}
</script>
<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
</script>
</body>
</html>