Question David Saunders · Aug 12

Need help with file upload.csp

I am trying to use upload.csp as a template for choosing a CDV file to process. I am calling it from a zen page using this:
<button caption="Import Client Consultation Extract" 
       controlStyle="width:500px; height:100px; font-size:1.5em;"
         onclick="zenPage.importExtract();"/>

ClientMethod importExtract() [ Language = javascript ]
{
    // Open CSP popup to upload the CSV
    //alert('importExtract called.');
    zenPage.launchPopupWindow(zenLink('Upload.CSP'),'Upload Client Consultation extract',
                              'status,scrollbars,resizable,width=750,height=250');
}

I have increased the size of the text and buttons and I have added code to process the contents of the selected file into a global that will be processed further in the next step. The only problem is, I can't get the code to call back to the parent zen page and close the popup. I also wanted to add an "Exit" button so the user can close the popup without choosing a file if needed for some reason. What I have developed isn't working.

I am hoping someone would take some time to look this over and give me some solutions.

Here is the upload.csp as I have altered it.

<!-- Copyright (c) 2001 InterSystems Inc. ALL RIGHTS RESERVED. -->
<csp:class description="Upload Client Consultations file.">
<html><head>
<H1>Upload Client Consultation extract file</H1>
</head><body bgcolor="#CCCCFF"><!-- HTML Form to submit the file. You must specify the enctype="multipart/form-data" -->
<!-- for this to work -->
<form enctype="multipart/form-data" method="post" action="upload.csp" style="font-size: 20px">
Choose Client Consultation file: <input type=file size=30 name=FileStream style="width: 500px; height: 40px; font-size:18px;">
<style="font-size: 20px;">
<ul>
  <input type="submit" value="Upload file" style="width: 100px; height: 40px; font-size: 18px;">
  <button onclick="exitPopup();" style="width: 100px; height: 40px; font-size: 18px;"> Exit </button>
</ul>
<p>
</form><!-- As form is submitted to this page look to see if we have the stream in the %request object -->
<csp:if condition='($data(%request.MimeData("FileStream",1)))'>
<ul>
<script language="Cache" runat="server">
&js<alert('Choose file click');>
New bytes,lc
Set bytes=%request.MimeData("FileStream",1).Read()
Set bytes=##class(%CSP.Utils).DecodeData(bytes)
If $Data(^G2W.Import("UploadedCSV")) Kill ^G2W.Import("UploadedCSV")
For lc=1:1:$L(bytes,"_$c(13,10)_") {
Set D=$TR($Piece(bytes,"_$c(13,10)_",lc),$C(187,191,239))
Set ^G2W.Import("UploadedCSV",lc)=$ZCONVERT(D, "I", "HTML")
}
</script>
</ul>
</csp:if>
</body>
<script language = "JavaScript" >
 function exitPopup() {
alert('Made it to exitPopup');
opener.processImport();
window.close();
}
</script>
</html>
 

I do realize this is to choose a file on the client side (my laptop). This is what I want. The file will not be on the server (my desktop).

Thank you for your time.

Product version: Caché 2018.1
$ZV: Cache for Windows (x86-64) 2018.1.7 (Build 721) Fri Mar 18 2022 22:24:36 EDT

Comments

Robert Cemper · Aug 12

Due to limited practice in ZEN I transferred your example to straight CSP and JS

<html><head><title>Demo for David</title><scriptlanguage="JavaScript"type="text/javascript">functionimportExtract()
{
	var url='upload.csp' ;
	var options = 'popup,status=yes,scrollbars=yes,resizable=yes,width=750,height=250' ;
	newwindow=window.open(url,'UPLOAD',options);
    newwindow.focus();
	alert('back');
	}
</script></head><body><h3>Demo for David</h3><Inputtype="button"value="Import Client Consultation Extract"onclick="importExtract();"/></body></html>

in upload.csp I just added this BUTTON to the end ot the main form

<buttononclick="window.close()"style="width: 100px; height: 40px; font-size: 18px;"> Exit </button></form>
0
David Saunders  Aug 15 to Robert Cemper

Hey Robert, Thanks for the reply. I did add an Exit button as you suggest, mostly to test window.close() function to close the window, and it does not close the window. I have used this function in the past to close windows and it usually works. But for some reason is not working in this case. I am not sure what is going on here, but that is why I posted it because it is unusual that it is not working.

0
Robert Cemper  Aug 15 to David Saunders

