javascripthtmlgoogle-apps-scriptbuttontextarea

Get the value of the (newly created) Textarea and insert it into Google Sheets


I have a number of Textareas, and can create new Textareas. I use the insertValue button to insert the values of the textareas into the spreadsheet. My code is as follows: HTML:

<!DOCTYPE html>
<html>
<body>
  <div class="container">
    <input type="text" id="qnumberDS" placeholder="Enter question">

    <textarea id="contentDS" placeholder="Enter question content"></textarea>

    <div class="options">
      <div class="option">
        <input type="checkbox" id="ch1" class="checkbox">
        <textarea id="a" class="option-textarea" placeholder="Enter option A"></textarea>
      </div>
      <div class="option">
        <input type="checkbox" id="ch2" class="checkbox">
        <textarea id="b" class="option-textarea" placeholder="Enter option "></textarea>
      </div>
      <div class="option">
        <input type="checkbox" id="ch3" class="checkbox">
        <textarea id="c" class="option-textarea" placeholder="Enter option C"></textarea>
      </div>
      <div class="option">
        <input type="checkbox" id="ch4" class="checkbox">
        <textarea id="d" class="option-textarea" placeholder="Enter option D"></textarea>
      </div>
      </div>

    <button id="insertRow">Add options</button>

    <button id="insertValue">Send data</button>
  </div>

  <script>
    
const qnumberDSInput = document.getElementById('qnumberDS');
const contentDSInput = document.getElementById('contentDS');
const optionsContainer = document.querySelector('.options');
const insertRowButton = document.getElementById('insertRow');
const insertValueButton = document.getElementById('insertValue');


function insertRow() {
  const newOption = document.createElement('div');
  newOption.classList.add('option');

  const newCheckbox = document.createElement('input');
  newCheckbox.type = 'checkbox';
  newCheckbox.id = `ch${optionsContainer.children.length + 1}`;
  newCheckbox.classList.add('checkbox');
  newOption.appendChild(newCheckbox);

  const newTextarea = document.createElement('textarea');
  newTextarea.id = String.fromCharCode(97 + optionsContainer.children.length);
  newTextarea.classList.add('option-textarea');
  newTextarea.placeholder = `Nhập phương án ${String.fromCharCode(97 + optionsContainer.children.length)}`;
  newOption.appendChild(newTextarea);

  optionsContainer.appendChild(newOption);
}


function insertValue() {
  const title = qnumberDSInput.value;
  const content = contentDSInput.value;

  const data = [];

  optionsContainer.querySelectorAll('.option').forEach((option, index) => {
    const checkbox = option.querySelector('.checkbox');
    const textarea = option.querySelector('.option-textarea');

    const optionValue = textarea.value;
    const isChecked = checkbox.checked;

    const optionData = {
      value: optionValue,
      isCorrect: isChecked ? 'Đ' : 'S'
    };
    if (!data[data.length - 1].options) {
      data[data.length - 1].options = [];
    }

    data[data.length - 1].options.push(optionData);
  });

  google.script.run.enterNameDS(data);
}

insertRowButton.addEventListener('click', insertRow);
insertValueButton.addEventListener('click', insertValue);

  </script>
</body>
</html>

js:

function enterNameDS(data) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var shTitle = ss.getSheetByName('title');
  var sh = ss.getSheetByName('tests');

  var numPart1 = Number(shTitle.getRange('E8').getValue());

 data.forEach(question => {
    const formulas = [question.title, `="${question.content}"`];

    question.options.forEach(option => {
      formulas.push(`=if(column()=${option.position + 3};"${option.value}";"")`);
    });

    sh.getRange(numPart1 + 1, 1, 1, formulas.length).setFormulas([formulas]);

    numPart1++;
  });

 shTitle.getRange('E8').setValue(numPart1);
}

I don't know if the error is in the HTML or in the js. I don't know how to find errors in script code embedded in HTML.

I really need your help to find errors in this code. Thank you.


Solution

  • I am not able to test with Google Sheets, so missed some problems in your code with my initial answer. I've fixed a few more things. I still don't know if the strings being passed to sh.getRange(), shTitle.getRange(), .setFormulas() and .setValue() are correct.

    You will have to look at the console.log() output and adjust things per Google Sheets documentation.

    The problem is in insertValue() - you need to push the options into the data array, NOT push to data[].options.

    i.e.:

    data.push(optionData);
    

    If you do not know how debug JavaScript in your html file, then may I suggest that you move it out to its own .js file where you do know how to debug it. Just remember to include a script command in your html <head> area to so it gets executed.

     <script defer src="/javascript_libraries/myJavascript.js"></script>
    

    Your original insertValue() was setting title and content, but not doing anything with them. And yet your enterNameDS() was expecting that they were in your data. So I've changed what you pass to enterNameDS() to be a structure with your data array as a property.

    I removed question.forEach() in enterNameDS() and changed the formulas.push() statement appropriately (see NOTE).

    I added position to optionData in insertValue() since enterNameDS() is expecting it in the data structure. I had to guess at what values you intended to be for position, so you will likely have to change that line of code.

    So here are new versions of both insertValue() and enterNameDS().

    Hope this helps you get things working!

    function enterNameDS(data) {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var shTitle = ss.getSheetByName('title');
      var sh = ss.getSheetByName('tests');
    
      var numPart1 = Number(shTitle.getRange('E8').getValue());
    
      data.data.forEach(question => {
        // NOTE .title and .content are at the top level of the data structure
        const formulas = [data.title, `="${data.content}"`];
    
        // NOTE There is no array here to loop through. We get our values from the question object
        formulas.push(`=if(column()=${question.position + 3};"${question.value}";"")`);
    
        sh.getRange(numPart1 + 1, 1, 1, formulas.length).setFormulas([formulas]);
        // NOTE Check to see if these strings look correct
        console.log( `setRange( ${numPart1 + 1}, 1, 1, ${formulas.length} `)
        console.log( `formulas: ${formulas}` )
    
        numPart1++;
      });
    
      shTitle.getRange('E8').setValue(numPart1);
      // NOTE Check to see if these strings look correct
      console.log( `numPart1: ${numPart1}` )
    }
    
    
    function insertValue() {
      const title = qnumberDSInput.value;
      const content = contentDSInput.value;
    
      const data = [];
    
      optionsContainer.querySelectorAll('.option').forEach((option, index) => {
        const checkbox = option.querySelector('.checkbox');
        const textarea = option.querySelector('.option-textarea');
    
        const optionValue = textarea.value;
        const isChecked = checkbox.checked;
    
        const optionData = {
          // NOTE Added position. I made a guess at what value you want in here
          position: parseInt( checkbox.id.slice(2) ),
          value: optionValue,
          isCorrect: isChecked ? 'Đ' : 'S'
        };
    
        // NOTE: This push replaces the other two
        data.push(optionData);
      });
    
      // NOTE Fixed this call to pass in an object
      google.script.run.enterNameDS({title, content, data});
    }