calling HTML using webViewShow in sl4a - javascript

trying out some basic html scripts with sl4a and my python application can't seem to call the HTML... trying to send data from a small form in the HTML over to the python side
here's the HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML form</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<div id="body">
<h1>My Settings</h1>
<script type="text/javascript">
var droid = new Android();
function post_data(){
var values = [
['airplane', document.getElementById('airplane_mode').value],
['wifi', document.getElementById('wifi_on').value],
['brightness', document.getElementById('brightness').value],
['volume', document.getElementById('volume').value],
];
var q = '?';
for (i=0;i<values.length;i++){
var k = values[i][0];
var v = values[i][1];
if (q != '?'){
q = q + '&';
}
q = q + k + '=' + v;
}
droid.postEvent('save', q);
}
</script>
<form onsubmit="post_data();">
<div class="container">
<div>
<label for="airplane_mode">Airplane Mode</label>
<input id="airplane_mode" name="radio" type="radio" />
</div>
<div>
<label for="wifi_on">WiFi On</label>
<input id="wifi_on" name="radio" type="radio" />
</div>
<div>
<label for="off">Both off</label>
<input id="off" name="radio" type="radio" />
</div>
</div>
<div class="container">
<div>
<label for="brightness">Brightness Level</label>
<input size="5" id="brightness" type="text" />
</div>
<div>
<label for="volume">Media Volume</label>
<input size="5" id="volume" type="text" />
</div>
</div>
<div class="container buttons">
<div>
<input size="5" id="save" name="save" type="submit" value="Save Settings" />
<input size="5" id="cancel" name="cancel" type="button" value="Cancel" />
</div>
</div>
</form>
</div>
</body>
</html>
here's the python end that uses the values passed from the js in the HTML to alter some phone options
import android
import urlparse
droid = android.Android()
droid.webViewShow('file:///tablet/sl4a/scripts/html/options.html')
while True:
result = droid.eventWaitFor('save').result
data = urlparse.parse_qs(result['data'][1:])
droid.toggleAirplaneMode('airplane' in data)
print 'airplane' in data
droid.toggleWifiState('wifi' in data)
print 'wifi' in data
droid.setScreenBrightness('screen' in data and 255 or 0)
thing is once I execute the python code, it does not call the webViewShow at all and simply closes stating that the response is not parseable because it's value is none, not a tuple so where exactly did I go wrong?
update: Tried different formats for the url so none worked. the webview itself is not being called
update 2: okay... webview is opening but all I get is a blank page that forces me to perform a hard kill using the task manager as sl4a freezes up there, as if it's trying to render the html
update 3: had the webViewShow refer to a non existent address and the screen issue keeps on happening. any ideas?
Py4A is the latest and SL4A version is R6. running on android 4.1.2

droid.webViewShow('file:///tablet/sl4a/scripts/html/options.html',None)

Related

In Google sheets I have a form in my sidebar that is not submitting the data. What is wrong with my code?

