3

I have an HTML form with text and checkbox inputs, and I want to to download this form data to a text file when I submit the form.

I found a solution to download data from a textbox into a text file, but I don't know how to modify it for the additional text and checkbox inputs that I require.

Here is my current code:

<html>
    <head>
        <script language="Javascript">
            function download(filename, text) {
                var pom = document.createElement('a');
                pom.setAttribute('href', 'data:text/plain;charset=utf-8,' +
                    encodeURIComponent(Notes));
                pom.setAttribute('download', filename);
                pom.style.display = 'none';
                document.body.appendChild(pom);
                pom.click();
                document.body.removeChild(pom);
            }
            function addTextTXT() {
                document.addtext.name.value = document.addtext.name.value + ".txt"
            }
        </script>
    </head>
    <body>
        <form name="addtext" onsubmit="download(this['name'].value, this[’Notes’].value)">
            Notes:<input type="text" name=“Note/Users/karlahaiat/Desktop/Copia de checklist.htmls”><br>
            Initials:<input type="text" name=“Initials”><br>
            <input type="checkbox" name=“check_list[]” value=“Check General Health”>
            <b>Check General Health.</b><br>
            <input type="checkbox" name=“check_list[]” value=“Check Fluid”>
            <b>Check Fluid.</b><br>
            <input type="text" name="name" value="" placeholder="File Name">
            <input type="submit" onClick="addTexttxt();" value="Save As TXT">
        </form>
    </body>
</html>

The form above shows the input fields I want in my form however the text file won't download. Any help understanding the syntax would be great!

Anshu
  • 1,277
  • 2
  • 13
  • 28
jamielov
  • 33
  • 3
  • How do you want the values to appear in the text field? You might want to check your HTML too; it's using "typographic quote marks" (curly quotes), which are not valid in HTML. – Heretic Monkey Jun 11 '19 at 23:38

2 Answers2

2

You code is fairly close to a working solution - consider making the following changes to your code (as shown in the snippet below):

  • avoid mixing " with the character in your HTML markup
  • ensure valid field names and avoid the name attribute of this form: name=“Note/Users/karlahaia..
  • consider using addEventListener() to bind event logic to your HTML, rather that using inline onclick, onsubmit, etc, as you currently are
  • also, consider setting up the form logic after the page has loaded via the DOMContentLoaded event. This ensures that form and input elements that your script depends on are present before your script attempts to access them

/* Run script after DOMContentLoaded event to ensure form element is 
present */
document.addEventListener("DOMContentLoaded", function() {
  /* Obtain form element via querySelector */
  const form = document.querySelector('form[name="addtext"]');

  /* Bind listener to forms submit event */
  form.addEventListener("submit", function(event) {
    /* Prevent browsers default submit and page-reload behavior */
    event.preventDefault();

    /* Obtain values from each field in form */
    const notes = form.querySelector('input[name="notes"]').value;
    const initials = form.querySelector('input[name="initials"]').value;
    const checkFluid = form.querySelector('input[name="check-fluid"]').checked;
    const checkHealth = form.querySelector('input[name="check-health"]').checked;
    const filename = form.querySelector('input[name="name"]').value + ".txt";

    /* Compose text file content */
    const text = `
    notes:${notes}
    initials:${initials}
    check health (checkbox):${checkHealth}
    check fluid (checkbox):${checkFluid}
    `;

    /* Create temporary link element and trigger file download  */
    const link = document.createElement("a");
    const href = "data:text/plain;charset=utf-8," + encodeURIComponent(text);
    link.setAttribute("href", href);
    link.setAttribute("download", filename);

    document.body.appendChild(link);

    link.click();

    document.body.removeChild(link);
  });
});
<!-- Ensure that the name attribute does not include invalid characters 
or nested "" which cause confusion-->
<form name="addtext">
  Notes:<input type="text" name="notes" /><br /> Initials:

  <input type="text" name="initials" /><br />

  <input type="checkbox" name="check-health" value="Check General Health" />
  <b>Check General Health.</b><br />

  <input type="checkbox" name="check-fluid" value="Check Fluid" />
  <b>Check Fluid.</b><br />

  <input type="text" name="name" value="" placeholder="File Name" />
  <input type="submit" value="Save As TXT" />
