Warm tip: This article is reproduced from stackoverflow.com, please click
html javascript yaml

How can i apply stringify on the data which has been input by the user in an html form?

发布于 2020-03-27 15:41:57

I have built an app using html,js and css. The output of the web app is a text or yaml file. I am inputing the data and trying to gather in a yaml file. The code is given below:- For instance, I want the 'PDU' data in the downloaded file to be like this

PDU: PDU_IP: 10.235.250.49 (this is just a sample IP)

While I am trying to do this, its showing [object Object]. I tried to use stringify to convert object to string but failed in realizing the following funcionality. can anyone please help me in formatting the downloaded data. Basically i want the data to be in the format as it is there in a YAML file.

document.addEventListener('DOMContentLoaded', function() {
  const extra = {};

  const oForm = document.forms.myForm;
  const oSave = document.querySelector('input[name="save"]');
  const oSub = document.querySelector('input[name="submit"]');
  const oCtrl = document.querySelector('select[name="controller"]');
  const oTest = document.querySelector('select[name="test"]');
  const oProto = document.querySelector('select[name="protocol"]');
  const oTmp = document.querySelector('template');


  const changehandler = function(e) {
    let option = this.options[this.options.selectedIndex];

    if (option.hasAttribute('data-extra')) extra[this.name] = this.value;
    else {
      if (extra.hasOwnProperty(this.name)) delete extra[this.name];
    }

    if (Object.keys(extra).length == 2) {
      let fieldset = oTmp.content.cloneNode(true);
      oForm.insertBefore(fieldset, oProto.parentNode.nextSibling)
    } else {
      if (document.getElementById('extra')) {
        fieldset = document.getElementById('extra')
        fieldset.parentNode.removeChild(fieldset);
      }
    }

    if (option.hasAttribute('data-extra')) extra[this.name] = this.value;
    else {
      if (extra.hasOwnProperty(this.name)) delete extra[this.name];
    }


    if (this.name == 'controller') {
      if (this.value == 'RAID') oProto.disabled = false
      else oProto.disabled = true
    }
  }



  const dialog = function(msg) {
    alert(msg);
    return false;
  }




  const savehandler = function(e) {
    e.preventDefault();
    let valid = true;

    /*[ 'name','email','test','controller','ip','chassis' ].forEach( n => {
    	oForm[ n ].classList.remove('invalid');
    	if( oForm[ n ].value=='' ){
    		oForm[ n ].classList.add('invalid');
    		valid=false; 
    	}
    });*/
    if (!valid) return dialog('Please fill all the fields!');



    const ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
    if (ipformat.test(oForm.ip.value) == false) {
      return dialog('Invalid IP Address');
    }



    let data = {
      "PDU": {
        "PDU TEST": oForm.test.value,
        "PDU_IP": oForm.ip.value
      },
      'Product Type': oForm.controller.value,
      'Protocol Type': oForm.protocol.value,
      'Chasis Inputs': oForm.chassis.value
    };
    var datastr = JSON.stringify(data);

    if (Object.keys(extra).length == 2) {
      data[' - 	#Controller_ID_A'] = oForm['Controller-ID1'].value;
      data['		 HBA_Ports_A'] = [oForm['hba-ports1'].value];
      data['		 MC_IP_A'] = oForm['extra-ip1'].value;
      data['		 MC_Netmask_A'] = oForm['netmask-ip1'].value;
      data['		 MC_Gateway_A'] = oForm['gateway-ip1'].value;
      data['		 MC_A'] = oForm['rbod-mc1'].value;
      data['		 SC_A'] = oForm['rbod-sc1'].value;
      data['		 FU_A'] = oForm['rbod-fu1'].value;
      data['		 EC_A'] = oForm['rbod-ec1'].value;


    }


    if (Object.keys(extra).length == 2) {
      data[' - 	#Controller_ID'] = oForm['Controller-ID'].value;
      data['		  HBA_Ports'] = [oForm['hba-ports'].value];
      data['		  MC_IP'] = oForm['extra-ip'].value;
      data['		  MC_Netmask'] = oForm['netmask-ip'].value;
      data['		  MC_Gateway'] = oForm['gateway-ip'].value;
      data['		  MC'] = oForm['rbod-mc'].value;
      data['		  SC'] = oForm['rbod-sc'].value;
      data['		  FU'] = oForm['rbod-fu'].value;
      data['		  EC'] = oForm['rbod-ec'].value;


    }



    let payload = Object.keys(data).map(key => {
      return [key, data[key]].join(': ')
    }).join(String.fromCharCode(10));


    const blob = new Blob([payload], {
      type: 'text/plain'
    });
    const file = 'formData.yaml';

    let link = document.createElement('a');
    link.download = file;

    if (window.webkitURL != null) {
      link.href = window.webkitURL.createObjectURL(blob);
    } else {
      link.href = window.URL.createObjectURL(blob);
      link.style.display = "none";
      document.body.appendChild(link);
    }
    link.click();
  }


  oCtrl.addEventListener('change', changehandler);
  oTest.addEventListener('change', changehandler);
  oSave.addEventListener('click', savehandler);
})
<!DOCTYPE html>
<html>

