/** * @param {SheetsOnEdit} e - edit event object */ function onEdit(e) { /** * @typedef {Object} MultiDropDown * @property {String} namedRange * @property {Number} handlingDuplicates * @property {String} separator * @property {Boolean} sortResult */ const ddRanges = [{'namedRange': 'ddFruitVeges', 'handlingDuplicates': 1, 'separator': ", ", 'sortResult': true}]; multiSelectDropDownList(e, ddRanges); } /** * @param {SheetsOnEdit} e * @param {MultiDropDown[]} ddRanges * @returns {void} */ function multiSelectDropDownList(e, ddRanges) { ddRanges.forEach((nr) => { if (!isIntersection(e, nr.namedRange)) return; updateDropDownListCell(e, nr.handlingDuplicates, nr.separator, nr.sortResult); }); } /** * @param {SheetsOnEdit} e - edit event object * @param {String} ddNamedRange * @returns {Boolean} */ function isIntersection(e, ddNamedRange) { const activeCell = e.range; // is the Active Cell a single cell? if (activeCell.width * activeCell.height > 1) return false; // loop through the array of drop down list named ranges const rngNR = e.source.getRangeByName(ddNamedRange); // is the Active Cell on the same sheet? const shtIdAC = activeCell.getSheet().getSheetId(); const shtIdNR = rngNR.getSheet().getSheetId(); if (shtIdAC !== shtIdNR) return false; // is the Active Cell intersecting within the boundaries of the named range? const colAC = activeCell.getColumn(); const rowAC = activeCell.getRow(); const colNR = rngNR.getColumn(); const rowNR = rngNR.getRow(); const colNRLast = rngNR.getLastColumn(); const rowNRLast = rngNR.getLastRow(); return colAC >= colNR && colAC <= colNRLast && rowAC >= rowNR && rowAC <= rowNRLast; } /** * @param {SheetsOnEdit} e * @param {Number} handlingDuplicates * @param {String} separator * @param {Boolean} sortResult * @returns {Range} */ function updateDropDownListCell(e, handlingDuplicates, separator, sortResult) { // if cell has been cleared or is a new cell if (!e.value || !e.oldValue) return e.range.setValue(e.value); const oldItems = e.oldValue.split(separator); const idx = oldItems.indexOf(e.value); if (idx > -1) { // if it does, how do you want to handle it? // Option #1: splice the item from the list if (handlingDuplicates === 1) { oldItems.splice(idx, 1); if (sortResult && oldItems.length > 1) oldItems.sort(); return e.range.setValue(oldItems.join(separator)); } // Option #2: exclude it from being added, but do not remove it if (handlingDuplicates === 2) return e.range.setValue(oldItems.join(separator)); // Option #3: add it to the existing list as an additional item // continue with rest of the code } // check if the newly selected item already exists in the active cell // add value to existing items oldItems.push(e.value); if (sortResult) oldItems.sort(); return e.range.setValue(oldItems.join(separator)); }