I'm new to coding and I wanted to make data entry more uniform in my worplace. And so I have been trying to create a html form in a sidebar and submit the resulting data to a speadsheet.
I have my form and my sidebar working but no matter what I try or which tutorial I follow I can't seem to wrap my head around how to get the data from the html form to my spreadsheet.
Here is the .gs
function onOpen(){
SpreadsheetApp.getUi()
.createMenu('Menu CFC')
.addItem('Ajout','showSidebar')
.addToUi();
showSidebar();
}
function showSidebar(){
var html = HtmlService.createHtmlOutputFromFile('menuCFC')
.setTitle('Mon menu CFC')
.setWidth(300);
SpreadsheetApp.getUi()
.showSidebar(html);
}
function formCFCSubmit(form_data){
var sheet = spreadsheetApp.getActive().getSheetByName('Feuille 1');
sheet.([form_data.nom,form_data.numéro])
}
and here is a simplified version of my html form for testing purpose.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form name="formAjoutCFC">
<div class ="block form-group">
<label for="Nom">Nom</label>
<input type="text" name="nom" id="nom" placeholder="Nom" required>
</div>
<div class ="block form-group">
<label for="Numéro">Numéro</label>
<input type="text" name="numéro" id="numéro" placeholder="Numéro" required>
</div>
<div class="block">
<button type="submit" class="action">Valider</button>
</div>
<div calss="block">
<input type="reset">
</div>
</form>
<script>
document.querySelector("#formAjoutCFC").addEventListener("submit", //not sure about the #
function(e)
{
e.preventDefault();
google.script.run.formCFCSubmit(this);
);
</script>
</body>
</html>
Any help would be welcome as I'm out of my depth at the moment ^^
You are doing all right #Lugh, very close to your goal indeed. But you need to take care of some things:
Your showSideBar function is alright too.
On your formCFCSubmit(form_data) you have errors:
The class you want to call from is SpreadsheetApp not (s)preadsheetApp.
sheet.([form_data.nom,form_data.numéro]) is not an existing method.
// For testing purposes, you can paste the data in ranges "A1" and "B1" for example:
function formCFCSubmit(form_data){
var sheet = SpreadsheetApp.getActive().getSheetByName('Feuille 1');
sheet.getRange('A1').setValue(form_data.nom);
sheet.getRange('B1').setValue(form_data.numero);
// Notice accent removed from numero!
// Putting accents in code will give you headaches sooner than later...
}
On your menuCFC.html:
Here is where most of your trouble is coming from...
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<!-- Notice 'id'! That's what the # in the query selector is referencing. Not name -->
<form id="formAjoutCFC">
<div class="block form-group">
<label for="Nom">Nom</label>
<input type="text" name="nom" id="nom" placeholder="Nom" required>
</div>
<div class="block form-group">
<label for="Numero">Numéro</label>
<input type="text" name="numero" id="numero" placeholder="Numéro" required>
</div>
<div class="block">
<button type="submit" class="action">Valider</button>
</div>
<div class="block">
<input type="reset">
</div>
</form>
<script>
document.querySelector("#formAjoutCFC")
.addEventListener(
"submit",
function(e) {
e.preventDefault();
google.script.run.formCFCSubmit(this);
}
);
</script>
</body>
</html>
Now the script in your sidebar, can get the form by id, and when submitted execute the formCFCSubmit function that does what you want it to with form_data.
Keep on coding!
Notes:
You should read official documentation now that you are into coding.
Read about the SpreadsheetsApp class from Apps Script's Spreadsheet service to find out which functions you can use to tailor to your need.

Form with input and output immediately reload the page after printing the output

I need to do a simple homework where you enter two integers in two text fields of a form and then you compute the sum and you print it in a "text field (not editable)". My program seems to work but it prints the right output and immediately reload the page. I want the page to remain with the printed output if the user does not click again on "submit" button
Here is my code HTML & JS :
function updateExpr() {
var x1 = document.getElementById("n1").value;
var x2 = document.getElementById("n2").value;
var sum = +x1 + +x2;
document.getElementById("sum").innerHTML = +x1 + +x2;
}
<!DOCTYPE html>
<html>
<head>
<title>Number in a form</title>
<link href="mystyle.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="function.js">
</script>
</head>
<body>
<div id="mainDiv">
<H3>Insert two positive numbers</H3>
<form>
First number:<br>
<input id="n1" type="text" name="firstname"><br>
Second number:<br>
<input id="n2" type="text" name="lastname">
<BR>
<input type="submit" value="Submit" onClick="updateExpr()"/><BR><BR>
</form>
The sum is:<br>
<output id="sum" name="x" for="a b"></output>
</div>
<noscript>
Sorry: Your browser does not support or has disabled javascript
</noscript>
</body>
</html>
When form is submited, the page will be reloaded. To prevent this you should change input type attribute from submit to button.
<input type="submit" value="Submit" onClick="updateExpr()"/>
to
<input type="button" value="Submit" onClick="updateExpr()"/>
You can simply avoid server call by changing your form tag
<form onSubmit="return false">
You dont really need a form to do something like this.
Forms send values to the backend, e.g. a server.
You only want to manipulate some front-end elements like a container to have some new text inside it.
a <form> tag typically sends you to some URI with some aprameters,
this is done by the actions attribute.
<form action="addnames.php">
for example would call the addnames.php script on your server...
You dont need a server tho..look below:
function updateExpr() {
var x1 = document.getElementById("n1").value;
var x2 = document.getElementById("n2").value;
var sum =x1 +x2;
document.getElementById("sum").innerHTML = sum;
}
<h2>HTML Forms</h2>
First name:<br>
<input id="n1" type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input id="n2" type="text" name="lastname" value="Mouse">
<br><br>
<button type="submit" onclick="updateExpr()">Submit</button>
<div id="sum">
</div>
<script>
</script>
I would recommand you to add onSubmit method to the form instead of onclick to the input.
Also you better add a return : false to your function and add onsubmit="return updateExpr()".
function updateExpr() {
var x1 = document.getElementById("n1").value;
var x2 = document.getElementById("n2").value;
var sum = +x1 + +x2;
document.getElementById("sum").innerHTML = +x1 + +x2;
return false;
}
<!DOCTYPE html>
<html>
<head>
<title>Number in a form</title>
<link href="mystyle.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="function.js">
</script>
</head>
<body>
<div id="mainDiv">
<H3>Insert two positive numbers</H3>
<form onsubmit="return updateExpr()">
First number:<br>
<input id="n1" type="text" name="firstname"><br>
Second number:<br>
<input id="n2" type="text" name="lastname">
<BR>
<input type="submit" value="Submit" onClick="updateExpr()"/><BR><BR>
</form>
The sum is:<br>
<output id="sum" name="x" for="a b"></output>
</div>
<noscript>
Sorry: Your browser does not support or has disabled javascript
</noscript>
</body>
Another way of doing this would have been to add a button outside of the form linked to the function by onclick event
juste add preventDefault(), like this
function updateExpr(e) {
e.preventDefault();
var x1 = document.getElementById("n1").value;
var x2 = document.getElementById("n2").value;
var sum = +x1 + +x2;
document.getElementById("sum").innerHTML = +x1 + +x2;
}

submitted HIT in mturk workersandbox, but can't view result in requester sandbox

I keep running into mysterious issues when testing my sample MTurk task in the sandbox environment. In the requester environment, I create a task by copy/pasting HTML/JS code into the "Source" text box under Create > Edit Project > (2) Design Layout.
I'm able to preview the task on that page, and it appears to work correctly. I can also publish the HIT in the RequesterSandbox, which lands me on this page: RequesterSandbox > Manage > Results
I can also log into the WorkerSandbox, find my HIT, and complete it. However, when I press submit, I'm redirected to a page that says "Loading next HIT...," and then to another page, which says "Sorry, we couldn't find that page.
Strange...the page you were looking for is not here. Let's go home and try again"
Going BACK to the RequesterSandbox, there is no evidence that the HIT was submitted at all, and I can't find the HIT results. I suspect that it isn't being submitted properly in the WorkerSandbox, but I'm not sure how to fix it. Any advice would be greatly appreciated!!
Here is the HTML/javascript code for my sample task:
// extract url parameters
var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {
queryDict[item.split("=")[0]] = item.split("=")[1]
})
// use extracted url parameters to populate form
$("#endForm").attr("action",queryDict["host"]);
$("#assignmentID").val(queryDict["assignmentId"]);
$("workerId").val(queryDict["workerId"]);
$("#hitId").val(queryDict["hitId"]);
// reveal submit button after radio button is selected
$('#question_buttons').change(function(){
var btnResponse = $("input[name='theseButtons']:checked").val();
if (btnResponse == "thisOne" || btnResponse == "thatOne") {
$("#endTask").removeClass("hidden");
}
})
// submit response
$("submitButton").click(function() {
$("#endForm").submit();
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>MTurk HIT Test</title>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<form action="https://workersandbox.mturk.com/mturk/externalSubmit" id="endForm" method="post" name="endForm">
<input id="data" name="data" type="hidden" value="" />
<input id="assignmentId" name="assignmentId" type="hidden" value="{{ assignment_id }}" />
<input id="workerId" name="workerId" type="hidden" value="{{ workerId }}" />
<input id="hitId" name="hitId" type="hidden" value="{{ hitId }}" />
<div class="container">
<h3>Write something:</h3>
<br />
<textarea cols="50" name="answer" rows="2"></textarea>
</div>
<div class="container" id="question_text">
<h3>Select one of these options:</h3>
</div>
<div class="container" id="question_buttons">
<div class="radio-inline">
<label><input name="theseButtons" type="radio" value="thisOne" />this one</label>
</div>
<div class="radio-inline"><label>
<input name="theseButtons" type="radio" value="thatOne" />that one</label>
</div>
</div>
<div class="container hidden" id="endTask">
<h3>Submit form by clicking the button below:</h3>
<br />
<input id="submitButton" name="submitButton" type="submit" />
</div>
</form>
The results created on sandbox worker UI would not show on the sandbox requester page.
You can also see the answer through this URL:
MTurk HITs created Through Java API are not showing on Manage Tab on UI
There is a console tool to manage the Mturk HIT on sandbox.

How to insert into .html file the template obtained from google app script HTMLService class?

I have a button and I would like to replace it with other HTML object loaded by google app script via method HtmlService.createTemplateFromFile('HTML_file').
The button onclick function is written in javascript in .html file:
<div id="add_form_button_wraper">
<input type="button" id="add_form" onclick="addForm()" value="Add Form">
</div>
<script>
function addForm() {
innerHTML = google.script.run.getForm(some_args);
document.getElementById("add_form_button_wraper").innerHTML =
innerHTML;
}
</script>
The Code.gs code looks following:
getForm(arg1, arg2) {
// Creating HTML template from html file.
var template = HtmlService.createTemplateFromFile(HTML_TEMPLATE);
template.arg1 = arg1;
template.arg2 = arg2;
return template.evaluate().getContent();
}
After clicking the button the content of the div is changed to undefined. I tried also HTMLService.createTemplateFromFile().getCode() with the same effect.
How to insert into div the raw html code obtained from app script HTMLService?
A Simple Web App Example
Here's how I do my dialogs and web apps. I know it doesn't necessarily pertain to your particular situation but hopefully a working example can give you some ideas as to how you can proceed.
This is a simple example of a standard web app form. You can view it as a dialog or run it as a webapp. It stores all of the response on a sheet.
Code.gs:
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Display Dialog', 'displayDialog')
.addToUi();
}
function doGet()
{
var output=HtmlService.createHtmlOutputFromFile('CyclingSurvey');
return output.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
Cycling Survey.gs:
function storeCyclingSurveyResults(rA)
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('CyclingSurvey');
var ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss");
rA.splice(0,0,ts);
sh.appendRow(rA);
return true;
}
function displayDialog()
{
var html=HtmlService.createHtmlOutputFromFile('CyclingSurvey').setWidth(800).setHeight(500);
SpreadsheetApp.getUi().showModelessDialog(html, 'Cycling Survey');
}
Cycling Survey.html:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function recordData()
{
var q1=$('#q1').val();
var q2=$('input[name="prefer"]:checked').val();
var checked = [];
$("input[name='own']:checked").each(function (){checked.push($(this).val());});
var q3=checked.join(', ');
var q4=$('#q4').val();
var rA=[];
rA.push(q1);
rA.push(q2);
rA.push(q3);
rA.push(q4);
google.script.run
.withSuccessHandler(setResponse)
.storeCyclingSurveyResults(rA);
}
function setResponse()
{
$('#reply').css('display','inline');
$('#collect').css('display','none');
}
console.log('script here');
</script>
<style>
#reply{display:none;}
#collect{display:block;}
</style>
</head>
<body>
<div id="reply" >Thanks for taking the time to take our survey. Your results have been recorded.</div>
<div id="collect">
<div style="font-weight:bold">What do you like about cycling?</div>
<textarea id="q1" rows="4" cols="50" placeholder="Enter Text Here..."></textarea>
<div style="font-weight:bold">Which type of bike do you prefer?</div>
<input type="radio" name="prefer" value="mountain bike">Mountain Bike<br />
<input type="radio" name="prefer" value="road bike" checked>Road Bike<br />
<input type="radio" name="prefer" value="fitness bike">Fitness Bike<br />
<div style="font-weight:bold">What types of bikes do you currently own?</div>
<input type="checkbox" name="own" value="Mountain Bike">Mountain Bike<br />
<input type="checkbox" name="own" value="Road Bike" checked>Road Bike<br />
<input type="checkbox" name="own" value="All Terrain Bike">All Terain Bike<br />
<input type="checkbox" name="own" value="Fitness Bike">Fitness Bike<br />
<div style="font-weight:bold">Do you prefer riding with others or alone?</div>
Alone<input id="q4" type="range" name="rating" max="10" min="0" step="1" defaultValue="5"/>Others<br />
<input type="button" id="btn1" value="Submit" onClick="recordData();" />
</div>
</body>
</html>

html How can I get multiple instant results from single calculation

Is it possible to get a dozen results from this single basic calculation? I have two output textboxes in the sample code; how can I get these two fields to work?
<!DOCTYPE html>
<html lang = "en">
<head>
<title> multiple results calculation </title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<link rel="style" href="css/main.css" type"text/css"/>
<!-- I need multiple results from single calculation!
<script type="text/javascript">
function sum()
{
var width = document.multiple results.width.value;
var height = document.multiple results.value;
var sum = parseInt(width) * parseInt(height) /144;
document.getElementById('Calculate').value = sum;
document.getElementById("results1").readOnly=true;
document.getElementById("results2").readOnly=true;
var result1= $1.99;
var result2= $2.99;
document.getElementById('Calculate').value = sum * result1;
document.getElementById('Calculate').value = sum * result2;
}
</script>
-->
</head>
<body>
<div>
<H2> Multiple instant results from single calculation</h2>
<p> the goal eventually is to have about a dozen results from this single calculation
</div>
<form name="multiple results">
<label for="width"> Width: </label>
<input type="number" <id="width" maxlength="4" size="10" value=""/>
<label for="height"> Height: </label>
<input type="number" <id="height" maxlength="4" size="10" value=""/>
<input type="button" name="button" value="Calculate" onClick="sum"/>
<div>
<label for="result1"> Result1: $ </label>
<input type="number" id="result1" name="result1"/>
<label for="result2"> Result2: $ </label>
<input type="number" id="result2" name="result2"/>
</div>
</form>
</body>
</html>
I found a solution by removing the first document.getElementById('Calculate').value = sum;, changed the remaining getElementById's and input type's to result and result2 also added the missing value="" to input, not necessary but renaming Id's helped me

Categories