I managed to make dependent dropdown list using codes from
It works and I get the intended responses. But it seems like the trigger function can only be used once. I meant, when I tried to use GetIslands(this.value) for the second line of entries, it didn't work. Here's how it's like when I tried to use GetIslands(this.value) repeatedly:
The dropdown list of islands for Person A was changed when I selected a state for Person B.
So I had to repeat the same block of codes multiple times (hence GetIslands2(this.value) for the second entry). There must be a less redundant way to do it. Can anyone help? Thanks in advance!
HTML & JAVASCRIPT
<label>State</label>
<select id="state1" onchange="GetIslands(this.value)" required></div>
<option value="" hidden>Select a state</option>
<? for(var i = 0; i < states.length; i ) { ?>
<option value="<?= states[i] ?>" ><?= states[i] ?></option>
<? } ?></select>
<label>Island</label>
<select name="island" id="island1" required>
<option value="" hidden>Select a marine park</option>
</select>
<label>State</label>
<select id="state2" onchange="GetIslands2(this.value)" required></div>
<option value="" hidden>Select a state</option>
<? for(var i = 0; i < states.length; i ) { ?>
<option value="<?= states[i] ?>" ><?= states[i] ?></option>
<? } ?></select>
<label>Island</label>
<select name="island2" id="island2" required>
<option value="" hidden>Select a marine park</option>
</select>
<script>
function GetIslands(state)
{
google.script.run.withSuccessHandler(function(ar)
{
console.log(ar);
island1.length = 0;
let option = document.createElement("option");
option.value = "";
option.text = "Select an island";
option.hidden = true;
island1.appendChild(option);
ar.forEach(function(item, index)
{
let option = document.createElement("option");
option.value = item;
option.text = item;
island1.appendChild(option);
});
}).getIslands(state);
};
function GetIslands2(state)
{
google.script.run.withSuccessHandler(function(ar)
{
console.log(ar);
island2.length = 0;
let option = document.createElement("option");
option.value = "";
option.text = "Select an island";
option.hidden = true;
island2.appendChild(option);
ar.forEach(function(item, index)
{
let option = document.createElement("option");
option.value = item;
option.text = item;
island2.appendChild(option);
});
}).getIslands(state);
};
</script>
APPS SCRIPT
function getState() {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var siteSheet = ss.getSheetByName("Sites");
var getLastRow = siteSheet.getLastRow();
var return_array = [];
for(var i = 2; i <= getLastRow; i )
{
if(return_array.indexOf(siteSheet.getRange(i, 1).getValue()) === -1) {
return_array.push(siteSheet.getRange(i, 1).getValue());
}
}
return return_array;
}
function getIslands(state) {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var siteSheet = ss.getSheetByName("Sites");
var getLastRow = siteSheet.getLastRow();
var return_array = [];
for(var i = 2; i <= getLastRow; i )
{
if(siteSheet.getRange(i, 1).getValue() === state){
return_array.push(siteSheet.getRange(i, 2).getValue());
}
}
const unique = (value,index,self) => {return self.indexOf(value) ===index;}
var Unique_List=return_array.filter(unique);
return Unique_List;
}
CodePudding user response:
I believe your goal is as follows.
- When
state1
is changed, a value is set toisland1
. And, whenstate2
is changed, a value is set toisland2
. In the current script, in order to achieve this, it is required to use 2 functions ofGetIslands
andGetIslands2
. - In your goal, you want to achieve this situation using only the function
GetIslands
.
In this case, how about the following modification?
Modified script:
In this modification, your showing HTML is modified as follows.
<label>State</label>
<select id="state1" onchange="GetIslands(this)" required></div>
<option value="" hidden>Select a state</option>
<? for(var i = 0; i < states.length; i ) { ?>
<option value="<?= states[i] ?>" ><?= states[i] ?></option>
<? } ?></select>
<label>Island</label>
<select name="island" id="island1" required>
<option value="" hidden>Select a marine park</option>
</select>
<label>State</label>
<select id="state2" onchange="GetIslands(this)" required></div>
<option value="" hidden>Select a state</option>
<? for(var i = 0; i < states.length; i ) { ?>
<option value="<?= states[i] ?>" ><?= states[i] ?></option>
<? } ?></select>
<label>Island</label>
<select name="island2" id="island2" required>
<option value="" hidden>Select a marine park</option>
</select>
<script>
function GetIslands(e) {
const obj = {state1: island1, state2: island2};
google.script.run.withSuccessHandler(function (ar) {
console.log(ar);
obj[e.id].length = 0;
let option = document.createElement("option");
option.value = "";
option.text = "Select an island";
option.hidden = true;
obj[e.id].appendChild(option);
ar.forEach(function (item, index) {
let option = document.createElement("option");
option.value = item;
option.text = item;
obj[e.id].appendChild(option);
});
}).getIslands(e.value);
}
</script>
- In this modification, an object for converting the edited tag is prepared like
const obj = {state1: island1, state2: island2}
. And, using this, each tag is managed.