My UserForm doesnt give an Output (GoogleSheets) - javascript

i am very new to google sheets and tryed to use an Userform to fill in my Sheets. But every time, i click submit it just freezes and nothing more happends...
https://docs.google.com/spreadsheets/d/13LdDIMvWpVkj5rom2fHV25FtYvbOcnKr4cZF84nITYQ/edit?usp=sharing
And the code:
HTML:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<form>
<div class="form-group">
<label for="name" class="form-label">name</label>
<input type="text" class="form-control" id="name">
</div>
<div class="form-group">
<label for="price" class="form-label">price</label>
<input type="text" class="form-control" id="price">
</div>
<button type="submit" class="btn btn-primary" id="add" >Submit</button>
</form>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
-->
<script>
function afterButtonClicked(){
var item = document.getElementById("name");
var price = document.getElementById("price");
google.script.run.addnewrow(name,price);
}
document.getElementById("add").addEventListener("click",afterButtonClicked);
<script>
</body>
</html>
Here are my functions:
function addnewRow(nameprice) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Results");
ws.appendRow([name,price]);
}
I dont know if its important, but here is the cutom menu:
function loadForm() {
const htmlForSidebar = HtmlService.createTemplateFromFile("uform");
const htmlOutput = htmlForSidebar.evaluate();
const ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
function createMenu(){
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("Meine Forms");
menu.addItem("Show UserForm","loadForm");
menu.addToUi();
}
function onOpen(){
createMenu();
}
Thank you!

There are few modification in your code:-
In HTML file you've syntax error, you didn't used </script>.
You're passing wrong variable as a argument in addnewRow while running it through google.script.run.
You're trying to run function which actually doesn't exist in server-side.
Parameter in addnewRow function is missing comma , in server-side.
Sheet you're trying to access in ss.getSheetByName("Results") doesn't exist.
Do following modifications in <script> tag of client side code(HTML File):-
<script>
function afterButtonClicked(){
var item = document.getElementById("name").value;
var price = document.getElementById("price").value;
google.script.run.addnewRow(item,price);
}
document.getElementById("add").addEventListener("click",afterButtonClicked);
</script>
And replace this :-
function addnewRow(nameprice) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Results");
ws.appendRow([name,price]);
}
with this :-
function addnewRow(name,price) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("Results");
ws.appendRow([name,price]);
}
and change/add the sheet name as Result in Spreadsheet.

Related

Access class properties in javascript from class method

