0

I have a list of options in a data list populated from a spreadsheet. When I click into the empty field, it shows all of the options. All of the options listed. After one is selected, I can't click into it again to see all of the options. I have to delete the option and then I can see all options again. Only one option shows. Looks like an autofill or history bubble.

 <form id="edit" autocomplete="off">
    <div>Choose an employee:<input list="employee" onchange="javascript:submit();">
    <datalist id="employee">
      <? var emp = getCurrentEmployees(); ?>
      <? for(x=0;x<emp.length;x++) { ?>
      <option value="
      <?= emp[x] ?>
      ">
      </option>
      <? } ?>
    </datalist>

I've tried to set the autocomplete to off and tried a suggestion to set the onchange. Neither seem to be doing anything.

I'm using this as a sidebar html service in google sheets.

Full HTML:

<!DOCTYPE html>
<html>

<head>
  <base target="_top" />
  <?!= include('CSS') ?>
</head>

<body>
  <?!= include('LOGO') ?>
  <form id="edit" autocomplete="off">
    <div>Choose an employee:<input list="employee" onchange="javascript:submit();">
    <datalist id="employee">
      <? var emp = getCurrentEmployees(); ?>
      <? for(x=0;x<emp.length;x++) { ?>
      <option value="
      <?= emp[x] ?>
      ">
      </option>
      <? } ?>
    </datalist>
    </div><hr>
    <div><input id="fName" type="text" /> First Name</div>
    <div><input id="lName" type="text" /> Last Name</div>
    <div><input id="empId" type="text" /> ID#</div>
    <div><input id="job" type="text" /> Job</div>
    <div><input id="wage" type="text" /> Wage</div>
    <div id="job2" style="display: none"><input id="jobtwo" type="text" /> Job 2</div>
    <div id="wage2" style="display: none"><input id="wagetwo" type="text" /> Wage 2</div>
    <div id="job3" style="display: none"><input id="jobthree" type="text" /> Job 3</div>
    <div id="wage3" style="display: none"><input id="wagethree" type="text" /> Wage 3</div>
    <div>
      <button id="enter" type="button" onclick="addRecord()"> Enter</button>
      <button id="more" type="button" onclick="moreJobs()"> + Job</button>
      <button id="less" type="button" onclick="lessJobs()"> - Job</button>
      <button id="close" type="button" onclick="closeSide()"> Close</button>
    </div>
  </form>
  <?!= include('EditEmpJS') ?>
  
</body>

</html>

FULL CODE FILE

const ws = 

SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EMPLOYEES");
const setup = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SETUP");
const summary = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SUMMARY");
const ui = SpreadsheetApp.getUi();

function onOpen(e) {
  ui.createMenu(" Employees")
    .addItem(" Add Employee", "addEmp")
    .addItem("✨ Edit Employee", "editEmp")
    .addItem(" Del Employee", "delEmp")
    .addToUi();
  ui.createMenu(" Departments")
    .addItem("➕ Add Department", "addDept")
    .addItem(" Edit Department", "editDept")
    .addItem("➖ Del Department", "delDept")
    .addToUi();
  ui.createMenu("⌚ Schedule")
    .addItem(" Add Week", "addSched")
    .addItem(" Update Summary Tab", "updateTabs")
    .addToUi();    
  updateTabs();
}

function updateTabs() {
  var tabList = SpreadsheetApp.getActiveSpreadsheet().getSheets().map((s) => s.getName())
    .filter((s) => s != "SETUP" && s != "EMPLOYEES" && s != "TEMPLATE" && s != "SUMMARY")
  Logger.log(tabList)
  var rule = SpreadsheetApp.newDataValidation().requireValueInList(tabList)
  var dropDown = summary.getRange("A1").setDataValidation(rule).activate();

}

function include(page) {
    return HtmlService.createHtmlOutputFromFile(page).getContent();
}

//ADD EDIT & REMOVE EMPLOYEE HTML 
function addEmp() {
  var page = HtmlService.createTemplateFromFile("AddEmp").evaluate();
  page.setTitle(" Add Employee")
  ui.showSidebar(page)
}
function editEmp() {
  var page = HtmlService.createTemplateFromFile("EditEmp").evaluate();
    page.setTitle("✨ Edit Employee");
  ui.showSidebar(page)
}
function delEmp() {
  var page = HtmlService.createTemplateFromFile("DelEmp").evaluate();
    page.setTitle(" Delete Employee");
  ui.showSidebar(page)
}

//checks for an id# and job code
// if id# already exist, err to checkId
// if job doesn't exist, eff to checkJob