</form>

Hope that helps!

Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
0

Observations:

  1. Every HTML 5 valid document should have a doctype mentioned at the very beginning, like so: <!DOCTYPE html>

2. Your approach is good, but the click() method on anchors is deprecated in Firefox. So we have to manually dispatch the click event, on the hidden anchor containing the URLEncoded of our TXT file.

Quoted from https://stackoverflow.com/a/1421770/8896148

The click method is intended to be used with INPUT elements of type button, checkbox, radio, reset or submit. Gecko does not implement the click method on other elements that might be expected to respond to mouse–clicks such as links (A elements), nor will it necessarily fire the click event of other elements.

Non–Gecko DOMs may behave differently.

  1. The function name in onClick="addTexttxt()" was misspeled. It's addTextTXT(). JavaScript is case sensitive!

  2. Instead of directly calling the download(filename, text) function, we should call an intermediary function instead, which will have to collect all the data from your form, and make it into a nice text string. And then, we will pass that string to the download function to make it into a file ready for download.

  3. In onsubmit="someFunctionCall()" we should return false if we don't wish to navigate away from the page (or reload it). So we pas to onsubmit the value returned by someFunctionCall() by adding a return in front of the call: onsubmit="return someFunctionCall()". This way, we can decide inside the someFunctionCall() if we want to navigate away or not by returning true or false.

  4. Text descriptions for checkbox and radio should be placed inside <label for="idOfTheInput">, so the user can click on the text and the checkbox will still activate.

Here is the updated version

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <script language="Javascript" >

            function download(filename, text){

                var pom = document.createElement('a');
                pom.style.display = 'none';
                document.body.appendChild(pom);

                pom.setAttribute('download', filename);
                pom.setAttribute('href', 'data:text/plain;charset=utf-8,'
                    + encodeURIComponent(text));

                pom.click();
                document.body.removeChild(pom);

            }

            //- SIDE NOTE for addTextTXT()
            //- This function works as it is, but it's a little sketchy using
            //- document.addtext directly inside it. The input we want to check
            //- should be passed as a parameter, if in the future we wish to
            //- extend this code to work with multiple forms in the same page.
            //- It's good for now, though
            
            function addTextTXT(){

                //- You may as well do some field validation here, and rename this
                //- function validate()

                //- Check if the last 4 characters of filename are already ".txt" or ".TXT"
                //- or any other variation of lower-case and upper-case
                if(document.addtext.filename.value.substr(-4).toLowerCase() != ".txt"){
                    //- Append ".txt" if missing
                    document.addtext.filename.value += ".txt"
                }
            }

            //- This function collects all the data present inside the form
            //- formats it accordingly, and passes the entyre text content
            //- to the download() function above
            function downloadData(formElement){

                //- We start with an initially empty file content
                var text = "";

                //- We iterate over all the form's inputs
                for(var i=0; i<formElement.length; i++){
                    var input = formElement[i];
                    //- We discard the submit button and the filename field.
                    //- If you remove this if statement the file will contain
                    //- all the inputs.
                    if(input.type == "text" && input.name != "filename"){
                        //- We append to the file content the name of the fiend
                        //- and it's value in single quotes (i like to quote them
                        //- to spot empty fields or to easily debug them later)
                        //- We append after each value an epty line: \n
                        text += input.name + "='" + input.value + "'\n";
                    }else if(input.type =="checkbox"){
                        text += "[" + (input.checked ? "x" : " ") + "] " + input.name + "\n";
                    }
                }

                //- Now the text variable contains all the info, so we send it
                //- for downloading
                download(formElement.filename, text);


                //- If we wish, we prevent navigation or page reload by returning false
                return false;
            }


        </script>
    </head>
    <body>

        <form name="addtext" onsubmit="return downloadData(this);">

            Notes:<input type="text" name=“Notes” value=""><br>
            Initials:<input type="text" name=“Initials” value=""><br>

            <input type="checkbox" name="Check General Health"> <b>Check General Health.</b><br>
            <input type="checkbox" name="Check Fluid"> <b>Check Fluid.</b><br>

            <input type="text" name="filename" placeholder="File Name">
            <input type="submit" onClick="addTextTXT();" value="Save As TXT">

        </form>
    </body>
</html>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459