<head>
  <title>Save form Data in a Text File using JavaScript</title>
  <h1>User Information </h1>
  <style>
    html,
    html * {
      box-sizing: border-box;
      border-color: teal;
      font-family: calibri;
    }
    
    html {
      background: radial-gradient(rgba(48, 97, 97, 0.5), rgba(255, 255, 255, 0.5))
    }
    
    input[type=button],
    input[type=submit] {
      padding: 1rem;
    }
    
    input[type=text],
    textarea,
    select {
      font: 17px Calibri;
      width: 100%;
      padding: 12px;
      border: 1px solid rgb(19, 18, 18);
      border-radius: 4px;
      color: teal
    }
    
    fieldset {
      border: none;
      padding: 10px;
      overflow: hidden;
      color: rgb(16, 8, 32);
      font-size: 25px;
      font-style: initial;
      font-family: 'Times New Roman', Times, serif;
    }
    
    #extra {
      border: 2px solid black;
      background: whitesmoke;
      border-radius: 1rem;
      box-shadow: 0 0 5px black;
      width: calc(100% - 24px);
      margin: auto;
      float: none;
      clear: both;
      text-indent: 50px;
    }
    
    #extra h6 {
      margin: 0
    }
    
    #extra style .invalid {
      border: 2px solid red!important;
      background: rgba(255, 0, 0, 0.1)
    }
  </style>
  <script src="script.js"></script>
</head>

<body>

  <template>
			<fieldset id='extra'>
				<h6>Additional Details Required</h6>
				<label for='Controller_ID_A'>Controller_ID:</label>
					<select name='Controller-ID1' required>
					<option value=""> - Select the Controller ID - </option>
					<option value='A'>A </select>
				<label for='HBA_Ports_A'>HBA_Ports:</label><input type='text' name='hba-ports1' placeholder='Enter the HBA Ports' /> 
				<label for='MC_IP_A'>MC_IP:</label><input type='text' name='extra-ip1' placeholder='Enter the MC_IP' /> 
				<label for='MC_Netmask_A'>MC_Netmask:</label><input type='text' name='netmask-ip1' placeholder='Enter the MC_Netmask' /> 
				<label for='MC_Gateway_A'>MC_Gateway:</label><input type='text' name='gateway-ip1' placeholder='Enter the MC_Gateway' /> 
				<label for='MC_A'>MC:</label><input type='text' name='rbod-mc1' placeholder='Enter the MC Port' /> 
				<label for='SC_A'>SC:</label><input type='text' name='rbod-sc1' placeholder='Enter the SC Port' /> 
				<label for='FU_A'>FU:</label><input type='text' name='rbod-fu1' placeholder='Enter the FU Port' /> 
				<label for='EC_A'>EC:</label><input type='text' name='rbod-ec1' placeholder='Enter the EC Port' /> 

				<label for='Controller_ID'>Controller_ID:</label>
				<select name='Controller-ID' required>
				<option value=""> - Select the Controller ID - </option>
				<option value='B'>B </select>
			<label for='HBA_Ports'>HBA_Ports:</label><input type='text' name='hba-ports' placeholder='Enter the HBA Ports' /> 
			<label for='MC_IP'>MC_IP:</label><input type='text' name='extra-ip' placeholder='Enter the MC_IP' /> 
			<label for='MC_Netmask'>MC_Netmask:</label><input type='text' name='netmask-ip' placeholder='Enter the MC_Netmask' /> 
			<label for='MC_Gateway'>MC_Gateway:</label><input type='text' name='gateway-ip' placeholder='Enter the MC_Gateway' /> 
			<label for='MC'>MC:</label><input type='text' name='rbod-mc' placeholder='Enter the MC Port' /> 
			<label for='SC'>SC:</label><input type='text' name='rbod-sc' placeholder='Enter the SC Port' /> 
			<label for='FU'>FU:</label><input type='text' name='rbod-fu' placeholder='Enter the FU Port' /> 
			<label for='EC'>EC:</label><input type='text' name='rbod-ec' placeholder='Enter the EC Port' /> 
				
			</fieldset>
		</template>



  <form name='myForm' method='POST'>

    <fieldset>
      <label for='Controller Type'>Controller Type</label>
      <select name='controller' required>
        <option value=""> - Select the Controller - </option>
        <option data-extra=true value='RAID'>RAID
          <option data-extra=true value='JBOD'>JBOD
            <option data-extra=true value='AP'>AP
      </select>
    </fieldset>

    <fieldset>
      <label for='Test Type'>Test Type</label>
      <select name='test' required>
        <option value=""> - Select The Test - </option>
        <option data-extra=true value='BFT'>BFT
          <option data-extra=true value='CTO'>CTO
            <option data-extra=true value='RAID Generic'>RAID Generic
              <option data-extra=true value='Port Check'>Port Check
                <option data-extra=true value='FW Generic'>FW Generic
                  <option data-extra=true value='JBOD Generic'>JBOD Generic
      </select>
    </fieldset>

    <!-- insert templated additional details here -->

    <fieldset>
      <label for='Protocol Type'>Protocol Type</label>
      <select name='protocol' required>
        <option value=""> - Select The Protocol -
          <option data-extra=true value='SAS'>SAS
            <option data-extra=true value='iSCSI'>iSCSI
              <option data-extra=true value='FC'>FC
      </select>
    </fieldset>

    <fieldset>
      <label for='IP Address'>IP Address:</label>
      <input type='text' name='ip' placeholder='Enter your IP address' required />
    </fieldset>

    <fieldset>
      <label for='Chasis Input'>Number of Chasis Input:</label>
      <input type='number' name='chassis' placeholder='Enter Number of Chasis' required />
    </fieldset>

    <fieldset>
      <input type='button' name='save' value='Save data to file' />
    </fieldset>
  </form>