function addEmpRecord(record) {
  let array_target = ws.getRange("C2");
  let array_formula = array_target.getFormula();
  array_target.clear();
  if (!checkId(record[2]) && !checkJob(record[3])) {
    ws.getRange(ws.getLastRow() + 1, 1, 1, 10).setValues([[
      record[0], record[1], , record[2].toString(), record[3].toUpperCase(), record[4], record[5].toUpperCase(), record[6], record[7].toUpperCase(), record[8]
    ]])
    var html = HtmlService.createHtmlOutput("<h4>Entry Accepted</h4><p>Close sidebar to continue or add another employee.</p>")
      .setWidth(300)
      .setHeight(125);
    ui.showModalDialog(html, "Success!")

  }
  else if (checkId(record[2].toString())) {
    var html = HtmlService.createHtmlOutput("<h4>User id# already exists</h4><p>Please choose different id#</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  else if (checkJob(record[3])) {
    var html = HtmlService.createHtmlOutput("<h4>Job Code does not exitst</h4><p>Please choose a valid job code.<br>*Case sensitive</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  else {
    var html = HtmlService.createHtmlOutput("<h4>Unspecified error</h4><p>Please contact support.</p>")
      .setWidth(200)
      .setHeight(75);
    ui.showModalDialog(html, "Warning!")
  }
  array_target.setValue(array_formula)
}

// checks if an id# already exists
function checkId(num) {
  var result = false;
  var current_ids = ws.getRange(2, 4, ws.getLastRow(), 1).getValues();
  for (id = 0; id < current_ids.length; id++) {
    if (current_ids[id].toString() == num.toString()) {
      result = true
    }
  }
  return result
}

// checks if a job code exists
function checkJob(job) {
  var result = false;
  var current_jobs = setup.getRange(2, 3, setup.getLastRow(), 1).getValues();
  for (job = 0; job < current_jobs.length; job++) {
    if (current_jobs[job] == job) {
      result = true
    }
  }
  return result
}

function getCurrentEmployees() {
  return ws.getRange("C2:C").getValues();
}

function getEmployeeRecord(employee) {
  var list = ws.getRange("C2:C").getValues();
  for(e=0;e<list.length;e++) {
    if(list[e] == employee) {
      return ws.getRange(e+1,1,1,10).getValues();
    }
  }
}

Edit: I'm getting the same result on the documentation site. If it is acting how it should, how do I get a dynamic select input besides datalist?

Mozilla all options.

After selecting, only the selected one will show.

J_da_grey
  • 3
  • 4
  • Can you provide the script for correctly replicating your current issue? – Tanaike Apr 06 '23 at 06:10
  • Full html and code files added. – J_da_grey Apr 06 '23 at 06:21
  • Thank you for replying. I think that this is the specification of `datalist`. And, it seems that `autocomplete="off"` is used. So, in this case, how about changing `datalist` to `select`? By this, after you select an option, you can see all values. But, I'm not sure whether this is your expected direction. So, I posted this as a comment. I apologize for this. – Tanaike Apr 06 '23 at 08:04
  • By the way, what is `onchange="javascript:submit();"` of ``? – Tanaike Apr 06 '23 at 08:30
  • I did find this other case. Didn't see this in the suggestions. https://stackoverflow.com/questions/6865943/html-form-select-option-vs-datalist-option#:~:text=Think%20of%20it%20as%20the,he%20wants%20in%20the%20input. @Tanaike I can confirm that select will accomplish my objective. I'm not sure why I settled on datalist to start, but it was the wrong choice for this application. ty again. The ```javascript:submit();``` assigned to the onchange element was an attempt to refresh the list but it was certainly in err. I found it on another similar issue but it is not the correct application. – J_da_grey Apr 07 '23 at 02:21
  • Thank you for your support. Although I'm not sure whether I could correctly understand your reply, if you can use `select`, your goal can be directly achieved. How about this? And, I think that I might understand about `javascript:submit();`. – Tanaike Apr 07 '23 at 02:53
  • But, if you are required to use `datalist`, I have a simple workaround. But, first, I would like to correctly understand your expected direction. So, I would like to wait for your next reply. – Tanaike Apr 07 '23 at 03:04
  • For this project, I do not want the user to have the ability to enter their own value. I have reset the input type to `select` and it is working as expected. It would be nice to know about the workaround you suggest in case I run into a future condition where I need a user input option alongside preselected choices. – J_da_grey Apr 07 '23 at 03:29
  • Thank you for replying. From your reply, I understood that your issue was resolved by changing "datalist" to select. In this case, can you post it as an answer? By this, it will be useful for other users who have the same issue. About the workaround for using "datalist", in this case, when a value is selected from "datalist", the selected value is retrieved and removed and put the selected value to other tag. By this, the currently selected value can be confirmed. And, the selected value can be also obtained. This is a simple workaround. – Tanaike Apr 07 '23 at 03:50

1 Answers1

0

Changing the type from datalist to select fixed the issue.

<form id="edit" autocomplete="off">
    <div>Choose an employee:<br>
    <select id="employee" onchange="changeTarget(document.getElementById('employee'))">
      <? var emp = getCurrentEmployees(); ?>
      <? for(x=0;x<emp.length;x++) { ?>
      <option value="
      <?= emp[x] ?>
      ">
      <?= emp[x] ?>      
      </option>
      <? } ?>
    </select>

autocomplete and onchange attributes did not help in the change.

Thanks to @Tanaike for his help identifying the issue

J_da_grey
  • 3
  • 4