Strange.
Did you try to load 'upload.csp' directly and just isolated? 
window.close() is the most basic function in JS in any browser.
If that fails, your browser might have a problem.
Do you run some sick PopUp blocker or similar in your browser?

0
David Saunders  Aug 15 to Robert Cemper

Yes, I have launched by pressing Web icon in Studio while upload.csp was in focus. But I have also tried by launching the popup using the button on my zen page.

0
David Saunders  Aug 15 to David Saunders

Robert, not sure why it occured to me just now,  but I decided to create a HelloWorld CSP page with an Exit button. It's very simple. I compiled it and then opened it directly. I then clicked the Exit button and it displayed the alert and then closed. I put the script between the upper HTML tag and the HEAD tag in my HelloWorld CSP. So I moved the Script in my upload.csp to between those tags. I am getting the alert for ExitPopup but then I ma also getting the alert for Choose file clicked and the window is not closing. So there is something with CSP script stuff. I am not really very familiar with the CSP Script stuff. So if you have any ideas I would love to hear them. At least I am getting a bit closer.

0
Robert Cemper  Aug 15 to David Saunders

Just as you, I start my CSP also from good old Studio

the EXIT button is inside <bod>y<form> ....<button>..   </form></body>
in upload
 

<!-- Copyright (c) 2001 InterSystems Inc. ALL RIGHTS RESERVED. -->
<csp:class description="Demo of how to upload a file from the browser.">
<html>

<head>
</head>

<body bgcolor="#CCCCFF">

<!-- display standard sample template using a custom tag -->
<isc:SAMPLE title="Upload a file Sample">
This sample uses an '&lt;input type=file&gt;' element in a form to upload a file
from the web browser to CSP. Pick a file and hit the submit button to try it.
</isc:SAMPLE>

<!-- HTML Form to submit the file. You must specify the enctype="multipart/form-data" -->
<!-- for this to work -->
<form enctype="multipart/form-data" method="post" action="upload.csp">
	Enter a file to upload here: <input type=file size=30 name=FileStream>
	<p>
	<ul><input type="submit" value="Upload file"></ul>
	<p>
	<button onclick="window.close()" style="width: 100px; height: 40px; font-size: 18px;"> Exit </button>
</form>

<!-- As form is submitted to this page look to see if we have the stream in the %request object -->
<csp:if condition='($data(%request.MimeData("FileStream",1)))'>
	<hr><br>
	Submitted filename: <b>#(..EscapeHTML(%request.MimeData("FileStream",1).FileName))#</b><br>
	Size of file: <b>#(..EscapeHTML(%request.MimeData("FileStream",1).Size))#</b><br>
	Mime Section: <b>#(..EscapeHTML(%request.MimeData("FileStream",1).MimeSection))#</b><br>
	Type of stream: <b>#(..EscapeHTML($classname(%request.MimeData("FileStream",1))))#</b><br>
	Content Type: <b>#(..EscapeHTML(%request.MimeData("FileStream",1).ContentType))#</b><br>
	<br>
	First 200 characters of stream:<br>
	<ul>
	<script language="Cache" runat="server">
		New bytes
		Set bytes=%request.MimeData("FileStream",1).Read(200)
		Set bytes=##class(%CSP.Utils).DecodeData(bytes)
		Write bytes,!
	</script>
	</ul>
</csp:if>

</body>
</html>

while your calling JS script is best located in <head>......</head>

<html>
<head>
<title>Demo for David</title>
<script language="JavaScript" type="text/javascript">
function importExtract()
{
	var url='upload.csp' ;
	var options = 'popup,status=yes,scrollbars=yes,resizable=yes,width=750,height=250' ;
	newwindow=window.open(url,'UPLOAD',options);
    newwindow.focus();
	alert('back');
	}
</script>
</head>
<body>
<h3>Demo for David</h3>
<Input type="button" value="Import Client Consultation Extract"
         onclick="importExtract();"/>
</body>
</html>
0
David Saunders  Aug 19 to Robert Cemper

Robert, I finally got this figured out. I posted my complete solution. I use a Zen Page and a Zen standard Dialog.

Thanks for your time

0
David Saunders · Aug 19

I appreciate all the advice I received from members on this post. I want to let all of you know that I finally got it working, including closing the popup. I spent a ton of time working on this. I wanted to share the final solution.

I am going to post a generic resolution that I think anyone would be able to make use of.

The solution involves using 2 different Zen pages. The parent, which I will name Demo.PopupFileSelectorMain, and the page, or really a defined Zen standardDialog page, which I will name Demo.PopupFileSelector. 