</body>

</html>
Questioner
Jayashri
Viewed
27
Stratubas 2020-02-05 16:53

Take a look at this snippet. It's mostly your code, but I changed the part where you create the payload.

I marked my changes with MY CHANGE BEGINS HERE and MY CHANGE ENDS HERE comments.

It adds spaces dynamically, so the format looks like this:

PDU:
  PDU TEST: BFT
  PDU_IP: 185.237.96.51
Product Type: 
Protocol Type: iSCSI
Chasis Inputs: 

However, it does not work with the rest of your fields, but maybe you can use it to replace your hacky whitespacing by creating plain objects and adding them to your data.

document.addEventListener('DOMContentLoaded', function() {
  const extra = {};

  const oForm = document.forms.myForm;
  const oSave = document.querySelector('input[name="save"]');
  const oSub = document.querySelector('input[name="submit"]');
  const oCtrl = document.querySelector('select[name="controller"]');
  const oTest = document.querySelector('select[name="test"]');
  const oProto = document.querySelector('select[name="protocol"]');
  const oTmp = document.querySelector('template');


  const changehandler = function(e) {
    let option = this.options[this.options.selectedIndex];

    if (option.hasAttribute('data-extra')) extra[this.name] = this.value;
    else {
      if (extra.hasOwnProperty(this.name)) delete extra[this.name];
    }

    if (Object.keys(extra).length == 2) {
      let fieldset = oTmp.content.cloneNode(true);
      oForm.insertBefore(fieldset, oProto.parentNode.nextSibling)
    } else {
      if (document.getElementById('extra')) {
        fieldset = document.getElementById('extra')
        fieldset.parentNode.removeChild(fieldset);
      }
    }

    if (option.hasAttribute('data-extra')) extra[this.name] = this.value;
    else {
      if (extra.hasOwnProperty(this.name)) delete extra[this.name];
    }


    if (this.name == 'controller') {
      if (this.value == 'RAID') oProto.disabled = false
      else oProto.disabled = true
    }
  }



  const dialog = function(msg) {
    alert(msg);
    return false;
  }




  const savehandler = function(e) {
    e.preventDefault();
    let valid = true;

    /*[ 'name','email','test','controller','ip','chassis' ].forEach( n => {
    	oForm[ n ].classList.remove('invalid');
    	if( oForm[ n ].value=='' ){
    		oForm[ n ].classList.add('invalid');
    		valid=false; 
    	}
    });*/
    if (!valid) return dialog('Please fill all the fields!');



    const ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
    if (ipformat.test(oForm.ip.value) == false) {
      return dialog('Invalid IP Address');
    }



    let data = {
      "PDU": {
        "PDU TEST": oForm.test.value,
        "PDU_IP": oForm.ip.value
      },
      'Product Type': oForm.controller.value,
      'Protocol Type': oForm.protocol.value,
      'Chasis Inputs': oForm.chassis.value
    };
    var datastr = JSON.stringify(data);

    if (Object.keys(extra).length == 2) {
      data[' - 	#Controller_ID_A'] = oForm['Controller-ID1'].value;
      data['		 HBA_Ports_A'] = [oForm['hba-ports1'].value];
      data['		 MC_IP_A'] = oForm['extra-ip1'].value;
      data['		 MC_Netmask_A'] = oForm['netmask-ip1'].value;
      data['		 MC_Gateway_A'] = oForm['gateway-ip1'].value;
      data['		 MC_A'] = oForm['rbod-mc1'].value;
      data['		 SC_A'] = oForm['rbod-sc1'].value;
      data['		 FU_A'] = oForm['rbod-fu1'].value;
      data['		 EC_A'] = oForm['rbod-ec1'].value;


    }


    if (Object.keys(extra).length == 2) {
      data[' - 	#Controller_ID'] = oForm['Controller-ID'].value;
      data['		  HBA_Ports'] = [oForm['hba-ports'].value];
      data['		  MC_IP'] = oForm['extra-ip'].value;
      data['		  MC_Netmask'] = oForm['netmask-ip'].value;
      data['		  MC_Gateway'] = oForm['gateway-ip'].value;
      data['		  MC'] = oForm['rbod-mc'].value;
      data['		  SC'] = oForm['rbod-sc'].value;
      data['		  FU'] = oForm['rbod-fu'].value;
      data['		  EC'] = oForm['rbod-ec'].value;


    }


    // MY CHANGE BEGINS HERE <-------
    let payload = '';
    const addToPayload = (object, whitespace) => {
      for (const key of Object.keys(object)) {
        payload += whitespace + key + ':';
        const value = object[key];
        if (typeof value === 'object') {
          payload += String.fromCharCode(10);
          addToPayload(value, whitespace + '  ');
        } else {
          payload += ' ' + value + String.fromCharCode(10);
        }
      }
    }
    addToPayload(data, '');
    // MY CHANGE ENDS HERE <------------


    const blob = new Blob([payload], {
      type: 'text/plain'
    });
    const file = 'formData.yaml';

    let link = document.createElement('a');
    link.download = file;

    if (window.webkitURL != null) {
      link.href = window.webkitURL.createObjectURL(blob);
    } else {
      link.href = window.URL.createObjectURL(blob);
      link.style.display = "none";
      document.body.appendChild(link);
    }
    link.click();
  }


  oCtrl.addEventListener('change', changehandler);
  oTest.addEventListener('change', changehandler);
  oSave.addEventListener('click', savehandler);
})
<!DOCTYPE html>
<html>

