This is a quick article on generating a file with the Zoho Deluge function .toFile() and uploading it to a file upload field within Zoho Creator.
Why?
The use-case here is that we want a file to be hosted within Zoho Creator for use by a JS widget that will download the CSV (in this case a Text *.txt) file for use by a dynamic auto-suggester dropdown; one of those fancy ones that includes photos and a bit of fuzzy logic.
I thought I could simply update the field with the new file but as I'm not downloading it, this is apparently not the process.
How?
As a high-level overview: we'll generate the CSV rows and then a file; then we'll use invokeURL to upload the file.
Generating the CSV
Here's the simplified code to generate the CSV - note that I am replacing commas with the HTML entity equivalent and enclosing the ID in double-quotes in case I open it in MS Excel or another system that likes rounding 64-bit signed integers (long numbers):
// // Generate a CSV of a Report in ZohoCreator l_CsvLines = List(); l_ApplicableProducts = Products[Display_in_Widget=="Yes"] sort by Product_Name; for each c_Product in l_ApplicableProducts { l_CsvRow = List(); l_CsvRow.add(c_Product.Photo); l_CsvRow.add(c_Product.Product_Name.replaceAll(",", ",", true)); l_CsvRow.add(c_Product.Product_Desc.replaceAll(",", ",", true)); l_CsvRow.add("\"" + c_Product.ID + "\""); l_CsvLines.add(l_CsvRow.toString()); }
- //
- // Generate a CSV of a Report in ZohoCreator
- l_CsvLines = List();
- l_ApplicableProducts = Products[Display_in_Widget=="Yes"] sort by Product_Name;
- for each c_Product in l_ApplicableProducts
- {
- l_CsvRow = List();
- l_CsvRow.add(c_Product.Photo);
- l_CsvRow.add(c_Product.Product_Name.replaceAll(",", ",", true));
- l_CsvRow.add(c_Product.Product_Desc.replaceAll(",", ",", true));
- l_CsvRow.add("\"" + c_Product.ID + "\"");
- l_CsvLines.add(l_CsvRow.toString());
- }
Generate the file
You may note that this generates a text file rather than a CSV, this is because our JS widget won't pack a CSV but it will pack text files.
// // generate a CSV or TXT v_CSVFilename = "applicable_products.txt"; f_CSVFile = l_CsvLines.toString(zoho.encryption.urlDecode("%0A")).toFile(v_CSVFilename); f_CSVFile.setParamName("file");
- //
- // generate a CSV or TXT
- v_CSVFilename = "applicable_products.txt";
- f_CSVFile = l_CsvLines.toString(zoho.encryption.urlDecode("%0A")).toFile(v_CSVFilename);
- f_CSVFile.setParamName("file");
Get current file name (optional)
To check on filename changes, I run this bit of code to get the internal and current file name:
// // get original document file (optional) - you need your own record ID here v_ZC_DocumentRecordID = 1234567890123456789; c_ExistingDocument = Document[ID == v_ZC_DocumentRecordID]; info c_ExistingDocument.Document_File;
- //
- // get original document file (optional) - you need your own record ID here
- v_ZC_DocumentRecordID = 1234567890123456789;
- c_ExistingDocument = Document[ID == v_ZC_DocumentRecordID];
- info c_ExistingDocument.Document_File;
Upload the generated file to the record
Note that this is overwriting the existing record and associated file. We have no intention of creating a new record per file... Saying that, the file name will change every time it is updated as you will see. Also note, I have a form called "Document", a report called "All Documents", and the file upload field is called "Document File":
// // now upload updated file v_Endpoint = "https://creator.zoho.com/api/v2.1"+zoho.appuri+"report/All_Documents/"+v_ZC_DocumentRecordID+"/Document_File/upload"; r_Upload = invokeurl [ url :v_Endpoint type :POST files: f_CSVFile connection:"zcreator" ]; info r_Upload;
- //
- // now upload updated file
- v_Endpoint = "https://creator.zoho.com/api/v2.1"+zoho.appuri+"report/All_Documents/"+v_ZC_DocumentRecordID+"/Document_File/upload";
- r_Upload = invokeUrl
- [
- url :v_Endpoint
- type :POST
- files: f_CSVFile
- connection:"zcreator"
- ];
- info r_Upload;
Display new file name (optional)
// // get updated document file (optional: integrity check) c_ExistingDocument = Document[ID == v_ZC_DocumentRecordID]; info c_ExistingDocument.Document_File;
- //
- // get updated document file (optional: integrity check)
- c_ExistingDocument = Document[ID == v_ZC_DocumentRecordID];
- info c_ExistingDocument.Document_File;
I have all of the above in the same function. I've split it out to explain parts but otherwise it is intended to be all in the same function as there are references to some variables in earlier snippets of code on this page.
Error(s):
2945: UPLOAD_RULE_NOT_CONFIGURED
Was happening when I was trying to update the Zoho Creator record, specifically the file upload field, with the file object directly, eg. <collection>.<field>=<file_object>.