I am attempting to create an expandable form to create on/off instructions that a user can submit times for in pairings, so my HTML defaults with one pair and the user can use a button to add additional pairs, but when i submit the form angular is only reading the first pairing, can someone point out what I am missing here? Am I appending in the extra fields improperly?
HTML
<div class="timing">
<form class="timingSelect" action="index.html" method="post">
<div class="inputField">
<div class="form-group">
On: <input type="number" ng-model="recipe.on1" value="" step=".1">
</div>
<div class="form-group">
oz: <input type="number" ng-model="recipe.oz1" value="" readonly="readonly">
</div>
<div class="form-group">
Off: <input type="number" ng-model="recipe.off1" value="" step='.1'>
</div>
</div>
<!-- <input type="submit" ng-click="createRecipe(recipe)" value="Generate Recipe"> -->
</form>
<button type="submit" ng-click="createRecipe(recipe)">Submit</button>
</div>
<button type="button" class="next" name="button" ng-click="addColumn()">+</button>
JS:
app.controller('CreateRecipeController', ['$scope', '$location', '$routeParams', 'DashFactory', function($scope, $location, $routeParams, DashFactory){
console.log("entered Create Recipe controller");
var columnCount = 1;
$scope.addColumn = function addColumn(){
columnCount++;
console.log('attempting to create column');
var d = document.createElement("div");
d.className = "inputField";
var f = document.createElement("form");
f.setAttribute('method',"post");
f.setAttribute('action',"submit.php");
var d2 = document.createElement("div");
d2.className = "form-group"
var i = document.createElement("input"); //input element, text
i.setAttribute('type',"number");
i.setAttribute('ng-model',"recipe.on"+columnCount);
i.setAttribute('value',"");
var d3 = document.createElement("div");
d3.className = "form-group"
var s = document.createElement("input"); //input element, Submit button
s.setAttribute('type',"number");
s.setAttribute('ng-model',"recipe.oz"+columnCount);
s.setAttribute('value',"");
s.setAttribute('readonly','readonly')
var d4 = document.createElement("div");
d4.className = "form-group"
var t = document.createElement("input"); //input element, Submit button
t.setAttribute('type',"number");
t.setAttribute('ng-model',"recipe.off"+columnCount);
t.setAttribute('value',"");
d.appendChild(f);
f.appendChild(d2);
f.appendChild(d3);
f.appendChild(d4);
d2.appendChild(i);
d3.appendChild(s);
d4.appendChild(t)
document.getElementsByClassName('timingSelect')[0].appendChild(d);
}
$scope.createRecipe = function(recipe){
console.log('recieved recipe data', recipe);
DashFactory.createRecipe(recipe)
}
}
]);
Great - Just move all your buttons inside your form tag like the code below
<div class="timing">
<form class="timingSelect" action="index.html" method="post">
<div class="inputField">
<div class="form-group">
On: <input type="number" ng-model="recipe.on1" value="" step=".1">
</div>
<div class="form-group">
oz: <input type="number" ng-model="recipe.oz1" value="" readonly="readonly">
</div>
<div class="form-group">
Off: <input type="number" ng-model="recipe.off1" value="" step='.1'>
</div>
</div>
<button type="submit" ng-click="createRecipe(recipe)">Submit</button>
<button type="button" class="next" name="button" ng-click="addColumn()">+</button>
</form>
</div>
And don't add another form when you append a new input field just add all your new inputs inside the existing form and try to submit it again - This might work
Thanks - Happy Coding !!
Related
I want to pre-fill the form with current user e-mail. Mainly to prevent it, so everyone could fill it in from their email address. Unfortunately, I can't achieve the expected result, and I'm not completely sure, why.
This is what I have:
Form.html:
<form id="myForm" class="p-2 border border-light rounded bg-light" onsubmit="handleFormSubmit(this)">
<p class="h4 mb-4 text-center">Sides</p>
<br>
<div id="message"></div>
<input type="text" id="RecId" name="RecId" value="" style="display: none">
<div class="form-group">
<label for="form_email" >Email</label>
<input type="email" class="form-control" id="form_email" name="form_email" placeholder="Email" required>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<input class="btn btn-secondary" type="reset" value="Reset">
</form>
Code.gs
/*CURRENT USER */
function getUserEmail() {
var userEmail = Session.getActiveUser().getEmail();
Logger.log(userEmail);
}
JavaScript.html
//active user
google.script.run.withSuccessHandler(currentuser).getUserEmail();
function currentuser(userEmail) {
document.getElementById('form_email').value = userEmail;
};
Unfortunately it does not work. Email field still displays only placeholder and nothing happens. Can you see what can be wrong? Thanks :)
To set the default value of an input element, use the value attribute.
<input type="text" value="default value">
I changed this part
var userEmail = Session.getActiveUser().getEmail();
to
var currentuser = Session.getActiveUser().getEmail();
and all occurrences of userEmail in the same way and it helped.
I am really new to google script and HTML and I am trying to create a program that accepts multiple inputs from a user using a HTML form, and when the user clicks submit, the data is stored inside a variable and can be used inside a .gs file from a .html . I have gotten the form to work but whenever I clicked "Submit" nothing occurs. After some troubleshooting, I think the problem is at my form_data() function. What I would like to know is how to compile the data inputs from the form and send it to my runsies() fucntion. Thank you in advance! Here is my HTML code below:
const ui = SpreadsheetApp.getUi();
function onOpen() {
ui.createAddonMenu()
.addItem('New Entry', 'newEntry')
.addToUi();
};
function newEntry() {
var html = HtmlService.createHtmlOutputFromFile("input")
.setWidth(750)
.setHeight(550);
//Display the dialog
var dialog = ui.showModalDialog(html, "External Organisations");
};
function runsies(info){
//Display the values submitted from the dialog box in the Logger.
Logger.log(info);
};
<html>
<head>
<!--Set the font of the form-->
<style>
body {font-family:Courier;}
</style>
</head>
<!--Main body design of the form-->
<body>
<!--Create text boxes for user input-->
<form action="" method="get" class="form-example">
</script>
<div class="form-example">
<label for="name"><b>Organisation: </b></label><br>
<input type="text" name="name" id= "txt1" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="email"><b>Email: </b></label><br>
<input type="text" name="email" id="txt2" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="phone"><b>Phone: </b></label><br>
<input type="text" name="phone" id="txt3" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="poc"><b>Point of Contact: </b></label><br>
<input type="text" name="poc" id="txt4" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="susmi"><b>SUSMI Contact: <b></label><br>
<input type="text" name="susmi" id="txt5" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="stats"><b>Status: <b></label><br>
<input type="text" name="stats" id="txt6" style="border-radius:3px" required><br><br>
</div>
<div class="form-example">
<label for="note"><b>Notes: </b><br><textarea rows="5" cols="50" id="multiLineInput" style="border:2px solid black;border-radius:3px">
</textarea></label><br><br>
</div>
<input type="button" value="Submit" onclick="form_data()">
<input type="button" value="Close" onclick="google.script.host.close()" />
<!--Once user clicks submit, compile info and send it to main .gs code-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function form_data(){
var info = [txt1,txt2,txt3,txt4,txt5,txt6,multiLineInput];
google.script.run.withSuccessHandler().runsies(info);
closeIt()
};
function closeIt(){
google.script.host.close()
};
</form>
</body>
</html>```
var info = [txt1,txt2,txt3,txt4,txt5,txt6,multiLineInput];
Your array is just a bunch of element id's if you want the data use `document.getElementById().value for the text boxes
Read about client to server communication google.script.run
javascript reference
Code is the variable with the URL in it.
That's how it is supposed to work: User enters code (ex: 123342) in Textbox and the Text inside the text box is saved inside variable Code. Then, its goes to the website page 123342.
<form for="Code" action='https://website.com/ + Code'>
//makes a label
<label for="Answer" >URL:</label>
<input type="Answer" id="Code" Answer="Answer"><br><br>
<input type="submit" value="Join" class="Join">
</form>
You can set it at onload:
window.onload = function(){
var id = 789
document.getElementById("form").action = "https://test.com/"+id
};
<form for="Code" id="form">
<label for="Answer" >URL:</label>
<input type="Answer" id="Code" Answer="Answer">
<input type="submit" value="Join" class="Join">
</form>
The following form shows a list of data on submit. I am trying to show no results found when there is no data on submit. I tried like shown below,it shows and hides the div. But when there is no options selected on form and click submit button it shows the no result div.How to show the no results div only when form validation succeeds and there is no data to display.
HTML
<div class="form-group" >
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption"
ng-required="!radioption"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" >
Main 2</label>
<div ng-show="!radioption && buttonClicked">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" ng-click="fetchresults()" value="submit" >
<div ng-show="buttonClicked">
<table> <thead>.....</thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td></td></tbody></table>
</div>
<div ng-show="buttonClicked">
<span ng-show="results.length==0 ">No results.</span>
</div>
Minimal Controller Code
$scope.fetchresults = function(){
$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
}
EDIT:
I used model to validate and $valid is also working, as suggested below.But Got a couple of glitches. If i click the button it does not show div. but after validation is over it shows automatically "no results" from the click before. How to stop this.And while it lists data when its available it shows "no results" for a second or so
Give your form a name
<form name="formName">
Then you can do
ng-show="results.length==0 && formName.$valid"
Some more information on angularJS form validation
You can check the below snippet, I have changed most of them in angular way with $invalid, $pristine, $submitted and $valid.
You can check the angular documentation to read about them.
Link 1, Link 2
Note: You can use a submit button and get rid of ng-click event and use ng-submit instead which can't be used in this snippet as form submit is not allowed. Comment the line form.$submitted = true; when you use a submit button.
var app = angular.module('app', []);
app.controller('TestController', function($scope){
$scope.isFieldInvalid = function(field) {
var form = $scope.testForm;
return form[field].$invalid && (!form[field].$pristine || form.$submitted);
};
$scope.fetchResults = function(){
var form = $scope.testForm;
form.$submitted = true; // comment this line if button type="submit"
if(form.$valid){
$scope.searching = true;
$scope.results = [];
var rnd = Math.random();
if(rnd >= 0.5) {
$scope.results = [{id: 1}, {id: 2}];
}
//$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
$scope.searching = false;
}
};
});
angular.bootstrap(document, ['app']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form name="testForm" ng-controller="TestController" ng-submit="fetchResults()" role="form" novalidate="">
<div class="form-group" ng-controller="TestController">
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption" ng-required="true"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" ng-required="true" >
Main 2</label>
<div ng-show="isFieldInvalid('sampleinlineradio')">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" value="submit" ng-click="fetchResults()" >
<div ng-show="buttonClicked && !searching">
<table> <thead></thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td>{{r.id}}</td></tbody></table>
</div>
<div ng-show="buttonClicked && !searching">
<span ng-show="results.length==0 ">No results.</span>
</div>
</form>
I use HTMLServices with google.script.run calls with form in args and i try to get the image from my form input file field and store it in my drive.
I get the value of all the fields correctly except the photodata field.
photodata contain the string "FileUpload" instead of a blob.
I have tested with .getBlob for the same result.
Server Side :
function setUsager(form) {
var blob = form.photodata;
Logger.log(Utilities.jsonStingify(blob);
DriveApp.getFolderById('0B2DdOMvW2Q84N0s4a21LM05wbms').createFile(form.usagerId,blob);
obj = new {};
obj.photo = file.getUrl();
return obj;
}
on click Handler
function onUsagerEditFormSubmit() {
loading(true);
var form = this.parentNode;
google.script.run.withSuccessHandler(showUsager)
.withFailureHandler(showError)
.setUsager(form);
}
And the form :
<form name="usager-edit" id="usager-edit" method='post' enctype="multipart/form-data">
<div class="hidden">
<input type="text" name="type" id="type" value="USAGER" readonly="readonly" />
<input type="text" name="usagerId" id="usagerId" readonly="readonly" />
</div>
<div class="field-container">
<label for="nom">Nom</label>
<input type="text" name="nom" id="nom">
</div>
<div class="field-container">
<label for="prenom">Prenom</label>
<input type="text" name="prenom" id="prenom">
</div>
<div class="field-container">
<label for="photo">Photo</label>
<input class="file" type="file" name="photodata" id="photodata" accept='image/*'>
<div id="prev-photo" name="prev-photo"></div>
<div class="clear"></div>
</div>
<input class="myButton" onClick="onUsagerEditFormSubmit" type="button" name="save" id="save-button" value="Sauvegarder" />
</form>
You are using the wrong createFile method overload.
You are using createFile(name, content), when you should use createFile(blob).
...
var file = DriveApp.getFolderById('****************************').createFile(blob);
...
You must define file in order to make: obj.photo = file.getUrl();.
Also you can change the following:
...
<input class="myButton" onClick="onUsagerEditFormSubmit" type="button" name="save" id="save-button" value="Sauvegarder" />
...
by:
...
<input class="myButton" onClick="onUsagerEditFormSubmit(this.parentNode)" type="button" name="save" id="save-button" value="Sauvegarder" />
...
and
function onUsagerEditFormSubmit() {
loading(true);
var form = this.parentNode;
google.script.run.withSuccessHandler(showUsager)
.withFailureHandler(showError)
.setUsager(form);
}
by:
function onUsagerEditFormSubmit(form) {
loading(true);
google.script.run.withSuccessHandler(showUsager)
.withFailureHandler(showError)
.setUsager(form);
}
Slight changes:
...
Logger.log(Utilities.jsonStingify(blob);
...
obj = new {};
...
by:
...
Logger.log(Utilities.jsonStringify(blob));
...
var obj = {};
...