I'm trying to make an alert with the value of the selected radio button, but I allways get the first of them, regardless the one I choose...(Acompanhado);
html:
<form/>
<input type="radio" class="simple_form" name="grupo_1" value="Acompanhado" id="saida"/>
<span class="texto">Acompanhado</span>
<input type="radio" class="simple_form" name="grupo_1" value="Individual" id="saida"/>
<span class="texto">Individual</span>
</form>
js:
function save() {
var saida_js = document.getElementById('saida').value;
alert("Tipo de saida: " + saida_js);
}
Any idea ?
#Quentin: I have alot of alerts, cause Im trying to get all data from a form. I used your code, and I get no alert at all.
function save() {
var morada_js = document.getElementById('morada').value;
var data_js = document.getElementById('data').value;
var hora_js = document.getElementById('hora').value;
var radio_saida = document.getElementsByName('name_saida');
var notas_js = document.getElementById('notas').value;
var condicoes_atm_js = document.getElementById('condicoes_atm').value;
alert("Morada: " + morada_js);
alert("Data: " + data_js);
alert("Hora: " + hora_js);
function get_checked_radio(radio_saida) {
for (var i = 0; i < radio_saida.length; i++) {
var current = radio_saida[i];
if (current.checked) {
return current;
}
}
}
alert(get_checked_radio(radio_saida).value);
alert("Notas: " + notas_js);
}
An id must be unique in a document.
To find the value of a selected radio button in a group, get the group by its nameā¦
var radios = document.getElementsByName('radio_name'); // or
var radios = document.forms.formId.elements.radio_name;
Then loop over them until you find the one with the true checked property.
function get_checked_radio(radios) {
for (var i = 0; i < radios.length; i++) {
var current = radios[i];
if (current.checked) {
return current;
}
}
}
alert(get_checked_radio(radios).value);
Makes sense because you've got two input tags with the same id saida
Related
I am a beginner in google app script. So right now I am doing a project where users can sign in and can view their payment history. So for now it is just showing from 2020 until 2021. So I want your guys help on creating a dropdown box which states (eg : 2020 , 2021 ) so maybe if the user clicks 2020 then they can see the payment history of 2020 only. I really need your guys help in this thing. I have attached the link to my google app script and a image to explain myself better. Thank you guys.
https://script.google.com/d/1DdRKqUX__-ZITUgTZanQ_A7hUL1kcc0TZOeFmn58wYsX_o_7cqNExnYo/edit?usp=sharing - Link to my appscript
First image
Second Image
Here is a sample code you can refer with:
WebAppLogin.html (modifications)
<script>
function GetRecords() {
var spin = "<span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>";
spin += " Loading...";
document.getElementById("LoginButton").innerHTML = spin;
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
google.script.run.withSuccessHandler(function(output) {
console.log(output);
var username = output[1];
var name = output[2];
if(output[0] == 'TRUE') {
document.getElementById("errorMessage").innerHTML = "";
document.getElementById("currentUser").value = username;
google.script.run.withSuccessHandler(displayTable).GetRecords(username,"None");
} else if(output[0] == 'FALSE') {
document.getElementById("firstLastName").innerHTML = "";
document.getElementById("currentUser").value = "";
document.getElementById("myFilter").innerHTML = "";
document.getElementById("errorMessage").innerHTML = "Failed to Login";
document.getElementById("LoginButton").innerHTML = "Login";
}
}).checkLogin(username, password);
}
function filter(){
var filterStr = document.getElementById("filterYear").value;
var user = document.getElementById("currentUser").value;
google.script.run.withSuccessHandler(displayTable).GetRecords(user,filterStr);
}
function displayTable(result) {
var ar = result.data;
var filterString = result.filter;
var username = document.getElementById("currentUser").value;
if(ar.length > 0) {
var displayTable = '<table class=\"table\" id=\"mainTable\" >';
displayTable += "<tr>";
displayTable += "<th>Month</th>";
displayTable += "<th>House Number</th>";
displayTable += "<th>Street</th>";
displayTable += "<th>Payment Status</th>";
displayTable += "</tr>";
ar.forEach(function(item, index) {
displayTable += "<tr>";
displayTable += "<td>"+item[0]+"</td>";
displayTable += "<td>"+item[1]+"</td>";
displayTable += "<td>"+item[2]+"</td>";
displayTable += "<td>"+item[3]+"</td>";
displayTable += "</tr>";
});
displayTable += "</table>";
} else {
var displayTable = "<span style=\"font-weight: bold\" >No Records Found</span>";
}
var filter = '';
if(filterString.length > 0) {
filter += '<label for="years" style="font-size: 20px">Years</label><br><select class="form-control form-control-sm" id="filterYear" name="years" required><option value="" selected>Choose...</option>';
filterString.forEach(str => {
filter += '<option value="'+str+'">'+str+'</option>';
});
filter += '</select><button class="btn btn-primary" type="button" id="FilterButton" onclick="filter()" >Submit</button>';
}
//var filter = '<label for="years" style="font-size: 20px">Years</label><br><select class="form-control form-control-sm" id="filterYear" name="years" required><option value="" selected>Choose...</option><option value="2020">2020</option><option value="2021">2021</option></select><button class="btn btn-primary" type="button" id="FilterButton" onclick="filter()" >Submit</button>';
document.getElementById("digitalgoods-030521182921-1").style.display = "block";
document.getElementById("displayRecords").innerHTML = displayTable;
document.getElementById("firstLastName").innerHTML = "USER: " + name;
document.getElementById("myFilter").innerHTML = filter;
document.getElementById("LoginButton").innerHTML = "Login";
document.getElementById("username").value = '';
document.getElementById("password").value = '';
}
</script>
<div>
<h2 id="firstLastName">
</h2>
</div>
<input type="hidden" id="currentUser" value=""/>
<div id ="myFilter" class="form-group">
</div>
</div>
<div id="displayRecords" style="padding: 10px;" >
</div>
Modifications done:
Include empty form-group class
Include hidden input to hold current logged-in user
Create a reusable function displayTable()
Create an html content for the drop-down filter. See variable filter.
Include another argument when calling GetRecords(username, filter)
Create a new function filter()
During initial log-in, filter will be set to "None". filter will be set depending on the option selected
Code.gs (modifications)
function GetRecords(username,filter) {
var filteredDataRangeValues = GetUsernameAssociatedProperties(username);
var resultArray = GetPaymentRecords(filteredDataRangeValues,filter);
var resultFilter = getYears();
result = {
data: resultArray,
filter: resultFilter
};
return result;
}
function getYears() {
var ss= SpreadsheetApp.openByUrl(url);
var yearSheet = ss.getSheetByName("Configuration");
var getLastRow = yearSheet.getLastRow();
var return_array = [];
for(var i = 2; i <= getLastRow; i++)
{
if(return_array.indexOf(yearSheet.getRange(i, 2).getDisplayValue()) === -1) {
return_array.push(yearSheet.getRange(i, 2).getDisplayValue());
}
}
return return_array;
}
function GetPaymentRecords(userProperties,filter) {
var transpose = m => m[0].map((_, i) => m.map(x => x[i]));
var resultArray = [];
var ss = SpreadsheetApp.openByUrl(url);
var displaySheet = ss.getSheetByName(streetSheetName);
var addressValues = displaySheet.getRange("B:C").getValues();
var paidMonthValues = displaySheet.getRange("G:AD").getValues();
//Logger.log(addressValues);
//Logger.log(transpose(paidMonthValues));
userProperties.forEach((v, i) => {
var userHouseNumber = v[1];
var userStreet = v[2];
var column = addressValues.reduce(function callbackFn(accumulator, currentValue, index, array) {
if (currentValue[0] == userHouseNumber && currentValue[1] == userStreet) {
return index
} else {
return accumulator
}
}, '');
//Logger.log(column);
Logger.log(filter)
Logger.log(paidMonthValues);
if(filter=="None"){
var result = transpose(paidMonthValues).map(function callbackFn(element, index, array) {
return [element[0], userHouseNumber, userStreet, element[column] || '']
});
}else{
var result = transpose(paidMonthValues).map(function callbackFn(element, index, array) {
if(element[0].includes(filter))return [element[0], userHouseNumber, userStreet, element[column] || '']
});
}
resultArray = resultArray.concat(result);
//Logger.log(resultArray);
})
//Remove null elements
resultArray = resultArray.filter(element=>{
Logger.log(element!=null)
return element != null;
});
return resultArray;
}
Modifications done:
Modified GetRecords() and GetPaymentRecords() to include filter option
Add removal of null elements in the resultArray. (Null elements may exist when filter option was used due to the map() used)
Output:
(After user logged-in)
(After user selects a filter)
(UPDATE):
The following modifications where done to create a drop-box based on the list of years available in the configuration sheet.
WebAppLogin.html
displayTable() was modified that will accept an object as its parameter which contains an array data and an array of filter strings.
displayTable() was modified to update the drop-down options based on the filter strings available
Code.gs
getYears() was added that will read the sheet "Configuration" to get the filter string values
GetRecords() was modified to return an object which contains an array of record data and an array of filter strings.
Filters work correctly as separate filters only i.e. if a user filters in "packages", it will filter as required or if a user filters "Nights" it will filter as required.
If a user wants to filter by two or more filters,rather than return the correct results, it will return the results for the last filtered only
i.e. If a user filters by Package:Silver and Nights:3, it should return four results, not 12.
The requirement is to return the exact results based on all filters chosen by the user.
The 's are from line 65 - 67 and the is from line 2243 - 2292.
It would be a bonus if the "number of people" input was a drop down form with values 1, 2, 3, 4 , but that's not a requirement at this point.
Code too large to paste, see link Table 1
You might wanna combine 3 functions into 1 because they look almost identical.
function filter() {
var filter_package = document.getElementById("myInput").value.toUpperCase().trim();
var filter_num_nights = document.getElementById("myInput1").value.toUpperCase().trim();
var filter_num_people = document.getElementById("myInput2").value.toUpperCase().trim();
var rows = document.querySelectorAll("tr");
// First few rows are headers
for (var i = 2; i < rows.length; i++) {
var items = rows[i].querySelectorAll("td");
if (items.length === 0) continue;
var pkg = items[0];
var night = items[1];
var people = items[2];
var package_text = pkg.innerHTML.toUpperCase().trim();
var night_text = night.innerHTML.toUpperCase().trim();
var people_text = people.innerHTML.toUpperCase().trim();
if (package_text.includes(filter_package) &&
night_text.includes(filter_num_nights) &&
people_text.includes(filter_num_people)) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
and modify the keyup events for the input boxes like below:
<input type="text" id="myInput" onkeyup="filter()" placeholder="Search for Packages.." title="Type in a Package name">
<input type="text" id="myInput1" onkeyup="filter()" placeholder="Search for Number of Nights.." title="Type in Number of Nights">
<input type="text" id="myInput2" onkeyup="filter()" placeholder="Search for Number of People.." title="Type in Number of People">
Please note
If your browser does not support string.includes naively then you can copy and paste the following polyfill into your javascript code. (ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/includes):
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
I am trying to make a google script web app that takes input from an HTML form and passes the input to a script. Right now, the function is failing because document.getelementbyId('text') returns null instead of the actual form value. How can I fix this?
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit() {
var formObject = document.getElementById('text');
google.script.run.withSuccessHandler(setTable).getSportData(formObject);
console.log(formObject);
}
function setTable(data) {
var div = document.getElementById('output');
div.innerHTML = createTable(data);
}
/**
* Adds an html table
*/
function createTable(tableData) {
var table = document.createElement('table');
var tableBody = document.createElement('tbody');
tableData.forEach(function(rowData) {
var row = document.createElement('tr');
rowData.forEach(function(cellData) {
var cell = document.createElement('td');
cell.appendChild(document.createTextNode(cellData));
row.appendChild(cell);
});
tableBody.appendChild(row);
});
table.appendChild(tableBody);
document.body.appendChild(table);
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit()">
<input name="text" type="text" />
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
</body>
</html>
Code.gs
//Initalization of global variables for use by the script's custom functions
var ss = SpreadsheetApp.openById("spreadsheetID");
var sheet = ss.getSheetByName("Sheet1");
var sportsFromSheet = sheet.getRange("D4:D12");
var namesFromSheet = sheet.getRange("B4:B12").getValues();
var timesFromSheet = sheet.getRange("A4:A12").getValues();
var NAMES = [];
var TIMES = [];
/**
* Handles HTTP GET requests to the published web app.
* #return {HtmlOutput} The HTML page to be served.
*/
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
/**
* Gets both names and Times of checked-in people from the spreadsheet from the private function getOutput.
* #return {HtmlOutput} A 2D array containing the names and times.
*/
function getSportData(formObject) {
getNamesInSport(formObject);
getTimesInSport(formObject);
var OUTPUT = [
[NAMES],
[TIMES]
];
return OUTPUT;
}
//Puts the names of every person from an inputted sport into an array.
function getNamesInSport(input) {
var data = sportsFromSheet.getValues();
for (var i = 0; i < data.length; i++) {
if(data[i] == input){
NAMES.push(namesFromSheet[i][0]);
}
}
}
//Puts the times of every person from an inputted sport into an array.
function getTimesInSport(input){
var data = sportsFromSheet.getValues();
for (var i = 0; i < data.length; i ++) {
if(data[i] == input){
TIMES.push(timesFromSheet[i][0]);
}
}
}
Duplicate of Why does jQuery or a DOM method such as getElementById not find the element?.
You appear to have answered your own question.
document.getElementById('text') returns null because...
You don't have an element with an id="text".
document.getElementById will return null
if an element with the specified ID is not in the document. (Mozilla Developer Network)
The solution, is <input type="text" name="text" id="text">
i having problem giving a unique id for each checkbox selected. i not sure am i doing it correctly already. I cant print the selected checkbox onto the view-attraction.html
all-attraction.html
<input type="checkbox" ng-model=a.selected value={{a.attractionName}} name={{a.attractionName}} id={{a.id}}>
attraction.js
$scope.selectAttraction = function()
{
var selected = '';
for (var i = 0; i < attractions.length; i++) {
if(attraction[i].selected){
selected += attraction[i].attractionName;
}
}
};
view-attraction.html
<p><img src={{"../img/"+a.attractionImg}} style="width:250px;height:250px;"/></p>
<p>Attraction Name: {{a.attractionName}}</p>
<p>Selected: {{a.selected}}</p>
https://jsfiddle.net/zcm2LLo8/
I am trying to get a list to populate from a spreadsheet based on the question posted here Previous questioe posted by #Kron011and I'm struggling somewhat. I added these lines to my .gs file:
function getMenuListOne(){
return SpreadsheetApp.openbyId('spreadsheet_key').getSheetByName('sheet1')
.getRange(row, column, numRows, numColumns).getValues();
}
and I added these lines to my HTML file:
<select id="menu">
<option></option>
<option>Google Chrome</option>
<option>Firefox</option>
</select>
<script
src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
// The code in this function runs when the page is loaded.
$(function() {
google.script.run.withSuccessHandler(showThings)
.getMenuListFromSheet();
google.script.run.withSuccessHandler(showMenu)
.getMenuListFromSheet();
});
function showThings(things) {
var list = $('#things');
list.empty();
for (var i = 0; i < things.length; i++) {
list.append('<li>' + things[i] + '</li>');
}
}
function showMenu(menuItems) {
var list = $('#menu');
list.find('option').remove(); // remove existing contents
for (var i = 0; i < menuItems.length; i++) {
list.append('<option>' + menuItems[i] + '</option>');
}
}
</script>
As ever my painfully limited experience is hampering my efforts. I can get a new menu box to appear and show the correct results I want but I cannot get an existing box to show the same list. The existing boxes code is currently:
<input type="text" name="site" list="depotslist" id="site" class="form-control" placeholder="Select depot/site" required>
<datalist id="depotslist">
<option value="one">
<option value="two">
</datalist>
but can someone please point me in the right direction of which parts of my existing menu box I need to change to get the two bits to communicate?
UPDATE 23 JULY
I added the following code to get the another list to operate from another source:
$(function() {
google.script.run.withSuccessHandler(showThings2)
.getMenuListSources();
google.script.run.withSuccessHandler(showMenu2)
.getMenuListSources();
});
function showThings2(things2) {
var list2 = $('#things2');
list.empty();
for (var i = 0; i < things2.length; i++) {
list2.append('<li>' + things2[i] + '</li>');
}
}
function showMenu2(menuItems2) {
var list2 = $('#menu2');
var box2 = $('#sourcelist');
list2.find('option').remove(); // remove existing contents
for (var i = 0; i < menuItems2.length; i++) {
list2.append('<option>' + menuItems2[i] + '</option>');
box2.append('<option>' + menuItems2[i] + '</option>');
}
}
with these lines in the .gs file:
var Bvals = SpreadsheetApp.openById(ssKey).getSheetByName('SourceCodes').getRange("C3:C").getValues();
var Blast = Avals.filter(String).length;
return SpreadsheetApp.openById(ssKey).getSheetByName('SourceCodes').getRange(3,3,Blast,1).getValues();
It would be similar to what you are doing with the element "menu". with jquery you can select the element of the box that contains the options and then append the new values. in this case it's id is: depotslist.
function showMenu(menuItems) {
var list = $('#menu');
var box = $('#depotslist');
list.find('option').remove(); // remove existing contents
for (var i = 0; i < menuItems.length; i++) {
list.append('<option>' + menuItems[i] + '</option>');
box.append('<option>' + menuItems[i] + '</option>');
}
As a difference with the element "menu" in this case the content will remain. This means that in the box you will see the options "one, two" and whatever you added because we are not removing the content like with this line
list.find('option').remove();
I'm not sure if this is exactly what you wanted to do, let me know if this doesn't help.