/// Created using the page template: Title Page
Class Demo.PopupFileSelectorMain Extends %ZEN.Component.page
{/// Class name of application this page belongs to.
Parameter APPLICATION;/// Displayed name of this page.
Parameter PAGENAME;/// Domain used for localization.
Parameter DOMAIN;/// This Style block contains page-specific CSS style definitions.
XData Style
{
<style type="text/css">
/* style for title bar */
#title {
background#C5D6D6;
colorblack;
font-familyVerdana;
font-size3em;
font-weightbold;
padding5px;
border-bottom1px solid black;
text-aligncenter;
}
/* style for main form buttons */
#mfbutton{
width500px;
height100px;
font-size1.5em;
}
</style>
}/// This XML block defines the contents of this page.
XData Contents [ XMLNamespace = "http://www.intersystems.com/zen]
{
<page xmlns="http://www.intersystems.com/zentitle="Demo Popup File Selector">
<html containerStyle="height:100px;" id="title">Demo Popup File Selector</html>
<hgroup width="100%">
<button caption="Import Demo File" 
       controlStyle="width:500px; height:100px; font-size:1.5em;"
         onclick="zenPage.showFileSelectDialog();"/>
</hgroup>
</page>
}ClientMethod showFileSelectDialog() [ Language = javascript ]
{
    // You can customize the 'Dir' (default directory) and 'wildcard' (file filter) parameters
    var defDir "C:\\"; // Start in the default manager directory or specify a path like "C:\\temp"
    var wildcard "*.csv, *.txt"; // Filter for text files
    zenLaunchPopupWindow('Demo.PopupFileSelector.cls', 'Test Popup', 'center=yes,resizable=no,width=400,height=250');
}ClientMethod onPopupAction(popupName, action, value) [ Language = javascript ]
{
    
    console.log('Popup dialog returned:\n popupName = '+popupName+'\n action = "'+action+'"\n value = '+value);
    if (value == 'importData') {
        //zenSetProp('messageLabel', 'value', 'Dialog returned: ' + value);
console.log('Made it to onPopupAction:\n value = '+value);
zenPage.ProcessFileContent();
    }
}ClassMethod ProcessFileContent() [ ZenMethod ]
{Set ^UT("Demo.PopupFileSelectorMain","ProcessFileContent")=$H
Write "Made it to frmMain:ProcessFileContent"Quit
}}
 

/// Created using the page template: Default
Class Demo.PopupFileSelector Extends %ZEN.Dialog.standardDialog
{/// This XML block defines the contents of this page.
XData dialogBody [ XMLNamespace = "http://www.intersystems.com/zen]
{
<pane title="Choose File">
<label value="Choose a file: "/>
<fileUpload id="chosenFile" accept=".csv,.txt" onchange="zenPage.uploadFile();"/>
</pane>
}/// Override to handle the OK button.
ClientMethod getDialogValue() [ Language = javascript ]
{
return "importData";
}/// Override to provide the dialog title.
Method %DrawTitle(pSeed As %String) As %Status
{
Write "<H1><Center>Choose a Client Consultation file.</Center></H1>"
Quit $$$OK
}ClientMethod uploadFile() [ Language = javascript ]
{
    // Get the file upload component
    console.clear();
    console.log('made it to uploadFile');
    var fileUpload zenPage.getComponentById('chosenFile');     // Get the selected file
    //var file = fileUpload.getValue(); // This will return the file object
    var file event.target.files[0];
console.log('file = ',file);     // Check if a file is actually selected
    if (file) {
    console.log('About to read file into string');
        // If the file is small and you only need the text content
        var reader new FileReader();         reader.onload function(e) {
// You can then process the fileContent as needed
            zenPage.ProcessFileContent(e.target.result); // Pass content as a string
console.log("File content:", e.target.result);
};reader.onerror function(e) {
console.error("Error reading file:", event.target.error);
};
  
        reader.readAsText(file); // Read as text
}
}ClassMethod ProcessFileContent(pContent As %String) As %Status [ ZenMethod ]
{
    // Process pContent on the server
&js<console.log('ProcessFileContent');>
Write "ProcessFileContent: pContent = "_pContent
Set ^UT("Demo.PopupFileSelector","ProcessFileContent","$IO")=$IO
Set ^UT("Demo.PopupFileSelector","ProcessFileContent","pContent")=pContent
    Quit $$$OK
}}
 

My hope is that someone finds this usefull.

0