How use sessionStorage with JS and Google Apps Script? - javascript

I am trying to avoid calling the server-side function getSuppliersForPoFromSS(orderPo, origin), if there isn't data available in the sessionStorage, but I am not sure I get the right structure:
**/
* Gets determined supplier from Spreadsheet and builds a select input with options.
* #param {Object} selecObject
* #param {String} origin specifying where this is going to be obtained from
*/
function loadSuppliersForPoFromSS(selectObject, origin) {
orderPo = selectObject.value;
document.getElementById('selectSupplier').innerHTML = '';
//My shot at it, trying to a 2D array. e.g.: [["Item1", "Item2"]]
let ar = JSON.parse(sessionStorage.getItem(orderPo));
if(!ar){
google.script.run.withSuccessHandler(function(ar) {
let select = document.getElementById('selectSupplier');
let options = select.getElementsByTagName('option');
for (let i = options.length; i--;) {
select.removeChild(options[i]);
}
let option = document.createElement("option");
option.value = "";
option.text = "";
select.appendChild(option);
ar.forEach(function(item, index) {
let option = document.createElement("option");
option.value = item.toLowerCase();
option.text = item;
select.appendChild(option)
});
}).getSuppliersForPoFromSS(orderPo, origin);
} else {
//Do I rewrit the part that builds the options with data from sessionStorage?
}

Since google.script.run is asynchronous, which means the commands following it will not wait for google.script.run to complete and return you can create an internal function getAr() which will be called either as part of the success handler of google.script.run or by itself if sessionStorage returns a value.
function loadSuppliersForPoFromSS(selectObject, origin) {
orderPo = selectObject.value;
document.getElementById('selectSupplier').innerHTML = '';
function getAr(ar) {
let select = document.getElementById('selectSupplier');
let options = select.getElementsByTagName('option');
for (let i = options.length; i--;) {
select.removeChild(options[i]);
}
let option = document.createElement("option");
option.value = "";
option.text = "";
select.appendChild(option);
ar.forEach(function(item, index) {
let option = document.createElement("option");
option.value = item.toLowerCase();
option.text = item;
select.appendChild(option)
});
}
//My shot at it, trying to a 2D array. e.g.: [["Item1", "Item2"]]
let ar = JSON.parse(sessionStorage.getItem(orderPo));
if(!ar){
google.script.run.withSuccessHandler(function(ar) {
getAr(ar);
}).getSuppliersForPoFromSS(orderPo, origin);
}
else {
getAr(ar);
}
}

Related

Submitting form is resetting city dropDown javascript

i made two dynamic dropdown list State and city
City dropdown will depend of selected option of state
problem is when all is good and okay to submit .it resets the city drop down
and does not submit
javascript code for making those dynamic drop down is
these function are onchange events
// remove all previous options
function removeOptions(selectbox) {
for (let i = selectbox.options.length - 1; i >= 0; i--) {
selectbox.remove(i);
}
}
// function to make city drop down according to selected state
function cityFunction(){
// get input value and text
const stateobj = document.getElementById('stateDropDown');
const valueState = stateobj.options[stateobj.selectedIndex].text;
const selectedOption = stateobj.options[stateobj.selectedIndex].value;
// making required arrays
let sindhArray = [ 'Select City', 'Karachi', 'Hyderabad', 'Mirpur khas', 'Sukkhar', 'Shikarpur' ];
let KhyberArray = [ 'Select City', 'gilgit', 'Qalat', 'Balakoot', 'Sawat', 'Peshwar' ];
let punjabArray = [ 'Select City', 'Lahore', 'Fasialabad', 'Qasoor', 'SheikhuPura', 'Gujrat' ];
let balochArray = [ 'Select City', 'Quetta', 'Chaman', 'Khuzdar', 'Turbat', 'Gawdar' ];
// if value is punjab or any select cities according to that state
if (valueState == 'Punjab') {
// removing all previous present options
removeOptions(document.getElementById('cityDropDown'));
let cityD = document.querySelector('#cityDropDown');
let index = 0;
for (let ele of punjabArray) {
var opt = document.createElement('option');
opt.value = index;
opt.innerHTML = ele; // whatever property it has
document.getElementById('cityDropDown').value = cityD.appendChild(opt);
index++;
}
}
if (valueState == 'Sindh') {
removeOptions(document.getElementById('cityDropDown'));
let cityD = document.querySelector('#cityDropDown');
let index = 0;
for (let ele of sindhArray) {
var opt = document.createElement('option');
opt.value = index;
opt.innerHTML = ele; // whatever property it has
document.getElementById('cityDropDown').value = cityD.appendChild(opt);
index++;
}
}
if (valueState == 'Balochistan') {
removeOptions(document.getElementById('cityDropDown'));
let cityD = document.querySelector('#cityDropDown');
let index = 0;
for (let ele of balochArray) {
var opt = document.createElement('option');
opt.value = index;
opt.innerHTML = ele; // whatever property it has
document.getElementById('cityDropDown').value = cityD.appendChild(opt);
index++;
}
}
if (valueState == 'khyber Pakhtunkhwa') {
removeOptions(document.getElementById('cityDropDown'));
let cityD = document.getElementById('cityDropDown');
let index = 0;
for (let ele of KhyberArray) {
var opt = document.createElement('option');
opt.value = index;
opt.innerHTML = ele; // whatever property it has
document.getElementById('cityDropDown').value = cityD.appendChild(opt);
index++;
}
}
}
for city form validation onchange event is
function cityDown() {
const cityObj = document.getElementById('cityDropDown');
const cityText = cityObj.options[cityObj.selectedIndex].text;
const valueOfCity = cityObj.options[cityObj.selectedIndex].value;
let citiesArray = [
'Quetta',
'Chaman',
'Khuzdar',
'Turbat',
'Gawdar',
'Lahore',
'Fasialabad',
'Qasoor',
'SheikhuPura',
'Gujrat',
'gilgit',
'Qalat',
'Balakoot',
'Sawat',
'Peshwar',
'Karachi',
'Hyderabad',
'Mirpur khas',
'Sukkhar',
'Shikarpur'
];
if ( valueOfCity == 0) {
document.getElementById('cityErr').innerText = 'City is required';
document.getElementById('cityDropDown').focus();
return valueOfCity;
}
if (citiesArray.indexOf(cityText) < 0) {
document.getElementById('cityErr').innerText = 'Select City';
document.getElementById('cityDropDown').focus();
return valueOfCity;
} else {
document.getElementById('cityErr').innerText = '';
return valueOfCity;
};
}
main function is
// validation f0rm function
function validateForm() {
// creating variable then sanitize them
isTrueorFalse = false;
document.getElementById('Address').disabled = isTrueorFalse;
document.getElementById('stateDropDown').disabled = isTrueorFalse;
document.getElementById('stateDropDown').style.background = '#FFF';
document.getElementById('cityDropDown').disabled = isTrueorFalse;
document.getElementById('cityDropDown').style.background = '#FFF';
const stateVal = stateDrag();
const cityV = cityDown();
const userAddress = form.Address.value;
//States must not be unselected
if (stateVal == 0 || stateVal == '') {
document.getElementById('stateErr').innerText = 'State is required.';
document.getElementById('stateDropDown').focus();
return false;
}
if (stateVal < 0) {
document.getElementById('stateErr').innerText = 'State is required.';
document.getElementById('stateDropDown').focus();
return false;
}
document.getElementById('addressErr').innerText = '';
document.getElementById('cityDropDown').focus();
console.log(cityV);
if (cityV == 0 || cityV == '') {
document.getElementById('cityErr').innerText = 'State is required.';
document.getElementById('cityDropDown').focus();
return false;
}
document.getElementById('cityErr').innerText = '';
document.getElementById('signupForm').submit();
}
here that demo
https://jsbin.com/jeguwakolo/1/edit?html,css,js,console,output
onsubmit was calling that function again and was resetting the city dropdown.
To solve this i just removed that function from stateDrag() and
in html i did this
<select oninput ="return stateDrag()" onchange="return cityFunction()">
after this i didnt get same problem and scripting was working fine thank you for everyone

How to populate the default to dropdown in Javascript

Good day
My code below populate the lists of warehouses to a dropdown, which is what i want but i also want do make the warehouse with isMainWarehouse = true a default selected when populating the warehouses (note that there is only one main warehouse)
function PopulateWarehouses() {
var warehouseDropDown = document.getElementById('SelectWarehouse');
var warehouseFragment = document.createDocumentFragment();
_warehouseRepository.getWarehouses().done(function (data) {
for (var element in data.items) {
if (data.items.hasOwnProperty(element)) {
var recievedData = data.items[element];
var id = recievedData.id;
var name = recievedData.warehouseName;
var main = recievedData.isMainWarehouse;
var opt = document.createElement('option');
opt.innerHTML = name;
opt.value = id;
warehouseFragment.appendChild(opt);
}
}
warehouseDropDown.appendChild(warehouseFragment);
$('#SelectWarehouse').selectpicker('refresh');
});}
here is my dropdown
<select id="SelectWarehouse" name="SelectWarehouse" class="selectpicker show-tick form-control" data-live-search="true"></select>
This method just get the list of all the warehouses
// GET: get list of all warehouses
public async Task<ListResultOutput<WarehouseListDto>> GetWarehouses()
{
var warehouses = await _warehouseRepository.GetAllListAsync();
ListResultOutput<WarehouseListDto> dto = new ListResultOutput<WarehouseListDto>(
warehouses
.OrderBy(t => t.WarehouseName)
.ToList()
.MapTo<List<WarehouseListDto>>()
);
return dto;
}
To select the main one, you just need to set the selected property of the option for the main warehouse
function PopulateWarehouses() {
var warehouseDropDown = document.getElementById('SelectWarehouse');
var warehouseFragment = document.createDocumentFragment();
_warehouseRepository.getWarehouses().done(function (data) {
for (var element in data.items) {
if (data.items.hasOwnProperty(element)) {
var recievedData = data.items[element];
var id = recievedData.id;
var name = recievedData.warehouseName;
var main = recievedData.isMainWarehouse;
var opt = document.createElement('option');
opt.innerHTML = name;
if(main){
opt.selected = 'selected';
}
opt.value = id;
warehouseFragment.appendChild(opt);
}
}
warehouseDropDown.appendChild(warehouseFragment);
$('#SelectWarehouse').selectpicker('refresh');
});}

Javascript. Change a form option based on a previous one

I'm trying to change the options that appear in my select box named session when a certain option is picked in my select box named movie.
Here's the script I've got so far.
<script>
var optionList = document.getElementsByName("movie")[0];
var movieList = ["AC", "CH", "AF", "RC"];
for(var i = 0; i < movieList.length; i++){
var movie = movieList[i];
var option = document.createElement("option");
option.textContent = movie;
option.value = movie;
optionList.appendChild(option);
}
</script>
<script>
var sessionList = document.getElementsByName("session")[0];
var actionSession = ["WED-09", "THU-09", "FRI-09", "SAT-09", "SUN-09"];
var childrenSession = ["MON-01", "TUE-01", "WED-06", "THU-06", "FRI-06", "SAT-12", "SUN-12"];
var foreignSession = ["MON-06", "TUE-06", "SAT-06", "SUN-06"];
var romanticSession = ["MON-09", "TUE-09", "WED-01", "THU-01", "FRI-01", "SAT-06", "SUN-06"];
if(document.getElementsByName("movie")[0].value === movieList[0])
{
for(var i = 0; i < actionSession.length; i++){
var session = actionSession[i];
var option = document.createElement("option");
option.textContent = session;
option.value = session;
sessionList.appendChild(option);
}
}
</script>
Consider changing the Sessions to an object, like so:
var sessions = {
"AC": ["WED-09", "THU-09", "FRI-09", "SAT-09", "SUN-09"],
"CH": ["MON-01", "TUE-01", "WED-06", "THU-06", "FRI-06", "SAT-12", "SUN-12"],
"AF": ["MON-06", "TUE-06", "SAT-06", "SUN-06"],
"RC": ["MON-09", "TUE-09", "WED-01", "THU-01", "FRI-01", "SAT-06", "SUN-06"]
}
This way, you can use the onchange of your select tag to get the value of the selected option and reference the list of sessions for the appropriate movie list as such:
var category = document.getElementByName("movie").value;
var currentSession = sessions[category];
for(var i = 0; i < currentSession.length; i++){
var session = currentSession[i];
var option = document.createElement("option");
option.textContent = session;
option.value = session;
sessionList.appendChild(option);
}
Objects in javascript can be referenced as "key" => "value" pairs simply by following the syntax:
object = { "key": value }, and value's type can be anything - even another Object!
You can even declare object keys like such:
var sessions = {};
sessions['AC'] = [...];
sessions['CH'] = [...];
sessions.AF = [...];
sessions.RC = [...];
That's right - all of the above declarations can be referenced as sessions['xx']
Hope this simplifies things a bit.
You could create a dictionary mapping elements of movieList to lists of <option> elements, maybe?
You might call the dictionary sessionOptions. You would then change all the children of #session at once - so this would go in your onchange handler for sessionList:
var sessionList = document.getElementsByName("session")[0];
var chosenMovie = "..."; // "AC", for instance
// Remove all elements from sessionList
while(sessionList.firstChild) {
sessionList.removeChild(sessionList.firstChild);
}
// Add the chosen movie options
var chosenMovieOptions = sessionOptions[chosenMovie];
for(var i = 0; i < chosenMovieOptions.length; i++) {
sessionList.appendChild(chosenMovieOptions[i]);
}
You would also want to make a mapping of movie codes to session lists:
var SESSION_LISTS = {
"AC": ["WED-09", "THU-09", "FRI-09", "SAT-09", "SUN-09"],
"CH": ["MON-01", "TUE-01", "WED-06", "THU-06", "FRI-06", "SAT-12", "SUN-12"],
"AF": ["MON-06", "TUE-06", "SAT-06", "SUN-06"],
"RC": ["MON-09", "TUE-09", "WED-01", "THU-01", "FRI-01", "SAT-06", "SUN-06"]
};
Then, to build sessionOptions, for each "session string list" (such as actionSession), you would loop through the session list and create elements:
var currentSession = "..."; // currentSession is the current session list - "AC", for instance
var currentSessionOptions = SESSION_LISTS[currentSession];
sessionOptions[currentSession] = [];
for(var i = 0; i < currentSessionOptions.length; i++){
var session = currentSessionOptions[i];
var option = document.createElement("option");
option.textContent = session;
option.value = session;
sessionOptions[currentSession].append(option);
}
But then you would do this for every sublist in SESSION_LISTS, so you would put this code in some initializer function:
var sessions = Object.keys(SESSION_LISTS);
for(var i = 0; i < sessions.length; i++) {
currentSession = sessions[i];
// the code snippet above
}

Populating a form with names from a .txt file

I am trying to populate a dropdown list with a bunch of names that are stored in a .txt in the same directory as the HTML code. Each name is on a new line of this file and"names" is the id of the dropdown that will store the names.
Upon loading the page, the list is not populated at all. Any guidance would be awesome.
<script type = "text/javascript">
window.onload = function () {
var select = document.getElementById("names");
var textFile = "/names.txt";
jQuery.get(textFile, function(textFileData) {
var EachLineInTextFile = textFileData.responseText.split(",");
for (var i = 0, len = EachLineInTextFile.length; i < len; i++) {
var option = document.createElement('option');
option.text = option.value = EachLineInTextFile[i];
select.add(option, 0);
};
};
};
</script>
Thanks!
It looks like the major issue was that I needed a better version of jquery. Thank you everyone for your help!
<script type = "text/javascript">
window.onload = function () {
var select = document.getElementById("names");
var textFile = "/names.txt";
jQuery.get(textFile, function(textFileData) {
window.alert(textFileData);
var EachName= textFileData.split("\n");
for (var i = 0, len = EachName.length; i < len; i++) {
var option = document.createElement('option');
option.text = option.value = EachName[i];
select.add(option, 0);
};
});
};
</script>

How do I populate a select box automatically with values from a IndexedDB objectStore?

I would like to iterate over a IndexedDB objectStore, get the results and populate this select box.
This is my HTML
<tr>
<td>
<select id="opt" name="opt"></select>
</td>
</tr>
This is my JavaScript
function populateOptions() {
var options = [ "1", "2", "3", "4", "5"];
var opt = document.getElementById("opt");
for (var i = 0; i < options.length; i++) {
var option = document.createElement("option");
option.value = options[i];
var optionText = document.createTextNode(options[i]);
option.appendChild(optionText);
opt.appendChild(option);
}
}
populateOptions();
Try the following:
var dbreq = indexeddb.open("db");
dbreq.onsuccess = function (conn){
var trans = dbreq.result.transaction(["objectstore"]);
var obj = trans.objectStore("objectstore");
var cursor = obj.openCursor();
cursor.onsuccess = function (e) {
if (!cursor.result) {
var opt = document.getElementById("opt");
var option = document.createElement("option");
option.value = cursor.result.value;
var optionText = document.createTextNode(cursor.result.value);
option.appendChild(optionText);
opt.appendChild(option);
cursor["continue"]()
} else {
// cursor ended
}
}
Or use my linq2indexeddb library and do it like this:
var db = linq2indexedDB("db");
db.linq.from("objectstore").select.then(null, null, function(e){
var opt = document.getElementById("opt");
var option = document.createElement("option");
option.value = e.data;
var optionText = document.createTextNode(e.data);
option.appendChild(optionText);
opt.appendChild(option);
});
for more information about indexeddb I can reffer to my blog. Here I frequently post information about the indexedDB API.
In html :
<body onload="load()">
In javascript :
function load(){
populateOptions();
}
or shortly :
<body onload="populateOptions()">

Categories