Reputation: 77
I need to get three depending drop-down lists, which depend on each other. Here is an editable sheet with the example. Cells in the yellow column contain a drop-down list which is based on usual data validation (Options sheet). Cells in the green column give a corresponding drop-down list, which is based on the script. And in blue column I need to get a corresponding list from the sheet Options with names corresponding with the data in the middle green column.
I will appreciate any help.
var mainWsName = "master";
var optionsWsName = "options";
var firstLevelColumn = 12;
var secondLevelColumn = 13;
var thirdLevelColumn = 14;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(optionsWsName);
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === mainWsName && c === firstLevelColumn && r > 4){
applyFirstLevelValidation(val,r);
} else if(wsName === mainWsName && c === secondLevelColumn && r > 4){
applySecondLevelValidation(val,r);
}
} //end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredOptions = options.filter(function(o){ return o[0] === val });
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r, secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions =options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r.thirdLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInlist(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule)
}
Upvotes: 1
Views: 238
Reputation: 201378
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
options
is not declared for the function of applyFirstLevelValidation
and applySecondLevelValidation
.r.thirdLevelColumn
of ws.getRange(r.thirdLevelColumn)
occurs an error. Because r
is the number..requireValueInlist(list)
is .requireValueInList(list)
. It's a spelling mistake.When your script is modified, please modify as follows.
var filteredOptions = options.filter(function(o){ return o[0] === val });
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === val });
and
var filteredOptions =options.filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === firstLevelColValue && o[1] === val });
and
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r.thirdLevelColumn);
applyValidationToCell(listToApply,cell);
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r, thirdLevelColumn); // <--- Modified
applyValidationToCell(listToApply,cell);
and
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInlist(list)
.setAllowInvalid(false)
.build();
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list) // <--- Modified
.setAllowInvalid(false)
.build();
var mainWsName = "master";
var optionsWsName = "options";
var firstLevelColumn = 12;
var secondLevelColumn = 13;
var thirdLevelColumn = 14;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(optionsWsName);
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName === mainWsName && c === firstLevelColumn && r > 4){
applyFirstLevelValidation(val,r);
} else if(wsName === mainWsName && c === secondLevelColumn && r > 4){
applySecondLevelValidation(val,r);
}
} //end onEdit
function applyFirstLevelValidation(val,r){
if(val === ""){
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, secondLevelColumn).clearContent();
ws.getRange(r, secondLevelColumn).clearDataValidations();
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === val }); // <--- Modified
var listToApply = filteredOptions.map(function(o){ return o[1] });
var cell = ws.getRange(r, secondLevelColumn);
applyValidationToCell(listToApply,cell);
}
}
function applySecondLevelValidation(val,r){
if(val === ""){
ws.getRange(r, thirdLevelColumn).clearContent();
ws.getRange(r, thirdLevelColumn).clearDataValidations();
} else {
ws.getRange(r, thirdLevelColumn).clearContent();
var firstLevelColValue = ws.getRange(r, firstLevelColumn).getValue();
var filteredOptions = wsOptions.getDataRange().getValues().filter(function(o){ return o[0] === firstLevelColValue && o[1] === val }); // <--- Modified
var listToApply = filteredOptions.map(function(o){ return o[2] });
var cell = ws.getRange(r, thirdLevelColumn); // <--- Modified
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list) // <--- Modified
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule)
}
If I misunderstood your question and this was not the direction you want, I apologize.
Upvotes: 1