this my first try doing the mvc model with classes in javascript.
With the method getFormValues() of the model object of my controller object app I want to read the values of all the input files . Then I want to save them to the form values property of the model object of my controller object. This doesn`t work!
The line console.log(app.model.getFormValues()); shows me the Array with the form values.
The line console.log(app.model.formValues); shows me an empty Array.
How can I store the array from the method getFormValues in the property formValues of the model object?
My HTML:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<form>
<div class="row">
<div class="col">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Last name">
</div>
</div>
</form>
<button id="verification"> Verify</button>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="js.js"></script>
</body>
</html>
My JS/Jquery:
class Model {
constructor() {
this.formValues = this.getFormValues();
}
getFormValues() {
let $inputs = $("input");
var formValues = [];
$inputs.each(function(index) {
let value1 = $(this).val();
formValues.push(value1);
});
return formValues;
}
}
class View {
constructor() {}
}
class Controller {
constructor(model, view) {
this.model = model
this.view = view
}
}
const app = new Controller(new Model(), new View());
check = function () {
console.log(app.model.getFormValues());
console.log(app.model.formValues);
}
$("#verification").on("click", check);
Greetings and thanks in advance
Fabian
Your problem is based on the creation of the app constant.
You create the app constant when you first load the page.
At this point the inputs are empty so are they for the app constant.
Edit: update your variable when you click your button like in my snippet.
class Model {
constructor() {
this.formValues = this.getFormValues();
}
getFormValues() {
let $inputs = $("input");
var formValues = [];
$inputs.each(function(index) {
let value1 = $(this).val();
formValues.push(value1);
});
return formValues;
}
}
class View {
constructor() {}
}
class Controller {
constructor(model, view) {
this.model = model
this.view = view
}
}
const app = new Controller(new Model(), new View());
check = function () {
app.model.formValues = app.model.getFormValues();
console.log(app.model.getFormValues());
console.log(app.model.formValues);
}
$("#verification").on("click", check);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="row">
<div class="col">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Last name">
</div>
</div>
</form>
<button id="verification"> Verify</button>

I'm receiving an uncaught type Error when looping using .add() in a loop

Once I have rendered my template with my elements I wanted to add options with values dynamically from JSON data, it populates and works fine but gives me: Uncaught (in promise) TypeError: sel.add is not a function
I have tried and failed to use a different set-up with .appendChild and it's doing me. I can't see the issue but I haven't been using JS long enough to know hope someone can help.
...js
const csv = require('csvtojson');
const path = "filepath here";
readData(path);
async function readData(path){
const data = await csv().fromFile(path).on('header', (header) =>{
assign(header);
});
}
function assign(col){
//Renders Template
const contain = document.getElementById("container");
const temp = document.getElementById("dropdown").content;
const clone = temp.cloneNode(true);
contain.appendChild(clone);
populate(col);
}
function populate(col){
//Populates dropdown boxes with data from headers
const group = document.querySelectorAll('.choice');
for(let i in group){
for(let x in col){
let sel = document.getElementsByClassName('choice')[i];
let opt = document.createElement('option');
opt.text = col[x];
opt.value = col[x];
sel.add(opt, sel[x]);
}
}
}
...
...html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Bulk Upload Assistant</title>
</head>
<body>
<div id="container">
<h1>Please browse to upload file</h1>
<input type="button" id = "browse-files" value="Browse" >
<template id="dropdown">
<p>Please select the appropriate headings for your file</p>
<p class = "drop-down">ID field</p>
<p class = "drop-down">Leaver field</p>
<p class = "drop-down">Auth Type field</p>
<select id="ID" class = "choice">
</select>
<select id="LEAVE" class = "choice">
</select>
<select id="AUTH" class = "choice">
</select>
<button onClick = 'getHeadings()'>Submit</button>
</template>
</div>
<script src = 'render.js'></script>
</body>
</html>
...
Should not throw the error message

extract headers from uploaded csv file in html

I want to extract the header row of the csv files i upload and display them as checkbox options. Currently, I split based on "\n", then on "," to get the individual column names. However, it does not work for all csv files and some do not get split properly (eg, data cells are returned as column headers). Is there any functions I can use instead? Thanks! My code is shown below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<!-- jquery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.7.7/xlsx.core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xls/0.7.4-a/xls.core.min.js"></script>
<script type="text/javascript">
/*---CSV FUNCTION---*/
function getColumns_csv() {
var reader = new FileReader();
reader.onload = function(e){
var data = e.target.result;
var header = data.split("\n")[0] //<--- is there a better way to split columns?
header = header.split(",");
var cnt = 1;
$('#columnCheckbox').empty();
header.forEach(function(y){
$('#columnCheckbox').append('<td><input type="checkbox" name='+y+' id="columnSelect'+cnt+'" class="chkbx">'+y+'</td>');
cnt++;
});
$('.chkbx').on('click',function(){
if($('.chkbx:checked').length == $('.chkbx').length){
$('#checkall').prop('checked',true);
}else{
$('#checkall').prop('checked',false);
}
});
$('.hiddeninputs').show();
$('#submission').show();
}
reader.readAsText($('#datafile')[0].files[0]);
}
/*---//CSV FUNCTION---*/
</script>
<script type="text/javascript">
//select all button
$(document).ready(function(){
$('#checkall').on('click',function(){
if(this.checked){
$('.chkbx').each(function(){
this.checked = true;
});
}else{
$('.chkbx').each(function(){
this.checked = false;
});
}
});
});
</script>
</head>
<body>
<div>
<h3>Upload File</h3>
<!-- form to post file -->
<form method="post" enctype="multipart/form-data" id="fileform">
<input type="file" name="datafile" id="datafile">
<button type="button" class="btn btn-info" name="upload" id="upload" onclick="getColumns_csv()">Upload File</button>
<br></br>
<table class="hiddeninputs" hidden="hidden">
<tr>
<td><input type="checkbox" id="checkall">Select all</td>
</tr>
<tr id="columnCheckbox"></tr>
</table>
<br>
<input type="submit" class="btn btn-info" value="submit" id="submission">
</form>
</div>
</body>
</html>
Try with this:
var header = data.split(/[\r\n]+/)[0];
If your problem is with line splitting, this will cover more possible end of line character.

Getting a value from a color picker and returning it

I want to know how you would go about getting a value from a color picker and returning it to a js script
Here is the HTML Code
<!DOCTYPE html>
<script type="text/javascript" src="Scripts/jquery-3.1.1.js"></script>
<script type="text/javascript" src="js/bootstrap-colorpicker.js"></script>
<link rel='stylesheet' href='css/bootstrap-colorpicker.css' />
<script type="text/javascript" src="js/bootstrap-colorpicker.min.js"></script>
<link rel='stylesheet' href='css/bootstrap-colorpicker.min.css' />
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
</head>
<body>
<p> test test test</p>
<div id="cp2" class="input-group colorpicker-component">
<input type="text" value="#00AABB" class="form-control" />
<span class="input-group-addon"><i></i></span>
</div>
<script>
$(function () {
$('#cp2').colorpicker({
color: '#AA3399',
format: 'rgb'
})
});
</script>
</body>
</html>
<script>document.getElementById("cp2").value = function () {
return rgb;
}
</script>
`
I am looking to return the value of the color picker which is in RGB format to a js script so that I will to able to assign vars like this
var 1 = rgb[1]
var 2 = rgb[2]
var 3 = rgb[3]
`
If you decide to help me I will be thankful and you could please explain so I can learn from it.
Check javascript function:
<script>
(function() {
var rgb = document.getElementById("cp2").value ;
return rgb;
})();
</script>

AngularJS Message Display On Click

I have two questions
How to display the initial message and/or upon button click. The current code I have displays the message continuously. I want it to display initially and once users starts pressing other button I want the message "Start guessing" to disappear and only appear after user clicks Start Over button.
How to display the correct answer when user clicks on Give up.
HTML
<!DOCTYPE html>
<html lang="en" data-ng-app="myApp">
<head>
<title>Template that uses Bootstrap</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initialscale=1.0"/>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet" />
<!-- Custom CSS -->
<link href="css/custom.css" rel="stylesheet" />
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div data-ng-controller="myCtrl">
<div class="container">
<h1>Guessing Game</h1><br>
<label>Enter Guess:</label>
<input type="text" id="guess" name="guess" data-ng-model="guess"/><br>
<span data-ng-bind="Message"></span>
<div class="row">
<div class="col-md-12">
<button class="btn btn-primary btn-md" data-ng-click="checkGuess()">Check</button>
<button class="btn btn-warning btn-md" data-ng-click="showAnswer()">Give Up</button>
<button class="btn btn-info btn-md" data-ng-click="startGame()">Start Over</button>
</div></div>
<div class="row">
<div class="col-xs-7">
<div ng-show="deviation<0" class="alert alert-warning">Guess higher</div>
<div ng-show="deviation>0" class="alert alert-warning">Guess lower</div>
<div ng-show="deviation===0" class="alert alert-success">You got it!</div>
</div></div>
</div>
</div>
<!-- jQuery – required for Bootstrap's JavaScript plugins) -->
<script src="js/jquery.min.js"></script>
<!-- All Bootstrap plug-ins file -->
<script src="js/bootstrap.min.js"></script>
<!-- Basic AngularJS -->
<script src="js/angular.min.js"></script>
<!-- Your Controller -->
<script src="js/app.js"></script>
</body>
</html>
Angular
/*global angular */
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function ($scope) {
"use strict";
$scope.checkGuess = function () {
$scope.deviation = $scope.original - $scope.guess;
};
$scope.startGame = function () {
$scope.guess = null;
$scope.original = Math.floor(Math.random() * 1000 + 1);
$scope.deviation = null;
$scope.display = false;
$scope.Message = "Start guessing.";
};
$scope.showAnswer = function () {
$scope.original = Math.floor(Math.random() * 1000 + 1);
$scope.display = true;
};
$scope.startGame();
}
);
1) Use ng-hide to hide your element when needed:
<span data-ng-bind="Message" ng-hide="hideMessage"></span>
In the checkGuess and showAnswer functions set the hideMessage to true:
$scope.hideMessage = true;
In the startGame function, set it to false:
$scope.hideMessage = false;
2) In your HTML add a tag:
<div ng-show="showOriginal">{{previousOriginal}}</div>
And in your showAnser and startGame function, add:
$scope.showOriginal = true;
$scope.previousOriginal = angular.copy($scope.original);
And remove of the showAnswer function:
$scope.original = Math.floor(Math.random() * 1000 + 1)
Finally, in the startGame function, set it to false:
$scope.showOriginal = false;

Categories

Resources