You are viewing limited content. For full access, please sign in.

Question

Question

How-To Create a Download File (Text/CSV) Button

asked on January 8, 2017

This was tricky to get working, so once I did, I wanted to share with everyone, in case anyone else could benefit.

I have a Multi-Line field on my form that is populated by Javascript with text formatted as comma-separated values.  The user can copy-paste the contents of the Multi-Line field into a text editor, save it as a CSV file, and then import that file into another software program for processing.  This works great, but I wanted to simplify it even more if I could.

So I added a button to my form that the user can click which will automatically create and download the CSV file.  Here's how to do it.

By the way, this isn't supported by all browsers (for example - IE 11 doesn't support but Chrome 55 does) - the code will warn the end user if it isn't supported in their current browser and recommends them to try Chrome instead.  For cross-compatibility, I had to leave the text field accessible to the user in addition to the button - so the button isn't a solution by itself, just an added feature.

2 0

Answer

SELECTED ANSWER
replied on January 8, 2017 Show version history

Add your button to your form as a custom HTML element - with a CSS Class of downloadCSVFileButton.

<button id="download-csv">Download CSV File</button>

 

And include this Javascript on your form.

$(document).ready(function () {

  //processes when the Download CSV File button is clicked.  If the browser can handle the
  //download archor attribute, the contents of the posting file Multi-Line field will be
  //downloaded in a csv file, if the browser can't handle the attribute, the user will be
  //alerted and recommended to try another browser
  $('.downloadCSVFileButton').click(function () {
    var textFile = $('.postingFile textarea').val();
    var element = document.createElement('a');
    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(textFile));
    element.setAttribute('download', 'filename.csv');
    element.style.display = 'none';
    if (typeof element.download != "undefined") {
      //browser has support - process the download
      document.body.appendChild(element);
      element.click();
      document.body.removeChild(element);
    }
    else {
      //browser does not support - alert the user
      alert('This functionality is not supported by the current browser, recommend trying with Google Chrome instead.  (http://caniuse.com/#feat=download)');
    } //end of if...else...block
  }); //end of $('.downloadCSVFileButton').click(function () {

}); //end of $(document).ready(function () {

The actual download is processed by an anchor element (<a>) not by the button.  The button creates the anchor element, adds it to the form, clicks it, and then removes it from the form.

0 0
replied on August 28, 2018

This is super. I love it.

I am incredible bad at scripting and coding.

Can't even get the button to work haha.

Can I request some friendly assistance please?

Capture.PNG
Capture.PNG (50.2 KB)
0 0
replied on August 28, 2018

Let's see that field's formula please?

0 0
replied on August 28, 2018 Show version history

Hello @████████

Looking at your screenshot, you have the HTML button put in to the CSS script section.  So remove it from there.  Go to the Layout page, add a custom HTML element, and add that code under the HTML tab.

Now go back to the CSS & Javascript page and populate the Javascript from my earlier post.

Note, that Javascript code is looking for a multi-line field which has CSS Class Name of "postingFile" - but looking at your screenshot, you don't appear to have that.

If you are actually trying to create the CSV file from the contents of the fields in your table, that is doable as well, but the Javascript will take tweaking.

1 0
replied on August 28, 2018

Hi Matthew.

Okay thank you for clarifying that for me. I went Workflow C# script route where I luckily had a shell for the export to CSV function.

I however have a need to do this via Forms and would like a quick user friendly button that downloads the table of contents locally in C:\Users\Downloads.

Could you point me to some resources online that can guide me through scripting JavaScript for a table of contents download please?

I noticed you stated you are exporting a multi-line field and not a table.

Thank you for the help and clarification.

0 0
replied on August 28, 2018

OK I have some progress.

I implemented your JavaScript and the button successfully and made a test multi line field's CSS "postingFile". However when I click the button it simply refreshes the page/moves on in the test process.

I'm missing something here.

0 0
replied on August 31, 2018

You changed some of the Javascript code...

Line #7 of your Javascript says:

$('.Download CSV File').click(function() {

In my example, it says:

$('.downloadCSVFileButton').click(function () {

You also need to add downloadCSVFileButton as the CSS Class name for the button (you can do that on the Layout page).

Alternately, you can trigger the button by its HTML ID instead of the CSS class name, like this: 

$('#download-csv').click(function() {

You could do that in the Javascript, and not bother with the CSS Class Name on the Layout page at all.

The code starting on line #7 (and running through the close brackets on line #23) is telling it what to do when the button is clicked.  But that only works if we have a matching HTML ID or CSS Class Name.

The syntax of "$('.Download CSV File')" doesn't really do anything.  The period tells it that Download is the CSS Class Name (as opposed to # which tells it is an HTML ID).  But then the spacing before CSV and File makes it look for tags in your DOM structure beneath the Download class called CSV and then beneath that called File.  Those aren't standard parts of the DOM structure, so it doesn't do anything, that code is never called. 

0 0
replied on November 8, 2018

Hi Matthew, is there any chance you could point me some resource that can help me export to CSV from the Form?

I want to export my data in a table to CSV.

So I am back and I have learned a lot of new stuff and feel a bit more confident to attempt this.

I will try to find some JavaScript online, but I have seen that Laserfiche Forms's JavaScript and regular JavaScript used in VSC or such is slightly different (correct me if I am wrong).

Any help resource would be appreciated.

Capture.PNG
Capture.PNG (79.83 KB)
0 0
replied on November 8, 2018

Hey there @████████- I have found that using sources outside of this site is good for little snippets of code, as long as you try to focus on JQuery whenever possible, and as long as you accept that LFForms is doing most of the work setting up your structure.  So you can't just take a whole segment of code that includes setting up your DOM and scripting structure, because LFForms has done that already - and any code impacting the DOM has to be tweaked as well, since LFForms is likely not structuring the DOM the same way that other sites are - but for learning how to code something in JS that you've never done before, and learning more about how JS actually operates - I do a lot of research through other sources.

0 0
replied on November 8, 2018 Show version history

Downloading the contents of a table to a CSV file will be similar to exporting the Multi-Line field as I demonstrated in the original post.  Here's the basic set-up.

Step 1 - Add the export button as a Custom HTML element, with a field ID of exportReportButton.  This code will also display the button at the far-right: 

<div style="text-align: right;"><span style="color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-ligatures: inherit; font-variant-caps: inherit; font-weight: inherit;"><button type="button" id="exportReportButton">Export Report as CSV</button></span></div>

Step 2 - Add a table, give the table the CSS Class Name of reportTable.

Step 3 - Add five fields to your table, give them CSS Class Names of field1, field2, field3, field4, field5.

Step 4 - Add this Javascript to your form:
(***EDIT: This code surrounds each value in the CSV file with quotes - if you don't want that for certain values like numbers, you can remove those on rows 10 through 14 by replacing this (   ',"' +   ) with this (   ',' +   ) and by replacing this (   .val() + '"';   ) with this (   .val();   ) - basically just adding a comma before the value and nothing after it.***)

$(document).ready(function () {

  //When the export report button is clicked, download what is shown in the report as 
  //a CSV file.  The lastValue tracking helps ensures that no row is recorded more than once.
  $('#exportReportButton').on('click', function() { 
    var theReport = 'Field 1,Field 2,Field 3,Field 4,Field 5'; 
    var lastValue = 0; 
    $('.reportTable .field1 input').each(function() { 
      if ($(this).closest('ul').find('.field1 input').val() != lastValue) { 
        var theRow = '"' + $(this).closest('ul').find('.field1 input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.field2 input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.field3 input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.field4 input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.field5 input').val() + '"'; 
        theReport = theReport + '\n' + theRow; 
        lastValue = $(this).closest('ul').find('.field1 input').val(); 
      }
    });
    var element = document.createElement('a');
    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(theReport));
    element.setAttribute('download', 'sample-report.csv');
    element.style.display = 'none';
    if (typeof element.download != "undefined") {
      document.body.appendChild(element);
      element.click();
      document.body.removeChild(element);
    }
    else {
      alert('This functionality is not supported by the current browser, recommend trying with Google Chrome instead.  (http://caniuse.com/#feat=download)');
    }
  });

});

Step 5 - Fill out some data in your table, either via lookups or user entry, and try out the export button.

Step 6 - Do a happy dance.

0 0
replied on November 11, 2018

Thank you the very precise step-by-step explanation of how to achieve this.

This is absolutely perfect. I need to compensate for commas in my values etc, but that stuff I can figure out by myself. It almost feels slightly overwhelming starting to use JavaScript on my custom Forms.

There is a vast amount to take in to consideration when it comes to JS, and other external resources. Like data types in SQL as an example - Something that seems arbitrary when starting.

Questions tend to pop up and always being able to successfully script whatever the requirements are involves a large series of questions that go through my head;

Will this JS work on a mobile device?

What if I have to add new variables due to customer requests?

How will the JS be affected on new software versions of LFForms?

And then, where do I get started if I want to achieve a completely different goal?

(Technically speaking, you know? Literally coding to its core. What powerful information source can I reference that will assist me in learning to use JS on LFForms? The JS used is different from normal JS, like you said, with the DOM structure already compensating for some of the stuff you would normally have to setup when starting from scratch).

Anyway, you have helped me greatly @████████I very much appreciate your input. I have successfully generated the CSV and it is almost in the right format as requested by the customer.

Cheers!

0 0
replied on November 13, 2018

I'm glad to help @████████.

You shouldn't have to do anything with commas in your values if you are using the code exactly as I provided, because it is surrounding each value with quotation marks, so it shouldn't be thrown off by commas in the values.

0 0
replied on April 4, 2019

@████████ I've tested out your provided code and I'm only getting the first row to export. Is the code you provided supposed to export the entire table or is it supposed to export the first row only?

 

0 0
replied on April 4, 2019

@████████ - That code is exporting from a multi-line field, not from a table.

I think I have some code for exporting from a table, let me check.

0 0
replied on April 4, 2019

@████████- here's some code to download a table as a CSV.

This assumes a couple things:

  1. Your table has a CSS Class name of: reportTable.
  2. Your table contains a column of numbers, which are unique for each row, and has a CSS Class name of: rowNumber.
  3. Your table contains four other columns of data (I used Single Value fields) with CSS Class names of: columnB, columnC, columnD, and columnE.
  4. The code is written so that the four columns of data are wrapped in quotes, so it should allow commas and other characters in the data.

 

Here's the Javascript: 

$(document).ready(function () {

  //when the export report button is clicked, download what is shown in the table as 
  //a CSV file the lastValue tracking helps ensures that no row is recorded twice
  $('.downloadCSVFileButton').click(function () { 
    var theReport = 'rowNumber,columnB,columnC,columnD,columnE'; 
    var lastValue = 0; 
    $('.reportTable .rowNumber input').each(function() { 
      if ($(this).closest('ul').find('.rowNumber input').val() != lastValue) { 
        var theRow = $(this).closest('ul').find('.rowNumber input').val(); 
        theRow = theRow + ',"' + $(this).closest('ul').find('.columnB input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.columnC input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.columnD input').val() + '"'; 
        theRow = theRow + ',"' + $(this).closest('ul').find('.columnE input').val() + '"'; 
        theReport = theReport + '\n' + theRow; 
        lastValue = $(this).closest('ul').find('.rowNumber input').val(); 
      }
    });
    var element = document.createElement('a');
    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(theReport));
    element.setAttribute('download', 'Report-Download.csv');
    element.style.display = 'none';
    if (typeof element.download != "undefined") {
      document.body.appendChild(element);
      element.click();
      document.body.removeChild(element);
    }
    else {
      alert('This functionality is not supported by the current browser, recommend trying with Google Chrome instead.  (http://caniuse.com/#feat=download)');
    }
  });
  
});

 

0 0
replied on April 4, 2019

@████████ Thank you for your response. I tried it this way as well and it only exports the the first row and nothing else after. Is there something I'm missing?

The table is being filled by lookup rules, including the rowNumber.

0 0
replied on April 4, 2019 Show version history

You know what, I'm sorry, this code is for a Collection not a Table, they have slightly different structures.

I don't have time to test this right now, so I'm not 100% on it, but give this a try:

All the places where it says:   .closest('ul')

try changing them to say:   .closest('tr')

1 0
replied on April 4, 2019

@████████ That did it, works like a charm! Thank you for your help!

1 0
replied on April 4, 2019

So glad it worked for you @████████

0 0

Replies

You are not allowed to reply in this post.
You are not allowed to follow up in this post.

Sign in to reply to this post.