<head>
  <title>Save form Data in a Text File using JavaScript</title>
  <h1>User Information </h1>
  <style>
    html,
    html * {
      box-sizing: border-box;
      border-color: teal;
      font-family: calibri;
    }
    
    html {
      background: radial-gradient(rgba(48, 97, 97, 0.5), rgba(255, 255, 255, 0.5))
    }
    
    input[type=button],
    input[type=submit] {
      padding: 1rem;
    }
    
    input[type=text],
    textarea,
    select {
      font: 17px Calibri;
      width: 100%;
      padding: 12px;
      border: 1px solid rgb(19, 18, 18);
      border-radius: 4px;
      color: teal
    }
    
    fieldset {
      border: none;
      padding: 10px;
      overflow: hidden;
      color: rgb(16, 8, 32);
      font-size: 25px;
      font-style: initial;
      font-family: 'Times New Roman', Times, serif;
    }
    
    #extra {
      border: 2px solid black;
      background: whitesmoke;
      border-radius: 1rem;
      box-shadow: 0 0 5px black;
      width: calc(100% - 24px);
      margin: auto;
      float: none;
      clear: both;
      text-indent: 50px;
    }
    
    #extra h6 {
      margin: 0
    }
    
    #extra style .invalid {
      border: 2px solid red!important;
      background: rgba(255, 0, 0, 0.1)
    }
  </style>
  <script src="script.js"></script>
</head>

