Question
· 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
Discussion (8)2
Log in or sign up to continue

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

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

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

	<button onclick="window.close()" style="width: 100px; height: 40px; font-size: 18px;"> Exit </button>
</form>

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.

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.

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>

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.