I'm trying to adapt this model. It is an HTML table that retrieves data from a Google table. However, I need the search to be done in a specific column. In this model, the search is performed in any column.
I've tried a few options, but to no avail. I believe it is necessary to change the function search or the function createTable.
This is my code:
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate();
}
/* PROCESS FORM */
function processForm(formObject){
var result = "";
if(formObject.searchtext){//Execute if form passes search text
result = search(formObject.searchtext);
}
return result;
}
//SEARCH FOR MATCHED CONTENTS
function search(searchtext){
var spreadsheetId = 'XXXXXXXXXXXXXXXXXXXXXXXXX'; //** CHANGE !!!
var dataRage = 'Data!A2:Y'; //** CHANGE !!!
var data = Sheets.Spreadsheets.Values.get(spreadsheetId, dataRage).values;
var ar = [];
data.forEach(function(f) {
if (~f.indexOf(searchtext)) {
ar.push(f);
}
});
return ar;
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o" crossorigin="anonymous"></script>
<!--##JAVASCRIPT FUNCTIONS ---------------------------------------------------- -->
<script>
//PREVENT FORMS FROM SUBMITTING / PREVENT DEFAULT BEHAVIOUR
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, true);
//HANDLE FORM SUBMISSION
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(createTable).processForm(formObject);
document.getElementById("search-form").reset();
}
//CREATE THE DATA TABLE
function createTable(dataArray) {
if(dataArray && dataArray !== undefined && dataArray.length != 0){
var result = "<table class='table table-sm table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Change table headings to match witht he Google Sheet
"<th scope='col'>ORDERNUMBER</th>"+
"<th scope='col'>QUANTITYORDERED</th>"+
"<th scope='col'>PRICEEACH</th>"+
"<th scope='col'>ORDERLINENUMBER</th>"+
"<th scope='col'>SALES</th>"+
"<th scope='col'>ORDERDATE</th>"+
"<th scope='col'>STATUS</th>"+
"<th scope='col'>QTR_ID</th>"+
"<th scope='col'>MONTH_ID</th>"+
"<th scope='col'>YEAR_ID</th>"+
"<th scope='col'>PRODUCTLINE</th>"+
"<th scope='col'>MSRP</th>"+
"<th scope='col'>PRODUCTCODE</th>"+
"<th scope='col'>CUSTOMERNAME</th>"+
"<th scope='col'>PHONE</th>"+
"<th scope='col'>ADDRESSLINE1</th>"+
"<th scope='col'>ADDRESSLINE2</th>"+
"<th scope='col'>CITY</th>"+
"<th scope='col'>STATE</th>"+
"<th scope='col'>POSTALCODE</th>"+
"<th scope='col'>COUNTRY</th>"+
"<th scope='col'>TERRITORY</th>"+
"<th scope='col'>CONTACTLASTNAME</th>"+
"<th scope='col'>CONTACTFIRSTNAME</th>"+
"<th scope='col'>DEALSIZE</th>"+
"</tr>"+
"</thead>";
for(var i=0; i<dataArray.length; i++) {
result += "<tr>";
for(var j=0; j<dataArray[i].length; j++){
result += "<td>"+dataArray[i][j]+"</td>";
}
result += "</tr>";
}
result += "</table>";
var div = document.getElementById('search-results');
div.innerHTML = result;
}else{
var div = document.getElementById('search-results');
//div.empty()
div.innerHTML = "Data not found!";
}
}
</script>
<!--##JAVASCRIPT FUNCTIONS ~ END ---------------------------------------------------- -->
</head>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">CPF</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Digite seu CPF">
</div>
<button type="submit" class="btn btn-primary mb-2">Pesquisar</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
Here's a html template that calls a function that returns a 2D array from a spreadsheet
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="tabledata">
<? var vs = lfunko ?>
<table>
<? vs.forEach((r,i)=>{ ?>
<tr>
<? r.forEach((c,j)=>{ ?>
<? if(i == 0) { ?>
<th style="padding:2px 5px;font-weight:bold;border:1px solid black;"><?= c ?> </th>
<? } else { ?>
<td style="padding:2px 5px;border:1px solid black;"><?= vs[i][j] ?> </td>
<? } ?>
<? }); ?>
</tr>
<? }); ?>
</table>
</div>
</body>
</html>
Related
I tried to create a table in jQuery with Create, Update, Edit and Delate row functions. I need to save the data in local storage. The table must have a column wise filter and sorting.
When I run the application the table header and first row should be displayed. The first row includes some sample data. What are the changes I need to make?
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="container">
<div class="form-row">
<div class="col-md-3">
<label>Name <span class="errdiv"> *</span></label>
<input id="txtName" type="text" class="form-control txt txtName" placeholder="Enter Name" required>
<input id="txtId" type="hidden" class="form-control txt">
</div>
<div class="col-md-3 col-sm-6 col-6">
<label>Contact No <span class="errdiv"> *</span></label>
<input id="txtContact" data-type="number" type="text" minlength="10" maxlength="10" class="form-control txt txtContact" placeholder="Contact No" required>
</div>
<div class="col-md-3 col-sm-6 col-6">
<label>Alt Contact No</label>
<input id="txtAltNo" type="text" class="form-control txt txtAltNo" minlength="10" maxlength="10" placeholder="Alt Contact No">
</div>
</div>
<div class="form-row">
<div class="col-md-6 col-sm-7">
<label>Address <span class="errdiv"> *</span></label>
<textarea id="txtAddress" class="form-control txt txtAddress" rows="3" minlength="15" placeholder="Enter Address" required></textarea>
</div>
</div>
<div class="row pt-2">
<div class="col-md-2">
<button type="button" class="btn btn-success" id="btnSave">Save</button>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-secondary" id="btnClear">Clear</button>
</div>
</div>
<div class="row pt-3">
<div class="col-md-12 col-sm-12 col-12 p-2 ">
<table id="tblData" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th> Name</th>
<th>Phone</th>
<th>Alt Phone</th>
<th>Address</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
var emptyRow = "<tr><td colspan='6' class='text-center'> No Records Available</td></tr>";
$(document).ready(function() {
loadDataFromLocal();
$('#tblData').on('click', '.btn-edit', function() {
debugger;
const name = $(this).parent().parent().find(".txtName").html();
const contact = $(this).parent().parent().find(".txtContact").html();
const altContact = $(this).parent().parent().find(".txtAltNo").html();
const address = $(this).parent().parent().find(".txtAddress").html();
const id = $(this).parent().parent().find(".txtName").attr("data-id");
$("#txtName").val(name);
$("#txtContact").val(contact);
$("#txtAltNo").val(altContact);
$("#txtAddress").val(address);
$("#txtId").val(id);
$("#btnSave").text("Update");
});
$('#tblData').on('click', '.btn-delete', function() {
debugger;
const id = $(this).parent().parent().find(".txtName").attr("data-id");
deleteDataFromLocal(id);
});
$("#btnSave").click(function() {
debugger;
if ($("#txtId").val() == '') {
addDataToLocal();
} else {
updateDataFromLocal();
}
});
$("#btnClear").click(function() {
debugger;
clearForm();
});
});
function clearForm() {
debugger;
$("#txtName").val("");
$("#txtContact").val("");
$("#txtAltNo").val("");
$("#txtAddress").val("");
$("#btnSave").text("Add");
}
function addEmptyRow() {
debugger;
if ($("#tblData tbody").children().children().length == 0) {
$("#tblData tbody").append(emptyRow);
}
}
function loadDataFromLocal() {
debugger;
let localData = localStorage.getItem('localData');
if (localData) {
$("#tblData tbody").html("");
let localArray = JSON.parse(localData);
let index = 1;
localArray.forEach(element => {
let dynamicTR = "<tr>";
dynamicTR = dynamicTR + "<td> " + index + "</td>";
dynamicTR = dynamicTR + "<td class='txtName' data-id=" + element.id + ">" + element.name + "</td>";
dynamicTR = dynamicTR + "<td class='txtContact'>" + element.contact + "</td>";
dynamicTR = dynamicTR + "<td class='txtAltNo'>" + element.altContact + "</td>";
dynamicTR = dynamicTR + "<td class='txtAddress'>" + element.address + "</td>";
dynamicTR = dynamicTR + " <td class='tdAction text-center'>";
dynamicTR = dynamicTR + " <button class='btn btn-sm btn-success btn-edit'> Edit</button>";
dynamicTR = dynamicTR + " <button class='btn btn-sm btn-danger btn-delete'> Delete</button>";
dynamicTR = dynamicTR + " </td>";
dynamicTR = dynamicTR + " </tr>";
$("#tblData tbody").append(dynamicTR);
index++;
});
}
addEmptyRow();
}
function addDataToLocal() {
debugger;
let localData = localStorage.getItem('localData');
if (localData) {
let localArray = JSON.parse(localData);
const obj = {
id: localArray.length + 1,
name: $("#txtName").val(),
contact: $("#txtContact").val(),
altContact: $("#txtAltNo").val(),
address: $("#txtAddress").val()
};
localArray.push(obj);
localStorage.setItem('localData', JSON.stringify(localArray));
loadDataFromLocal();
} else {
const arryObj = [];
const obj = {
id: 1,
name: $("#txtName").val(),
contact: $("#txtContact").val(),
altContact: $("#txtAltNo").val(),
address: $("#txtAddress").val()
};
arryObj.push(obj);
localStorage.setItem('localData', JSON.stringify(arryObj));
loadDataFromLocal();
}
clearForm();
}
function updateDataFromLocal() {
debugger;
let localData = localStorage.getItem('localData');
let localArray = JSON.parse(localData);
const oldRecord = localArray.find(m => m.id == $("#txtId").val());
oldRecord.name = $("#txtName").val();
oldRecord.contact = $("#txtContact").val();
oldRecord.altContact = $("#txtAltNo").val();
oldRecord.address = $("#txtAddress").val();
localStorage.setItem('localData', JSON.stringify(localArray));
loadDataFromLocal();
clearForm();
}
function deleteDataFromLocal(id) {
debugger;
let localData = localStorage.getItem('localData');
let localArray = JSON.parse(localData);
let i = 0;
while (i < localArray.length) {
if (localArray[i].id === Number(id)) {
localArray.splice(i, 1);
} else {
++i;
}
}
localStorage.setItem('localData', JSON.stringify(localArray));
loadDataFromLocal();
}
So I have this GAS Web app that lets you search for an ID, and it pulls the data next to that ID from the spreadsheet and then displays it on a data table right under the form elements
This is the code I have for the HTML file
The thing is the info for some columns is just 2 or 3 digits and for others there may be a couple of words, so there is quite some variance in width for the columns
Id been trying to adjust the width to 16.66% (I have 6 columns) but I cant make it work, any ideas?
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o" crossorigin="anonymous"></script>
<!--##JAVASCRIPT FUNCTIONS ---------------------------------------------------- -->
<script>
//PREVENT FORMS FROM SUBMITTING / PREVENT DEFAULT BEHAVIOUR
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, true);
//HANDLE FORM SUBMISSION
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(createTable).processForm(formObject);
document.getElementById("search-form").reset();
}
//CREATE THE DATA TABLE
function createTable(dataArray) {
if(dataArray && dataArray !== undefined && dataArray.length != 0){
var result = "<table class='table-responsive table-sm table-bordered table-striped' id='dtable' style='font-size:0.8em'>"+
"<thead style='white-space: nowrap'>"+
"<tr>"+ //Change table headings to match witht he Google Sheet
"<th scope='col'>-</th>"+
"<th scope='col'>-</th>"+
"<th scope='col'>-</th>"+
"<th scope='col'>-</th>"+
"<th scope='col'>-</th>"+
"<th scope='col'>-</th>"+
"</tr>"+
"</thead>";
for(var i=0; i<dataArray.length; i++) {
result += "<tr>";
for(var j=0; j<dataArray[i].length; j++){
result += "<td>"+dataArray[i][j]+"</td>";
}
result += "</tr>";
}
result += "</table>";
var div = document.getElementById('search-results');
div.innerHTML = result;
}else{
var div = document.getElementById('search-results');
//div.empty()
div.innerHTML = "Data not found!";
}
}
</script>
<!--##JAVASCRIPT FUNCTIONS ~ END ---------------------------------------------------- -->
</head>
<body>
<div class="container">
<br>
<div class="row">
<div class="col">
<!-- ## SEARCH FORM ------------------------------------------------ -->
<form id="search-form" class="form-inline" onsubmit="handleFormSubmit(this)">
<div class="form-group mb-2">
<label for="searchtext">Search Text</label>
</div>
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="searchtext" name="searchtext" placeholder="Search Text">
</div>
<button type="submit" class="btn btn-primary mb-2">Search</button>
</form>
<!-- ## SEARCH FORM ~ END ------------------------------------------- -->
</div>
</div>
<div class="row">
<div class="col">
<!-- ## TABLE OF SEARCH RESULTS ------------------------------------------------ -->
<div id="search-results" class="table-responsive">
<!-- The Data Table is inserted here by JavaScript -->
</div>
<!-- ## TABLE OF SEARCH RESULTS ~ END ------------------------------------------------ -->
</div>
</div>
</div>
</body>
</html>
I have built a web app with GAS that send the data on submit to a google spreadsheet.
Sometimes it happens that if I don't update the google spreadsheet manually, the data just entered in the form doesn't appear in the spreadsheet.
Why? Something is missing in the code I need to add?
This is my code.gs:
function doGet(request) {
return HtmlService.createTemplateFromFile('Index')
.evaluate();
}
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
/* #Process Form */
function processForm(formObject) {
var url = "xxx";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([formObject.azienda,
formObject.test,
formObject.field1,
formObject.field2,
formObject.field3]);
}
function sceltaatecoedatiseguenti() {
var sheet = SpreadsheetApp.openById("xxx").getSheetByName("Sheet3");
var lastRow = sheet.getLastRow();
var myRange = sheet.getRange("A2:D" + lastRow); // Modified
var data = myRange.getValues();
var optionsHTML = "";
for (var i = 0; i < data.length; i+=1) {
optionsHTML += `<option data-values="${data[i][1]};${data[i][2]};${data[i][3]}">${data[i][0]}</option>`; // Modified
};
return optionsHTML;
}
This is my javascript.html:
<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(formObject) {
google.script.run.processForm(formObject);
document.getElementById("myForm").reset();
}
// Funzione scelta ateco e dati seguenti -prima parte-
function setValues(select) {
const [v1, v2, v3] = select.options[select.selectedIndex].dataset.values.split(";");
document.getElementById("field1").value = v1;
document.getElementById("field2").value = v2;
document.getElementById("field3").value = v3;
}
// Funzione scelta ateco e dati seguenti -seconda parte-
const select = document.getElementById("test");
setValues(select);
select.addEventListener("change", () => setValues(select));
</script>
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-12">
<form id="myForm" onsubmit="handleFormSubmit(this)">
<h1>Master Leads</h1>
<div class="form-row">
<div class="form-group col-md-12">
<label for="azienda">Azienda</label>
<input type="text" class="form-control" id="azienda" name="azienda" required="">
</div>
<div class="form-group col-md-12">
<span class="badge badge-primary">Codici Ateco</span>
</div>
<div class="form-group col-md-2">
<label for="test">Ateco 1</label>
<select class="custom-select" name="test" id="test">
<?!= sceltaatecoedatiseguenti(); ?>
</select>
</div>
<div class="form-group col-md-10">
<label for="field1">Sottocategoria</label>
<input type="text" class="form-control" id="field1" name="field1" readonly>
</div>
<div class="form-group col-md-8">
<label for="field2">Divisione</label>
<input type="text" class="form-control" id="field2" name="field2" readonly>
</div>
<div class="form-group col-md-4">
<label for="field3">Sezione</label>
<input type="text" class="form-control" id="field3" name="field3" readonly>
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Inserisci in Master Leads</button>
</form>
<div id="output"></div>
</div>
</div>
</div>
</body>
<?!= include('JavaScript'); ?>
</html>
Conclusions after testing with your spreadsheet:
I could reproduce the issue with your spreadsheet
I could reproduce the issue when making a copy of your spreadsheet
The issue does not occur when creating a brand new spreadsheet
Thus, the issue must be related to some setting in your spreadsheet.
You can either create a new spreadsheet from scratch or use the following workaround:
Go to File - > Spreadsheet Settings and change Calculation to On change and every minute.
This seems to solve your problem.
I am applying JQuery:
HTML
<div id="myNotice" class="container-fluid">
<div style="margin-bottom: 10px;" class="row">
<div class="col-lg-12" >
<button type="button" onclick="myFunction()" class="btn btn-block btn-info">
<i class="fas fa-arrow-right"></i>
<span >Proceed</span>
</button>
</div>
</div>
</div>
<div id="myMSF" class="container-fluid" style="display:none">
<table id="msfTable" class=" table table-bordered table-striped table-hover datatable">
<thead>
<tr>
<th scope="col" width="4%">ID</th>
<th scope="col" width="25%">Core Value<span style="color:red;">*</span></th>
<th scope="col" width="25%">Rating<span style="color:red;">*</span></th>
<th scope="col" width="46%">Comment</th>
</tr>
</thead>
<tbody class="resultbody">
</tbody>
</table>
</div>
JQuery
<script type="text/javascript">
$(document).ready(function() {
//Try to get tbody first with jquery children. works faster!
var tbody = $('#msfTable').children('tbody');
//Then if no tbody just select your table
var table = tbody.length ? tbody : $('#msfTable');
$('[name=count_skills_no]').text();
function myFunction() {
var x = document.getElementById("myMSF");
var y = document.getElementById("myNotice");
if (x.style.display === "none") {
x.style.display = "block";
y.style.display = "none";
} else {
x.style.display = "none";
y.style.display = "block";
}
var nx = ($('.resultbody tr').length - 0) + 1;
var num_rows = $("#msfTable tbody tr").length + 1;
var rows = $('[name=count_skills_no]').val() - 1;
var sn;
for (var i = 0; i < rows; i++) {
sn = num_rows + i;
//Add row
table.append('<tr>\n' +
'<td class="no">' + sn + '</td>\n' +
' <td><select class="form-control select2bs4" data-placeholder="Choose Employee Type" tabindex="1" name="appraisal_skill_id[]" required>\n' +
' <option value="0" selected="true" disabled="true">Select Core Value</option>\n' +
' #if($skills->count() > 0 )\n' +
' #foreach($skills as $skill)\n' +
' <option value="{{$skill->id}}">{{$skill->skill_name}}</option>\n' +
' #endforeach\n' +
' #endif\n' +
' </select></td>\n' +
' <td><select class="form-control select2bs4" data-placeholder="Choose Rating" tabindex="1" name="appraisal_respondent_rating_id[]" required>\n' +
' <option value="0" selected="true" disabled="true">Select Rating</option>\n' +
' #if($ratings->count() > 0 )\n' +
' #foreach($ratings as $rating)\n' +
' <option value="{{$rating->id}}">{{$rating->rating_value}} - {{$rating->rating_name}}</option>\n' +
' #endforeach\n' +
' #endif\n' +
' </select></td>\n' +
' <td><input type="text" name="comment[]" placeholder="Enter comment here" class="form-control comment" required></td>\n' +
'</tr>');
}
}
});
</script>
By default
<div id="myMSF" class="container-fluid" style="display:none">
is hidden while
<div id="myNotice" class="container-fluid">
is visible.
<button type="button" onclick="myFunction()" class="btn btn-block btn-info">
<i class="fas fa-arrow-right"></i>
<span >Proceed</span>
</button>
is to display myMSF and hide. Also it creates tbody of the table
When the button proceed is onclick, I got this error:
Uncaught ReferenceError: myFunction is not defined at HTMLButtonElement.onclick
and this code is highlighted
<button type="button" onclick="myFunction()" class="btn btn-block btn-info">
How do I resolve it?
Thanks
You defined function myFunction() { inside the context of $(document).ready(function() {. Hence, it is not visible outside. Move such a function outside the dom ready.
Moreover, avoid inline event handler, use instead .on():
$('#myNotice button.btn-info').on('click', function(e) {
.....
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<div id="myNotice" class="container-fluid">
<div style="margin-bottom: 10px;" class="row">
<div class="col-lg-12" >
<button type="button" onclick="myFunction()" class="btn btn-block btn-info">
<i class="fas fa-arrow-right"></i>
<span >Proceed</span>
</button>
</div>
</div>
</div>
<div id="myMSF" class="container-fluid" style="display:none">
<table id="msfTable" class=" table table-bordered table-striped table-hover datatable">
<thead>
<tr>
<th scope="col" width="4%">ID</th>
<th scope="col" width="25%">Core Value<span style="color:red;">*</span></th>
<th scope="col" width="25%">Rating<span style="color:red;">*</span></th>
<th scope="col" width="46%">Comment</th>
</tr>
</thead>
<tbody class="resultbody">
</tbody>
</table>
</div>
<script>
function myFunction() {
var x = document.getElementById("myMSF");
var y = document.getElementById("myNotice");
if (x.style.display === "none") {
x.style.display = "block";
y.style.display = "none";
} else {
x.style.display = "none";
y.style.display = "block";
}
var nx = ($('.resultbody tr').length - 0) + 1;
var num_rows = $("#msfTable tbody tr").length + 1;
var rows = $('[name=count_skills_no]').val() - 1;
var sn;
for (var i = 0; i < rows; i++) {
sn = num_rows + i;
//Add row
table.append('<tr>\n' +
'<td class="no">' + sn + '</td>\n' +
' <td><select class="form-control select2bs4" data-placeholder="Choose Employee Type" tabindex="1" name="appraisal_skill_id[]" required>\n' +
' <option value="0" selected="true" disabled="true">Select Core Value</option>\n' +
' #if($skills->count() > 0 )\n' +
' #foreach($skills as $skill)\n' +
' <option value="{{$skill->id}}">{{$skill->skill_name}}</option>\n' +
' #endforeach\n' +
' #endif\n' +
' </select></td>\n' +
' <td><select class="form-control select2bs4" data-placeholder="Choose Rating" tabindex="1" name="appraisal_respondent_rating_id[]" required>\n' +
' <option value="0" selected="true" disabled="true">Select Rating</option>\n' +
' #if($ratings->count() > 0 )\n' +
' #foreach($ratings as $rating)\n' +
' <option value="{{$rating->id}}">{{$rating->rating_value}} - {{$rating->rating_name}}</option>\n' +
' #endforeach\n' +
' #endif\n' +
' </select></td>\n' +
' <td><input type="text" name="comment[]" placeholder="Enter comment here" class="form-control comment" required></td>\n' +
'</tr>');
}
}
$(document).ready(function() {
//Try to get tbody first with jquery children. works faster!
var tbody = $('#msfTable').children('tbody');
//Then if no tbody just select your table
var table = tbody.length ? tbody : $('#msfTable');
$('[name=count_skills_no]').text();
});
</script>
I am trying to create a dashboard in Google script HTML web app, the data consist, assigned project and total time spent on project by user
I have used some HTML code however it got jumbled, sharing the google sheet which consists data I want to replicate this data in the web app.Functions I am looking here is "Date Picker" "User name / Project name" are the search parameters
The dashboard should reflect according to the search parameters and data should consist Total worked users by the user or total hours or users spent on the project.
I know it's bit complex, if your refer my sheet you will get some idea what I am looking to publish in web app
Sheet
function doGet() {
return HtmlService
.createTemplateFromFile('index')
.evaluate();
}
function getData() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet4')
.getDataRange()
.getValues();
}
function getData1() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet5')
.getDataRange()
.getValues();
}
function getData2() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet6')
.getDataRange()
.getValues();
}
function getData3() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet7')
.getDataRange()
.getValues();
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
/* Add a gray background color and some padding to the footer */
footer {
background-color: #f2f2f2;
padding: 25px;
}
.carousel-inner img {
width: 100%; /* Set width to 100% */
min-height: 200px;
}
}
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Logo</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>Projects</li>
<li>Contact</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-log-in"></span> Login</li>
</ul>
</div>
</div>
</nav>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="row">
<div class="col-xs-3"><label for="usr"><p class="text-primary">User Name</label><input type="text" class="form-control" id="#"></div>
<div class="col-xs-3"><label for="usr"><p class="text-primary">Date Range Picker</label><input type="text" class="form-control" id="#"></div>
</div>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="col-sm-6">
<div class="well">
<p><html>
<? var data = getData(); ?>
<table class="table table-striped table-bordered table-hover table-condensed">
<tr>
<p>Today Report</p>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</html></p>
</div>
<div class="well">
<table class="table table-bordered">
<thead>
<tr>
<td class="bg-primary"style="background-color:#4885ed"><b>Project Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>Test1</td>
<td>A</td>
<td>12:00:00</td>
</tr>
<tr>
<td>Test2</td>
<td>B</td>
<td>11:00:00</td>
</tr>
<tr>
<td>Test3</td>
<td>C</td>
<td>10:00:00</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-sm-6">
<div class="well">
<p><html>
<? var data = getData1(); ?>
<table class="table table-striped table-bordered table-hover table-condensed">
<tr>
<p>Monthly Report</p>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</html></p>
</div>
<div class="well">
<table class="table table-bordered">
<thead>
<tr>
<td class="bg-primary"style="background-color:#4885ed"><b>Project Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>Test1</td>
<td>A</td>
<td>122:00:00</td>
</tr>
<tr>
<td>Test2</td>
<td>B</td>
<td>211:00:00</td>
</tr>
<tr>
<td>Test3</td>
<td>C</td>
<td>190:00:00</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr>
This is a simple html file communicating with Google Apps Script contained in a Spreadsheet. I test it a lot as a dialog and I also run it as a web app. The html file and the Google Apps Script communicate with each other and I pass one array from the html file to the Google Script. Hope this helps.
The Code.gs file:
function doGet()
{
var html = HtmlService.createHtmlOutputFromFile('index');
return html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
function getData(a)
{
var ts = Utilities.formatDate(new Date(), "GMT-6", "M/d/yyyy' 'HH:mm:ss");
a.splice(0,0,ts);
var ss=SpreadsheetApp.openById('SPREADSHEETID')
ss.getSheetByName('Form Responses 1').appendRow(a);
return true;
}
function getURL()
{
var ss=SpreadsheetApp.openById('SPREADSHEETID');
var sht=ss.getSheetByName('imgURLs');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var urlA=[];
for(var i=1;i<rngA.length;i++)
{
urlA.push(rngA[i][0]);
}
return urlA;
}
The index.html file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="data">
<br />Text 1<input name="t1" type="text" size="15" id="txt1" placeholder="Text 1" />
<br />Text 2<input name="t2" type="text" size="15" id="txt2" placeholder="Text 2" />
<br />Text 3<input name="t3" type="text" size="15" id="txt3" placeholder="Text 3" />
<br />Text 4<input name="t4" type="text" size="15" id="txt4" placeholder="Text 4" />
<br /><input type="radio" name="Type" value="Member" checked />Member
<br /><input type="radio" name="Type" value="Guest" />Guest
<br /><input type="radio" name="Type" value="Intruder" />Intruder
<br /><input type="button" value="submit" id="btn1" />
<br /><img id="img1" src="" alt="img1" width="300" />
</div>
<div id="resp" style="display:none;">
<h1>Response</h1>
<p>Your data has been received.</p>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
$('#btn1').click(validate);
$('#txt4').val('');
$('#txt3').val('');
$('#txt2').val('');
$('#txt1').val('')
google.script.run
.withSuccessHandler(setURL)
.getURL();
});
function setURL(url)
{
$('#img1').attr('src',url[0]);
}
function setResponse(a)
{
if(a)
{
$('#data').css('display','none');
$('#resp').css('display','block');
}
}
function validate()
{
var txt1 = document.getElementById('txt1').value || '';
var txt2 = document.getElementById('txt2').value || '';
var txt3 = document.getElementById('txt3').value || '';
var txt4 = document.getElementById('txt4').value || '';
var type = $('input[name="Type"]:checked').val();
var a = [txt1,txt2,txt3,txt4,type];
if(txt1 && txt2 && txt3 && txt4)
{
google.script.run
.withSuccessHandler(setResponse)
.getData(a);
return true;
}
else
{
alert('All fields must be completed.');
}
}
function loadTxt(from,to)
{
document.getElementById(to).value = document.getElementById(from).value;
}
function radioValue()
{
var radios = document.getElementsByName('genderS');
for (var i = 0, length = radios.length; i < length; i++)
{
if(radios[i].checked)
{
return radios[i].value;
}
}
}
console.log('My Code');
</script>
</body>
</html>