<body>

  <template>
			<fieldset id='extra'>
				<h6>Additional Details Required</h6>
				<label for='Controller_ID_A'>Controller_ID:</label>
					<select name='Controller-ID1' required>
					<option value=""> - Select the Controller ID - </option>
					<option value='A'>A </select>
				<label for='HBA_Ports_A'>HBA_Ports:</label><input type='text' name='hba-ports1' placeholder='Enter the HBA Ports' /> 
				<label for='MC_IP_A'>MC_IP:</label><input type='text' name='extra-ip1' placeholder='Enter the MC_IP' /> 
				<label for='MC_Netmask_A'>MC_Netmask:</label><input type='text' name='netmask-ip1' placeholder='Enter the MC_Netmask' /> 
				<label for='MC_Gateway_A'>MC_Gateway:</label><input type='text' name='gateway-ip1' placeholder='Enter the MC_Gateway' /> 
				<label for='MC_A'>MC:</label><input type='text' name='rbod-mc1' placeholder='Enter the MC Port' /> 
				<label for='SC_A'>SC:</label><input type='text' name='rbod-sc1' placeholder='Enter the SC Port' /> 
				<label for='FU_A'>FU:</label><input type='text' name='rbod-fu1' placeholder='Enter the FU Port' /> 
				<label for='EC_A'>EC:</label><input type='text' name='rbod-ec1' placeholder='Enter the EC Port' /> 

				<label for='Controller_ID'>Controller_ID:</label>
				<select name='Controller-ID' required>
				<option value=""> - Select the Controller ID - </option>
				<option value='B'>B </select>
			<label for='HBA_Ports'>HBA_Ports:</label><input type='text' name='hba-ports' placeholder='Enter the HBA Ports' /> 
			<label for='MC_IP'>MC_IP:</label><input type='text' name='extra-ip' placeholder='Enter the MC_IP' /> 
			<label for='MC_Netmask'>MC_Netmask:</label><input type='text' name='netmask-ip' placeholder='Enter the MC_Netmask' /> 
			<label for='MC_Gateway'>MC_Gateway:</label><input type='text' name='gateway-ip' placeholder='Enter the MC_Gateway' /> 
			<label for='MC'>MC:</label><input type='text' name='rbod-mc' placeholder='Enter the MC Port' /> 
			<label for='SC'>SC:</label><input type='text' name='rbod-sc' placeholder='Enter the SC Port' /> 
			<label for='FU'>FU:</label><input type='text' name='rbod-fu' placeholder='Enter the FU Port' /> 
			<label for='EC'>EC:</label><input type='text' name='rbod-ec' placeholder='Enter the EC Port' /> 
				
			</fieldset>
		</template>



  <form name='myForm' method='POST'>

    <fieldset>
      <label for='Controller Type'>Controller Type</label>
      <select name='controller' required>
        <option value=""> - Select the Controller - </option>
        <option data-extra=true value='RAID'>RAID
          <option data-extra=true value='JBOD'>JBOD
            <option data-extra=true value='AP'>AP
      </select>
    </fieldset>

    <fieldset>
      <label for='Test Type'>Test Type</label>
      <select name='test' required>
        <option value=""> - Select The Test - </option>
        <option data-extra=true value='BFT'>BFT
          <option data-extra=true value='CTO'>CTO
            <option data-extra=true value='RAID Generic'>RAID Generic
              <option data-extra=true value='Port Check'>Port Check
                <option data-extra=true value='FW Generic'>FW Generic
                  <option data-extra=true value='JBOD Generic'>JBOD Generic
      </select>
    </fieldset>

    <!-- insert templated additional details here -->

    <fieldset>
      <label for='Protocol Type'>Protocol Type</label>
      <select name='protocol' required>
        <option value=""> - Select The Protocol -
          <option data-extra=true value='SAS'>SAS
            <option data-extra=true value='iSCSI'>iSCSI
              <option data-extra=true value='FC'>FC
      </select>
    </fieldset>

    <fieldset>
      <label for='IP Address'>IP Address:</label>
      <input type='text' name='ip' placeholder='Enter your IP address' required />
    </fieldset>

    <fieldset>
      <label for='Chasis Input'>Number of Chasis Input:</label>
      <input type='number' name='chassis' placeholder='Enter Number of Chasis' required />
    </fieldset>

    <fieldset>
      <input type='button' name='save' value='Save data to file' />
    </fieldset>
  </form>
</body>

</html>

You commented that you would prefer dynamic filenames. You can replace

const file = 'formData.yaml';

with something like this:

let file = 'test_' + data.PDU['PDU TEST'];
file += '_controller_' + data['Product Type'];
file += '_' + new Date().toISOString().substr(0, 10); // '2020-05-02'
file += '.yaml';
file = prompt('Filename:', file); // to edit manually
if (!file) { return; } // canceled by user