i am building a configuration utility and having a problem with the js.
I am very new to javascript so i apologize in advance for the request for help.
in my HTML i have multiple divs that are structured like this:
<div id="options" class="opt">
<h2 id="optionName">Power Button Options</h2>
<label for="pwrAvl">Power Button Available</label>
<input type="checkbox" name="pwrAvl" id="pwrAvl"/ >
<br /><br />
<label for="pwrLabel">Power Button Label</label>
<input type="text" name="pwrLabel" id="pwrLabel"/ >
<br /><br />
<label for="pwrGraphic">Power Button Graphic</label>
<select name="pwrGraphic" id="pwrGraphic">
<option value="" selected>
----- Please select a graphic -----
</option>
<option value="power.jpeg">Power</option>
<option value="light.jpg">Light</option>
<option value="help.jpg">Help</option>
<option value="camera.jpg">Camera</option>
</select>
<br /><br />
<label for="pwrIndex">Power Button Menu Index</label>
<input type="text" name="pwrIndex" id="pwrIndex"/ >
</div>
i have between 5-10 divs that will all be structured the same way just with different labels and input values.
i tried adding all the divs to an array and then enumerate through the array but that did not work.
here is my js file what i have tried:
{
const bar = document.querySelector('options');
var opts = document.querySelectorAll('.opt')
var option = {}
var nCount = $(".opt").length;
var divArray = [];
var optName = document.getElementById('optionName');
function addArray() {
for (let i = 0; i < nCount; i++) {
divArray[i] = opts[i];
}
}
const saveBtn = document.getElementById('submit');
saveBtn.addEventListener('click', (e) => {
putSettings();
});
function SystemOptions(optionName, optionAvailable, optionLabel, optionGraphic, optionIndex) {
this.optionName = optionName;
this.optionAvailable = optionAvailable;
this.optionLabel = optionLabel;
this.optionGraphic = optionGraphic;
this.optionIndex = optionIndex;
}
async function putSettings() {
let info = {
"SystemConfiguration": {
"Options": [],
}
}
addArray()
console.log(`Divarray = ${divArray.length}`)
//The following would never work
opts.forEach(label => {
$('[id=optionName]').each(function () {
var atId = this.id;
console.log(`Searched Name = ${atId.innerHTML}`)
});
});
divArray.forEach(element => {
var name = divArray.getElementById('optionName').innerHTML;
console.log(name)
option = new SystemOptions(name, "yes", "Help Label", "Option.jpeg", 3);
info.SystemConfiguration.Options.push(option);
});
for (let i = 0; i < nCount; i++) {
// console.log(` ${$(".opt").find("h2[id=optionName").each.text()}`)
console.log(` ${divArray[i].querySelector(optName[i]).innerHTML}`)
}
// i did this once to see if the SystemsOptions function worked
// obviosly it added the same data 7 times but i was trying to be sure the function worked and created the json objects
for (let i = 1; i < nCount; i++) {
option = new SystemOptions("Power", "yes", "Help Label", "Option.jpeg", 3);
info.SystemConfiguration.Options.push(option);
}
let data = JSON.stringify(info, 0, 4);
console.log(data);
}
}
any help would be greatly appreciated.
not the most eloquent but this does work.
sure there are better ways:
var opts = document.querySelectorAll('.opt');
var option = {};
const saveBtn = document.getElementById('submit');
saveBtn.addEventListener('click', (e) => {
putSettings();
});
function SystemOptions(optionName, optionAvailable, optionLabel, optionGraphic, optionIndex) {
this.optionName = optionName;
this.optionAvailable = optionAvailable;
this.optionLabel = optionLabel;
this.optionGraphic = optionGraphic;
this.optionIndex = optionIndex;
}
async function putSettings() {
let info = {
"SystemConfiguration" :{
"Options": [],
}
};
for(var opt of opts)
{
var name = opt.getElementsByTagName('h2')[0].innerHTML;
let isAvailable = opt.getElementsByTagName("input")[0].value;
let optLabel = opt.getElementsByTagName("input")[1].value;
let optGraphic = opt.getElementsByTagName('select')[0].value;
let index = opt.getElementsByTagName("input")[2].value;
option = new SystemOptions(name, isAvailable, optLabel, optGraphic, index);
info.SystemConfiguration.Options.push(option);
}
console.log(`Number of options = ${opts.length}`)
let data = JSON.stringify(info, 0, 4);
console.log(data);
};
Related
my problem is I console log the local storage and the inputs appear fine but I can't see them on the other page although at local storage they are stored fine
the form :
<form id="formID">
<div class="Contact__Card">
<div class="Input__Container">
<label for="foodName" class="Label" >Food</label>
<input
name="foodName"
class="Input"
type="text"
placeholder="What would you like to add?"
id="foodName"
required
/>
</div>
<div class="input__Container">
<label for="foodType">Choose Food type:</label>
<select class="Input" id="foodType" name="foodlist">
<option value="Fruit and vegetables">Fruit and vegetables</option>
<option value="Starchy food">Starchy food</option>
<option value="Dairy">Dairy</option>
<option value="Protein">Protein</option>
<option value="Fat">Fat</option>
</select></div>
<div class="Input__Container">
<label for="price" class="Label">price</label>
<input type="text" min="1" step="any" class="Input" id="foodPrice" required/>
</div>
<br>
<div class="Input__Container">
<input type="submit" value="Submit" class="Input"/>
</div>
</div>
</form>
the js file of the form page :
"use strict";
var allFood = [];
function food(foodName, foodType, price) {
this.foodName = foodName;
this.foodType = foodType;
this.price = price;
allFood.push(this);
}
food.prototype.fID = function () {
this.id = Math.floor(1111 + Math.random() * 9999);
};
const formEl = document.getElementById("formID");
formEl.addEventListener("submit", handleSubmit);
function handleSubmit(event) {
event.preventDefault();
let foodName = event.target.foodName.value;
let foodType = event.target.foodType.value;
let price = event.target.foodPrice.value;
const newFood = new food(foodName, foodType, price);
newFood.fID();
saveData();
}
function saveData() {
let stringifiedData = JSON.stringify(allFood);
localStorage.setItem("Food", stringifiedData);
}
the table of the other page i want the data to apear in :
<table id="fTable">
<tr id="hdrTable">
</tr>
</table>
the js file of the output page is the issue from the get data function ?:
"use strict";
const fdTable = document.getElementById('fTable');
const tableHead = document.getElementById('hdrTable');
var allFood = [];
function food(foodName, foodType, price) {
this.foodName = foodName;
this.foodType = foodType;
this.price = price;
allFood.push(this);
}
food.prototype.fID = function () {
this.id = Math.floor(1111 + Math.random() * 9999);
};
table();
function table() {
let headerID = document.createElement("th");
headerID.textContent = "ID";
let headerName = document.createElement("th");
headerName.textContent = "Food Name";
let headerType = document.createElement("th");
headerType.textContent = "Type of Food";
let headerPrice = document.createElement("th");
headerPrice.textContent = "price";
hdrTable.appendChild(headerID);
hdrTable.appendChild(headerName);
hdrTable.appendChild(headerType);
hdrTable.appendChild(headerPrice);
}
food.prototype.Render = function () {
let row = document.createElement("tr");
let id = document.createElement("td");
let name = document.createElement("td");
let type = document.createElement("td");
let price = document.createElement("td");
id.textContent = this.id;
name.textContent = this.foodName;
type.textContent = this.foodType;
price.textContent = this.price;
row.appendChild(id);
row.appendChild(name);
row.appendChild(type);
row.appendChild(price);
fTable.appendChild(row);
};
getData();
function getData(){
let retrivedData = localStorage.getItem("stringifiedData");
let parsedData = JSON.parse(retrivedData);
if(parsedData!=null){
for (let i = 0; i < parsedData.length; i++) {
let newFoodOP = new food(
parsedData[i].foodName,
parsedData[i].foodType,
parsedData[i].price
);
}
}
for (let i = 0; i < allFood.length; i++) {
allFood[i].Render();
}
console.log(allFood);
}
I made a selectBox which had its range of values from a Google Sheet Column. I also want to take an Integer input value from the user and then write this value in a specific cell according to option taken from selectBox. The html link does not show the integer response box. Is it possible to do the above plan in a while loop? Would appreciate any ideas and correction of code
function doGet() {
var ap = SpreadsheetApp.openByUrl("Gsheet URL here");
var ui = SpreadsheetApp.getUi();
var user = ui.prompt("Put down a number");
var result = result.getSelectedButton();
var sheet = ap.getSheetByName("lv");
var values = sheet.getRange("A2:A10").getValues();
var options = values.map(function(row)
{
#To show show the selected option??
var item = options.getSelecteditem();
if (item === A3)
{
var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
var a1 = cell.getA3Notation();
var val = cell.getValue();
SpreadsheetApp.getUi().alert("Ur value is "+a1+" value is "+val);
}
{
return '<option value="' + row[0] + '">' + row[0] + '</option>';
});
var html = '<form onSubmit="handleSubmit(this)"> Type of Cuisine' + options.join('') + '</select></form>';
return HtmlService.createHtmlOutput(html);
}
Using an Html Dialog to Control User Inputs
Not sure what you wanted so here's a complete example I whipped up for you.
Code.gs:
function processInput(obj) {
Logger.log(JSON.stringify(obj));
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const [min,max,locs] = sh.getRange('B1:B3').getValues().flat();
Logger.log('min: %s max: %s locs: %s',min,max,locs)
const lA = locs.split(',');
if(obj.int > max) {
obj.msg = "Too High Try Again";
return obj;
} else if (obj.int < min) {
obj.msg = "To Low Try Again";
return obj;
} else if (!~lA.indexOf(obj.loc)) {
obj.msg = "Invalid Location";
return obj;
} else {
sh.getRange(obj.loc).setValue(obj.int);
obj.msg = "Complete";
return obj;
}
}
Following function Launches the dialog:
function launchInputDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'),"Enter Input");
}
html:
<!DOCTYPE html>
<html>
<head>
</head>
<style>input {margin: 2px 5px 2px 0;}</style>
<body>
<form>
<input type="text" id="in1" placeholder="Enter an integer" />
<br /><input type="text" id="in2" placeholder="Enter a location" />
<br /><input type="button" value="Process" onClick="processinput();" />
</form>
<div id="msg"></div>
<script>
function processinput() {
document.getElementById("msg").innerHTML = '';
let v1 = parseInt(document.getElementById('in1').value);
let v2 = document.getElementById('in2').value;
let obj = {int:v1,loc:v2,msg:''};
google.script.run
.withSuccessHandler(robj => {
console.log(JSON.stringify(robj))
if(robj.msg == "Complete") {
document.getElementById("msg").innerHTML = `Value: ${robj.int} Location: ${robj.loc} Try Again`;
document.getElementById("in1").value = '';
document.getElementById("in2").value = '';
} else {
document.getElementById("msg").innerHTML = robj.msg;
}
})
.processInput(obj);
}
</script>
</body>
</html>
Short Demo:
This version uses a <select> tag to allow the user to determine where the data will be loaded
GS:
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
sh.getRange(data.loc).setValue(data.id)
}
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params = { "contentType": "application/json", "payload": JSON.stringify(obj), "muteHttpExceptions": true, "method": "post", "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
UrlFetchApp.fetch(url, params);
}
function displayError(msg) {
SpreadsheetApp.getUi().alert(msg);
}
function launchMyDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'My Dialog');
}
function getSelectOptions() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName('Options');
var rg = sh.getDataRange();
var vA = rg.getValues();
var options = [];
for (var i = 0; i < vA.length; i++) {
options.push(vA[i][0]);
}
return vA;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
<input type="text" id="txt1" name="id" placeholder="Enter Numbers only"/>
<select id="sel1" name="loc"></select>
<input type="button" value="submit" onClick="processForm(this.parentNode);" />
</form>
<script>
function processForm(obj) {
console.log(obj.id.value);
if(obj.id.value.match(/[A-Za-z]/)) {
google.script.run.displayError("Invalid Characters Found in id field");
} else {
google.script.run.sendData(obj);
}
}
window.onload = function() {
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();
}
function updateSelect(vA) {
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<vA.length;i++) {
select.options[i] = new Option(vA[i],vA[i]);
}
}
</script>
</body>
</html>
Demo:
I have a table form with some rows, that are controlled by user. Meaning they can add as more as they want. Let's pretend user requested 5 rows and i need to check if they all have values.
function validateForm() {
var lastRowInserted = $("#packageAdd tr:last input").attr("name"); // gives me "packageItemName5"
var lastCharRow = lastRowInserted.substr(lastRowInserted.length - 1); // gives me 5
var i;
for (i = 1; i <= lastCharRow; i++) {
var nameValidate[] = document.forms["packageForm"]["packageItemName"].value;
if(nameValidate[i].length<1){
alert('Please fill: '+nameValidate[i]);
return false;
}
}
}
How can i receive packageItemName1 to 5 values in a loop so then I can use to validate them. Want the loop to process this code
var nameValidate[] = document.forms["packageForm"]["packageItemName1"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName2"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName3"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName4"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName5"].value;
Like this
const validatePackageItems = () => {
const nameValidate = $("form[name=packageForm] input[name^=packageItemName]"); // all fields with name starting with packageItemName
const vals = nameValidate.map(function() { return this.value }).get(); // all values
const filled = vals.filter(val => val.trim() !== ""); // all values not empty
console.log("Filled", filled, "= ", filled.length, "filled of", vals.length)
return filled.length === vals.length
};
$("[name=packageForm]").on("submit",(e) => {
if (!validatePackageItems()) {
alert("not valid");
e.preventDefault();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="packageForm">
<input type="text" name="packageItemName1" value="one" /><br/>
<input type="text" name="packageItemName2" value="two" /><br/>
<input type="text" name="packageItemName3" value="" /><br/>
<input type="text" name="packageItemName4" value="four" /><br/>
<input type="submit">
</form>
You can use string interpolation to get the key dynamically:
for (let i = 1; i < 6; i++) {
const currentValue = document.forms.packageForm[`packageItemName${i}`]
console.log('current value:', currentValue)
}
I have created a custom selector system with JS trying to make it look better. It looks perfect and changes the selector when I make it visible, but it doesn't changes my ngModel at my Angular component, keeping it at undefined. Here is my JS and HTML.
<div class="form__select">
<select id="gender" name="gender" #gender="ngModel" [(ngModel)]="user.occupation">
<option value="0">Selecciona un género</option>
<option value="1">Hombre</option>
<option value="2">Mujer</option>
<option value="3">Otro</option>
</select>
</div>
load_selector() {
const selectors: HTMLCollectionOf<Element> = document.getElementsByClassName("form__select");
document.addEventListener("click", MainScript.close_selector);
[].forEach.call(selectors, (selector) => {
const select: any = selector.getElementsByTagName("select")[0];
let replaced: HTMLElement = document.createElement("DIV");
replaced.setAttribute("class", "form__select-box");
replaced.innerHTML = select.options[select.selectedIndex].innerHTML;
selector.appendChild(replaced);
let option_parent: HTMLElement = document.createElement("DIV");
option_parent.setAttribute("class", "form__select-items");
[].forEach.call(select.options, (options) => {
let option: HTMLElement = document.createElement("DIV");
option.setAttribute("class", "form__select-item");
option.innerHTML = options.innerHTML;
option.addEventListener("click", function () {
const parent_node: any = (<HTMLElement>(<HTMLElement>(<HTMLElement>this.parentNode)).parentNode).getElementsByTagName("select")[0];
let previous_sibling: any = this.parentNode.previousSibling;
for (let i = 0; i < parent_node.length; i++) {
if (parent_node.options[i].innerHTML == this.innerHTML) {
parent_node.selectedIndex = i;
previous_sibling.innerHTML = (<HTMLElement>this).innerHTML;
let actual_selected = (<HTMLElement>(<HTMLElement>this.parentNode)).getElementsByClassName("form__select-item--selected");
[].forEach.call(actual_selected, (node) => {
node.classList.remove("form__select-item--selected");
node.classList.add("class", "form__select-item");
});
this.classList.add("form__select-item--selected");
}
}
previous_sibling.click();
});
option_parent.appendChild(option);
});
selector.appendChild(option_parent);
replaced.addEventListener("click", function (e) {
e.stopPropagation();
(<any>this).nextSibling.classList.toggle("form__select-items--active");
(<any>this).classList.toggle("form__select-box--active");
});
});
}
I have a select with options that I am putting into an array, and I am attempting to alert a specific message when you click a button, but only if the proper array[x] has been selected. However, when I click the button, regardless of the option I get the message. What am I doing wrong?
Code:
HTML:
<button id="button">Click Me</button>
<br />
<br />
<select id = "list" value = "list">
<option id="one" value="one">
one
</option>
<option id="two" value="two">
two
</option>
<option id="three" value="three">
three
</option>
</select>
JS:
var listArr = [];
var button = document.getElementById("button");
var list = document.getElementById("list");
var selected = document.getElementById("list").selectedIndex;
for (var i = 0; i < list.options.length; i++) {
listArr[i] = list.options[i].value;
}
button.onclick = function() {
if (selected = [1]) {
alert("hello");
}
};
You cannot compare arrays like this. You need to use literal number instead. JSFiddle
var listArr = [];
var button = document.getElementById("button");
var list = document.getElementById("list");
var selected = document.getElementById("list");
for(var i = 0; i < list.options.length; i++) {
listArr[i] = list.options[i].value;
}
button.onclick = function() {
if(selected.selectedIndex == 1) {
alert('hello');
}
};
If I have understood your question correctly, you need the updated value of the select:
button.onclick = function()
{
if(document.getElementById("list").selectedIndex==1) // Also change = to ==
{
alert("hello");
}
};
https://jsfiddle.net/6bs1vjva/1/