Microsoft Cognitive Services Speech Save option - javascript

I have written the following code, which works OK to convert text to speech and play it through the speaker. I am using Microsoft Cognitive Services.
<html lang="en">
<head>
<title>Microsoft Cognitive Services Speech SDK JavaScript Sample for Speech Synthesis</title>
<meta charset="utf-8" />
<style>
body {
font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif;
font-size: 14px;
}
table, th, td {
border: 1px solid #f1f1f1;
border-collapse: collapse;
}
th, td {
padding: 10px;
}
textarea {
font-family: Arial,sans-serif;
}
.mode {
font-size: 18px;
}
.highlight{
background-color: yellow;
}
input:not(disabled) {
font-weight: bold;
color: black;
}
button {
padding: 4px 8px;
background: #0078d4;
color: #ffffff;
}
button:disabled {
padding: 4px 8px;
background: #ccc;
color: #666;
}
input[type=radio] {
position: relative;
z-index: 1;
}
input[type=radio] + label {
padding: 8px 4px 8px 30px;
margin-left: -30px;
}
input[type=radio]:checked + label {
background: #0078d4;
color: #ffffff;
}
</style>
</head>
<body>
<div id="warning">
<h1 style="font-weight:500;">Speech Speech SDK not found
(microsoft.cognitiveservices.speech.sdk.bundle.js missing).</h1>
</div>
<div id="content" style="display:none">
<table>
<tr>
<td></td>
<td><h1 style="font-weight:500;">Microsoft Cognitive Services</h1></td>
</tr>
<tr>
<td align="right">
<label for="subscriptionKey">
<a href="https://learn.microsoft.com/azure/cognitive-services/speech-service/get-started"
rel="noreferrer noopener"
target="_blank">Subscription Key</a>
</label>
</td>
<td><input id="subscriptionKey" type="text" size="40" placeholder="YourSubscriptionKey"></td>
</tr>
<tr>
<td align="right"><label for="regionOptions">Region</label></td>
<td>
<!-- see https://aka.ms/csspeech/region for more details-->
<select id="regionOptions">
<option value="uksouth">UK South</option>
</select>
</td>
</tr>
<tr>
<td align="right"><label for="voiceOptions">Voice</label></td>
<td>
<button id="updateVoiceListButton">Update Voice List</button>
<select id="voiceOptions" disabled>
<option>Please update voice list first.</option>
</select>
</td>
</tr>
<tr>
<td align="right"><label for="isSSML">Is SSML</label><br></td>
<td>
<input type="checkbox" id="isSSML" name="isSSML" value="ssml">
</td>
</tr>
<tr>
<td align="right"><label for="synthesisText">Text</label></td>
<td>
<textarea id="synthesisText" style="display: inline-block;width:500px;height:100px"
placeholder="Input text or ssml for synthesis."></textarea>
</td>
</tr>
<tr>
<td></td>
<td>
<button id="startSynthesisAsyncButton">Start synthesis</button>
<button id="pauseButton">Pause</button>
<button id="resumeButton">Resume</button>
</td>
</tr>
<tr>
<td align="right" valign="top"><label for="resultsDiv">Results</label></td>
<td><textarea id="resultsDiv" readonly style="display: inline-block;width:500px;height:50px"></textarea></td>
</tr>
<tr>
<td align="right" valign="top"><label for="eventsDiv">Events</label></td>
<td><textarea id="eventsDiv" readonly style="display: inline-block;width:500px;height:200px"></textarea></td>
</tr>
<tr>
<td align="right" valign="top"><label for="highlightDiv">Highlight</label></td>
<td><div id="highlightDiv" style="display: inline-block;width:800px;"></div></td>
</tr>
</table>
</div>
<!-- Speech SDK reference sdk. -->
<script src="microsoft.cognitiveservices.speech.sdk.bundle.js"></script>
<!-- Speech SDK Authorization token -->
<script>
// Note: Replace the URL with a valid endpoint to retrieve
// authorization tokens for your subscription.
var authorizationEndpoint = "token.php";
function RequestAuthorizationToken() {
if (authorizationEndpoint) {
var a = new XMLHttpRequest();
a.open("GET", authorizationEndpoint);
a.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
a.send("");
a.onload = function() {
var token = JSON.parse(atob(this.responseText.split(".")[1]));
serviceRegion.value = token.region;
authorizationToken = this.responseText;
subscriptionKey.disabled = true;
subscriptionKey.value = "using authorization token (hit F5 to refresh)";
console.log("Got an authorization token: " + token);
}
}
}
</script>
<!-- Speech SDK USAGE -->
<script>
// On document load resolve the Speech SDK dependency
function Initialize(onComplete) {
if (!!window.SpeechSDK) {
document.getElementById('content').style.display = 'block';
document.getElementById('warning').style.display = 'none';
onComplete(window.SpeechSDK);
}
}
</script>
<!-- Browser Hooks -->
<script>
// status fields and start button in UI
var resultsDiv, eventsDiv;
var highlightDiv;
var startSynthesisAsyncButton, pauseButton, resumeButton;
var updateVoiceListButton;
// subscription key and region for speech services.
var subscriptionKey, regionOptions;
var authorizationToken;
var voiceOptions, isSsml;
var SpeechSDK;
var synthesisText;
var synthesizer;
var player;
var wordBoundaryList = [];
document.addEventListener("DOMContentLoaded", function () {
startSynthesisAsyncButton = document.getElementById("startSynthesisAsyncButton");
updateVoiceListButton = document.getElementById("updateVoiceListButton");
pauseButton = document.getElementById("pauseButton");
resumeButton = document.getElementById("resumeButton");
subscriptionKey = document.getElementById("subscriptionKey");
regionOptions = document.getElementById("regionOptions");
resultsDiv = document.getElementById("resultsDiv");
eventsDiv = document.getElementById("eventsDiv");
voiceOptions = document.getElementById("voiceOptions");
isSsml = document.getElementById("isSSML");
highlightDiv = document.getElementById("highlightDiv");
setInterval(function () {
if (player !== undefined) {
const currentTime = player.currentTime;
var wordBoundary;
for (const e of wordBoundaryList) {
if (currentTime * 1000 > e.audioOffset / 10000) {
wordBoundary = e;
} else {
break;
}
}
if (wordBoundary !== undefined) {
highlightDiv.innerHTML = synthesisText.value.substr(0, wordBoundary.textOffset) +
"<span class='highlight'>" + wordBoundary.text + "</span>" +
synthesisText.value.substr(wordBoundary.textOffset + wordBoundary.wordLength);
} else {
highlightDiv.innerHTML = synthesisText.value;
}
}
}, 50);
updateVoiceListButton.addEventListener("click", function () {
var request = new XMLHttpRequest();
request.open('GET',
'https://' + regionOptions.value + ".tts.speech." +
(regionOptions.value.startsWith("china") ? "azure.cn" : "microsoft.com") +
"/cognitiveservices/voices/list", true);
if (authorizationToken) {
request.setRequestHeader("Authorization", "Bearer " + authorizationToken);
} else {
if (subscriptionKey.value === "" || subscriptionKey.value === "subscription") {
alert("Please enter your Microsoft Cognitive Services Speech subscription key!");
return;
}
request.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey.value);
}
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
const response = this.response;
const neuralSupport = (response.indexOf("JessaNeural") > 0);
const defaultVoice = neuralSupport ? "JessaNeural" : "JessaRUS";
let selectId;
const data = JSON.parse(response);
voiceOptions.innerHTML = "";
data.forEach((voice, index) => {
voiceOptions.innerHTML += "<option value=\"" + voice.Name + "\">" + voice.Name + "</option>";
if (voice.Name.indexOf(defaultVoice) > 0) {
selectId = index;
}
});
voiceOptions.selectedIndex = selectId;
voiceOptions.disabled = false;
} else {
window.console.log(this);
eventsDiv.innerHTML += "cannot get voice list, code: " + this.status + " detail: " + this.statusText + "\r\n";
}
};
request.send()
});
pauseButton.addEventListener("click", function () {
player.pause();
pauseButton.disabled = true;
resumeButton.disabled = false;
});
resumeButton.addEventListener("click", function () {
player.resume();
pauseButton.disabled = false;
resumeButton.disabled = true;
});
startSynthesisAsyncButton.addEventListener("click", function () {
startSynthesisAsyncButton.disabled = true;
resultsDiv.innerHTML = "";
eventsDiv.innerHTML = "";
wordBoundaryList = [];
synthesisText = document.getElementById("synthesisText");
// if we got an authorization token, use the token. Otherwise use the provided subscription key
var speechConfig;
if (authorizationToken) {
speechConfig = SpeechSDK.SpeechConfig.fromAuthorizationToken(authorizationToken, serviceRegion.value);
} else {
if (subscriptionKey.value === "" || subscriptionKey.value === "subscription") {
alert("Please enter your Microsoft Cognitive Services Speech subscription key!");
return;
}
speechConfig = SpeechSDK.SpeechConfig.fromSubscription(subscriptionKey.value, regionOptions.value);
}
speechConfig.speechSynthesisVoiceName = voiceOptions.value;
// The SDK uses Media Source Extensions (https://www.w3.org/TR/media-source/) for playback.
// Mp3 format is supported in most browsers.
speechConfig.speechSynthesisOutputFormat = SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
player = new SpeechSDK.SpeakerAudioDestination();
player.onAudioEnd = function (_) {
window.console.log("playback finished");
eventsDiv.innerHTML += "playback finished" + "\r\n";
startSynthesisAsyncButton.disabled = false;
pauseButton.disabled = true;
resumeButton.disabled = true;
wordBoundaryList = [];
};
var audioConfig = SpeechSDK.AudioConfig.fromSpeakerOutput(player);
var audioConfig = AudioConfig.FromWavFileOutput("/var/www/html/unitypst/customfiles/tts/ttsfile.wav");
synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig);
// The event synthesizing signals that a synthesized audio chunk is received.
// You will receive one or more synthesizing events as a speech phrase is synthesized.
// You can use this callback to streaming receive the synthesized audio.
synthesizer.synthesizing = function (s, e) {
window.console.log(e);
eventsDiv.innerHTML += "(synthesizing) Reason: " + SpeechSDK.ResultReason[e.result.reason] +
"Audio chunk length: " + e.result.audioData.byteLength + "\r\n";
};
// The synthesis started event signals that the synthesis is started.
synthesizer.synthesisStarted = function (s, e) {
window.console.log(e);
eventsDiv.innerHTML += "(synthesis started)" + "\r\n";
pauseButton.disabled = false;
};
// The event synthesis completed signals that the synthesis is completed.
synthesizer.synthesisCompleted = function (s, e) {
console.log(e);
eventsDiv.innerHTML += "(synthesized) Reason: " + SpeechSDK.ResultReason[e.result.reason] +
" Audio length: " + e.result.audioData.byteLength + "\r\n";
};
// The event signals that the service has stopped processing speech.
// This can happen when an error is encountered.
synthesizer.SynthesisCanceled = function (s, e) {
const cancellationDetails = SpeechSDK.CancellationDetails.fromResult(e.result);
let str = "(cancel) Reason: " + SpeechSDK.CancellationReason[cancellationDetails.reason];
if (cancellationDetails.reason === SpeechSDK.CancellationReason.Error) {
str += ": " + e.result.errorDetails;
}
window.console.log(e);
eventsDiv.innerHTML += str + "\r\n";
startSynthesisAsyncButton.disabled = false;
pauseButton.disabled = true;
resumeButton.disabled = true;
};
// This event signals that word boundary is received. This indicates the audio boundary of each word.
// The unit of e.audioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
synthesizer.wordBoundary = function (s, e) {
window.console.log(e);
eventsDiv.innerHTML += "(WordBoundary), Text: " + e.text + ", Audio offset: " + e.audioOffset / 10000 + "ms." + "\r\n";
wordBoundaryList.push(e);
};
const complete_cb = function (result) {
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
resultsDiv.innerHTML += "synthesis finished";
} else if (result.reason === SpeechSDK.ResultReason.Canceled) {
resultsDiv.innerHTML += "synthesis failed. Error detail: " + result.errorDetails;
}
window.console.log(result);
synthesizer.close();
synthesizer = undefined;
};
const err_cb = function (err) {
startSynthesisAsyncButton.disabled = false;
phraseDiv.innerHTML += err;
window.console.log(err);
synthesizer.close();
synthesizer = undefined;
};
if (isSsml.checked) {
synthesizer.speakSsmlAsync(synthesisText.value,
complete_cb,
err_cb);
} else {
synthesizer.speakTextAsync(synthesisText.value,
complete_cb,
err_cb);
}
});
Initialize(function (speechSdk) {
SpeechSDK = speechSdk;
startSynthesisAsyncButton.disabled = false;
pauseButton.disabled = true;
resumeButton.disabled = true;
saveButton.disabled = true;
// in case we have a function for getting an authorization token, call it.
if (typeof RequestAuthorizationToken === "function") {
RequestAuthorizationToken();
}
});
});
</script>
</body>
</html>
What I would like to do now is add the option to save the synthesized speech data to disk, and prompt the user to download the file. Is this possible using the Microsoft Cognitive Services Speech SDK? How should I modify the code to support a "save" or "download" option?

we have a sample to show how to save the TTS audio under browser using Azure Speech SDK.

Related

Create a file with the same name as the folder where a file was uploaded

I have an HTML form within a Web App, created with GAS.
This HTML form was created from this file upload script here:
drive-multi-upload
This is the HTML form:
The point is that I needed the files to be uploaded in folders that follow the following pattern:
The first number refers to the model selected on the form, the second number refers to the slot used.
Therefore, it was necessary to create a function to identify the input chosen in the Model and, according to this input, check which is the first empty folder, then take the ID of that folder and pass it to the client side to upload the file inside it.
With the help of some members of the community, some adaptations were made and the final function was this:
/** Modified version of script written by Tanaike */
function createOrGetFolder(folderName, parentFolderId) {
try {
var parentFolder = DriveApp.getFolderById(parentFolderId), folder;
if (parentFolder) {
var foldersIter = parentFolder.getFoldersByName("Video");
if (foldersIter.hasNext()) {
var videoFolder = foldersIter.next();
var nextFolderName = folderName + "-01";
while (!folder) {
video_folder = videoFolder.getFoldersByName(nextFolderName);
if (video_folder.hasNext()) {
folder = video_folder.next();
var files = folder.getFiles();
if (files.hasNext()) {
var [a, b] = nextFolderName.split("-");
nextFolderName = `${a}-${String(Number(b) + 1).padStart(2, "0")}`;
folder = null;
}
} else {
folder = videoFolder.createFolder(nextFolderName);
}
}
} else {
folder = parentFolder.createFolder("Video");
folder = folder.createFolder(folderName);
}
} else {
throw new Error("Parent Folder with id: " + parentFolderId + " not found");
}
return folder.getId();
} catch (error) {
return error;
}
}
It works perfectly, the point is that this form also has a function that generates a .csv file when the form is submitted, the function is this one:
.gs file:
const saveDataAsCSV = (data, folderId) => DriveApp.getFolderById(folderId).createFile("Sample.csv", data);
HTML file:
var name = $('#name01').val();
var description = $('#description').val();
var model = $('#Model').val();
upload_folder = model;
var color = $('#Color').val();
var form_values = [name, description, model, color];
var data = form_values.join(",");
google.script.run.saveDataAsCSV(data, uploadParentFolderId);
My goal is to make the .csv file be generated with the same name as the folder where the file was uploaded, that is, if the file is uploaded in folder 01-01, the file name has to be 01-01.csv, if the file is uploaded in the 02-02 folder, the file name has to be 02-02.csv, and so on.
How can I achieve this?
The complete script code can be viewed here:
.gs file:
function doGet(e) {
return HtmlService.createTemplateFromFile('forms0101.html').evaluate();
}
function getOAuthToken() {
return ScriptApp.getOAuthToken();
}
function getParent(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var id = ss.getId();
var parent = DriveApp.getFileById(id).getParents().next().getId();
return parent
}
function getLimitFolder(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pastapai = DriveApp.getFileById(ss.getId()).getParents();
var limitfolder = pastapai.next().getFoldersByName("_").next().getId();
return limitfolder;
}
function getFilesLimit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pastapai = DriveApp.getFileById(ss.getId()).getParents();
var files = [];
Logger.log(pastapai);
//var limitfolder = pastapai.next().getFoldersByName("_").next().getId();
var limitfolder = pastapai.next().getFoldersByName("_").next().getFiles();
while(limitfolder.hasNext()){
var file = limitfolder.next();
files.push([file.getId()]);
}
console.log(files.length);
return files.length;
}
//function testenumeroarquivos(){
//console.log(checkForFiles()); // When you use this line, you can see the filename of the files.
//}
/**
* creates a folder under a parent folder, and returns it's id. If the folder already exists
* then it is not created and it simply returns the id of the existing one
*/
function createOrGetFolder(folderName, parentFolderId) {
try {
var parentFolder = DriveApp.getFolderById(parentFolderId), folder;
if (parentFolder) {
var foldersIter = parentFolder.getFoldersByName("Video");
if (foldersIter.hasNext()) {
var videoFolder = foldersIter.next();
var nextFolderName = folderName + "-01";
while (!folder) {
video_folder = videoFolder.getFoldersByName(nextFolderName);
if (video_folder.hasNext()) {
folder = video_folder.next();
var files = folder.getFiles();
if (files.hasNext()) {
var [a, b] = nextFolderName.split("-");
nextFolderName = `${a}-${String(Number(b) + 1).padStart(2, "0")}`;
folder = null;
}
} else {
folder = videoFolder.createFolder(nextFolderName);
}
}
} else {
folder = parentFolder.createFolder("Video");
folder = folder.createFolder(folderName);
}
} else {
throw new Error("Parent Folder with id: " + parentFolderId + " not found");
}
console.log("Test" + nextFolderName)
return folder.getId();
} catch (error) {
return error;
}
}
const saveDataAsCSV = (data, folderId) => {
const folder = DriveApp.getFolderById(folderId);
folder.createFile(`${nextFolderName.getName()}.csv`, data);
}
const increaseRequest = (data, folderId) => DriveApp.getFolderById(folderId).createFile("IncreaseRequest.csv", data);
// NOTE: always make sure we use DriveApp, even if it's in a comment, for google to import those
// libraries and allow the rest of the app to work. see https://github.com/tanaikech/Resumable_Upload_For_WebApps
HTML file:
<!DOCTYPE html>
<html>
<head>
<base target="_blank">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Drive Multi Large File Upload</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
#import url('https://fonts.googleapis.com/css2?family=Rubik:wght#400;600;700&display=swap');
.disclaimer{
width: 480px;
color: #646464;
margin: 20px auto;
padding:0 16px;
text-align:center;
font:400 12px Rubik,sans-serif;
}
h5.center-align.teal-text {
font:700 26px Rubik,sans-serif;
color: #00F498!important;
}
.row {
font:600 14px Rubik,sans-serif;
}
.btn {
background-color: black;
}
.btn:hover {
background-color: #00F498;
}
body {
margin-top: -40px;
}
#progress {
color: #00000;
}
.disclaimer a{
color: #00BCAA;
}
#credit{
display:none
}
.btnOpenModal {
font-size: x-large;
padding: 10px;
border: none;
border-radius: 5px;
background-color: blueviolet;
color: white;
cursor: pointer;
}
hr {
border: 0px;
border-top: 1px solid lightgray;
}
.modal-container {
width: 100vw;
position: fixed;
top: 30px;
display: none;
z-index: 999;
justify-content: center;
}
.modal {
display: flex;
flex-direction: column;
padding: 30px;
background-color: white;
border-radius: 10px;
width: 50%;
}
.active {
display: flex;
}
.active .modal {
animation: modal .4s;
}
#keyframes modal {
from {
opacity: 0;
transform: translate3d(0, -60px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.btns {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.btns button {
font-size: medium;
padding: 10px;
border: none;
border-radius: 5px;
color: white;
cursor: pointer;
}
.btnOK {
background-color: blue!important;
}
.btnClose {
background-color: brown!important;
}
</style>
</head>
<body>
<form class="main" id="form" novalidate="novalidate" style="max-width: 480px;margin: 40px auto;">
<div id="forminner">
<div class="modal-container">
<div class="modal">
<h2>Info</h2>
<hr />
<span>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of
type and scrambled it to make a type specimen book.
</span>
<hr />
<div class="btns">
<button class="btnOK" onclick="increaseRequest(); closeModal();">OK</button>
<button class="btnClose" onclick="closeModal()">Close</button>
</div>
</div>
</div>
<h5 class="center-align teal-text" style="margin-bottom: -10px; font-size: 20px; font-family: Rubik; ">YOUR NAME</h5>
<div class="row">
<div class="input-field col s12">
<input id="name01" type="text" name="Name" class="validate" required="required" aria-required="true">
<label for="name" class="">Name</label>
</div>
</div>
<h5 class="center-align teal-text" style="margin-bottom: -10px; font-size: 20px; font-family: Rubik; ">SOME DESCRIPTION</h5>
<div class="row">
<div class="input-field col s12">
<input id="description" type="text" name="Description" class="validate" required="required" aria-required="true">
<label for="name">Description</label>
</div>
</div>
<div class="row">
<div class="col-8 col-md-4">
<h6>Model</h6>
<select class="custom-select" id="Model">
<option selected="">Choose...</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
</select>
<h6>Color</h6>
<select class="custom-select" id="Color">
<option selected="">Choose...</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
</select>
</div>
</div>
<div class="row">
<div class="col s12">
<h5 class="center-align teal-text">Upload the Video File</h5>
</div>
</div>
<div class="row">
<div class="file-field input-field col s12">
<div id="input-btn" class="btn">
<span>File</span>
<input id="files" type="file" single="">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Select the file">
</div>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<button id="submit-btn" class="waves-effect waves-light btn submit-btn" type="submit" onclick="submitForm(); return false;">Submit</button>
</div>
</div>
<div class="row">
<div class="input-field col s12 hide" id="update">
<hr>
<p>
Por favor, aguarde enquanto seu arquivo está sendo carregado.<br><span style="color: #00000;"><b>Não feche ou atualize a janela durante o upload.</b></span>
</p>
</div>
</div>
<div class="row">
<div class="input-field col s12" id="progress">
</div>
</div>
</div>
</div>
<div id="success" style="display:none">
<h5 class="center-align teal-text">Tudo certo!</h5>
<p>Se você já preencheu todos os campos é só fechar essa janela e clicar em enviar!</p>
<button id="fechar" class="waves-effect waves-light btn submit-btn" style ="transform: translateX(160%);" type="button" onclick="google.script.host.close()">Fechar</button>
</div>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
<script src="https://gumroad.com/js/gumroad.js"></script>
<script>
var upload_folder = "01";
const chunkSize = 5242880;
const uploadParentFolderId = <?=getParent()?>; // creates a folder inside of this folder
const limitfolder = <?=getLimitFolder()?>;
const fileslimit = <?=getFilesLimit()?>;
const modal = document.querySelector('.modal-container');
var name = $('#name01').val();
var description = $('#description').val();
var model = $('#Model').val();
upload_folder = model;
var color = $('#Color').val();
var form_values = [name, description, model, color];
form_values = form_values.map(r => r.replaceAll(",", "#")); // Essa linha substitui todas as "," por "#" antes de gerar o .csv
var data = form_values.join(",");
function submitForm() {
var name = $('#name01').val();
var description = $('#description').val();
var model = $('#Model').val();
upload_folder = model;
var color = $('#Color').val();
var form_values = [name, description, model, color];
form_values = form_values.map(r => r.replaceAll(",", "#")); // Essa linha substitui todas as "," por "#" antes de gerar o .csv
var data = form_values.join(",");
// Added the below script.
if ($('#submit-btn.disabled')[0]) return; // short circuit
var name = upload_folder
var files = [...$('#files')[0].files]; // convert from FileList to array
if (files.length === 0) {
showError("Por favor, selecione um arquivo");
return;
}
google.script.run.saveDataAsCSV(data, uploadParentFolderId);
google.script.run.saveDataAsCSV(data, limitfolder);
disableForm(); // prevent re submission
// the map and reduce are here to ensure that only one file is uploaded at a time. This allows
// the promises to be run sequentially
files.map(file => uploadFilePromiseFactory(file))
.reduce((promiseChain, currentTask) => {
return promiseChain.then(currentTask);
}, Promise.resolve([])).then( () => {
console.log("Completed all files upload");
showSuccess();
});
}
function checkforfiles() {
if (fileslimit <= 2) {
submitForm();
}
if (fileslimit == 3) {
openModal();
}
if (fileslimit >= 4) {
showError("erro");
return;
}
}
function openModal() {
modal.classList.add('active');
}
function closeModal() {
modal.classList.remove('active');
}
function increaseRequest() {
google.script.run.increaseRequest(data, limitfolder);
}
function disableForm() {
$('#submit-btn').addClass('disabled');
$('#input-btn').addClass('disabled');
$('#update').removeClass('hide');
$('#update').removeClass('hide');
}
function closer(){
google.script.host.close();
}
function uploadFilePromiseFactory(file) {
return () => {
console.log("Processing: ", file.name);
return new Promise((resolve, reject) => {
showProgressMessage("Seu arquivo está sendo carregado");
var fr = new FileReader();
fr.fileName = file.name;
fr.fileSize = file.size;
fr.fileType = file.type;
// not sure of a better way of passing the promise functions down
fr.resolve = () => resolve();
fr.reject = (error) => reject(error);
fr.onload = onFileReaderLoad;
fr.readAsArrayBuffer(file);
});
};
}
/**
* Gets called once the browser has loaded a file. The main logic that creates a folder
* and initiates the file upload resides here
*/
function onFileReaderLoad(onLoadEvent) {
var fr = this;
var newFolderName = upload_folder
createOrGetFolder(newFolderName, uploadParentFolderId).then(newFolderId => {
console.log("Found or created guest folder with id: ", newFolderId);
uploadFileToDriveFolder.call(fr, newFolderId).then(() => {
fr.resolve();
}, (error) => {
fr.reject(error);
});
},
(error) => {
if (error) {
showError(error.toString());
}
console.log("onFileReaderLoad Error2: ", error);
});
}
/**
* call to the DriveApp api. Wrapped in a promise in case I want to address timing issues between a
* createFolder and findFolderById
*/
function createOrGetFolder(folderName, parentFolderId) {
return new Promise((resolve, reject) => {
google.script.run.withSuccessHandler(response => {
console.log("createOrGetFolder response: ", response);
if (response && response.length) {
resolve(response);
}
reject(response);
}).createOrGetFolder(folderName, parentFolderId);
});
}
/**
* Helper functions modified from:
* https://github.com/tanaikech/Resumable_Upload_For_WebApps
*/
function uploadFileToDriveFolder(parentFolderId) {
var fr = this;
return new Promise((resolve, reject) => {
var fileName = fr.fileName;
var fileSize = fr.fileSize;
var fileType = fr.fileType;
console.log({fileName: fileName, fileSize: fileSize, fileType: fileType});
var buf = fr.result;
var chunkpot = getChunkpot(chunkSize, fileSize);
var uint8Array = new Uint8Array(buf);
var chunks = chunkpot.chunks.map(function(e) {
return {
data: uint8Array.slice(e.startByte, e.endByte + 1),
length: e.numByte,
range: "bytes " + e.startByte + "-" + e.endByte + "/" + chunkpot.total,
};
});
google.script.run.withSuccessHandler(oAuthToken => {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable");
xhr.setRequestHeader('Authorization', "Bearer " + oAuthToken);
xhr.setRequestHeader('Content-Type', "application/json");
xhr.send(JSON.stringify({
mimeType: fileType,
name: fileName,
parents: [parentFolderId]
}));
xhr.onload = () => {
doUpload(fileName, {
location: xhr.getResponseHeader("location"),
chunks: chunks,
}).then(success => {
resolve(success);
console.log("Successfully uploaded: ", fileName);
},
error => {
reject(error);
});
};
xhr.onerror = () => {
console.log("ERROR: ", xhr.response);
reject(xhr.response);
};
}).getOAuthToken();
});
}
function showSuccess() {
$('#forminner').hide();
$('#success').show();
$('#fechar').show();
}
function showError(e) {
$('#progress').addClass('red-text').html(e);
}
function showMessage(e) {
$('#update').html(e);
}
function showProgressMessage(e) {
$('#progress').removeClass('red-text').html(e);
}
/**
* Helper functions modified from:
* https://github.com/tanaikech/Resumable_Upload_For_WebApps
*/
function doUpload(fileName, e) {
return new Promise((resolve, reject) => {
showProgressMessage("Carregando: <span style='color: #00F498 ;'>" + "0%</span>");
var chunks = e.chunks;
var location = e.location;
var cnt = 0;
var end = chunks.length;
var temp = function callback(cnt) {
var e = chunks[cnt];
var xhr = new XMLHttpRequest();
xhr.open("PUT", location, true);
console.log("content range: ", e.range);
xhr.setRequestHeader('Content-Range', e.range);
xhr.send(e.data);
xhr.onloadend = function() {
var status = xhr.status;
cnt += 1;
console.log("Uploading: " + status + " (" + cnt + " / " + end + ")");
showProgressMessage("Carregando: <span style='color: #00F498 ;'>"
+ Math.floor(100 * cnt / end) + "%</span>" );
if (status == 308) {
callback(cnt);
} else if (status == 200) {
$("#progress").text("Done.");
resolve();
} else {
$("#progress").text("Error: " + xhr.response);
reject();
}
};
}(cnt);
});
}
/**
* Helper functions modified from:
* https://github.com/tanaikech/Resumable_Upload_For_WebApps
*/
function getChunkpot(chunkSize, fileSize) {
var chunkPot = {};
chunkPot.total = fileSize;
chunkPot.chunks = [];
if (fileSize > chunkSize) {
var numE = chunkSize;
var endS = function(f, n) {
var c = f % n;
if (c == 0) {
return 0;
} else {
return c;
}
}(fileSize, numE);
var repeat = Math.floor(fileSize / numE);
for (var i = 0; i <= repeat; i++) {
var startAddress = i * numE;
var c = {};
c.startByte = startAddress;
if (i < repeat) {
c.endByte = startAddress + numE - 1;
c.numByte = numE;
chunkPot.chunks.push(c);
} else if (i == repeat && endS > 0) {
c.endByte = startAddress + endS - 1;
c.numByte = endS;
chunkPot.chunks.push(c);
}
}
} else {
var chunk = {
startByte: 0,
endByte: fileSize - 1,
numByte: fileSize,
};
chunkPot.chunks.push(chunk);
}
return chunkPot;
}
</script>
</body>
</html>
It can also be viewed by accessing this worksheet
Although I'm not sure whether I could correctly understand your actual expected result, please test the following modification.
Google Apps Script side:
Please modify saveDataAsCSV of Google Apps Script as follows.
const saveDataAsCSV = (data, folderId1, folderId2 = null) => {
if (folderId2) {
DriveApp.getFolderById(folderId1).createFile(`${DriveApp.getFolderById(folderId2).getName()}.csv`, data);
} else {
DriveApp.getFolderById(folderId1).createFile("sample.csv", data);
}
}
Javascript side:
Please remove google.script.run.saveDataAsCSV(data, uploadParentFolderId); in the function submitForm.
And, please modify onFileReaderLoad of Javascript as follows.
function onFileReaderLoad(onLoadEvent) {
var fr = this;
var newFolderName = upload_folder
createOrGetFolder(newFolderName, uploadParentFolderId).then(newFolderId => {
google.script.run.saveDataAsCSV(data, uploadParentFolderId, newFolderId);
console.log("Found or created guest folder with id: ", newFolderId);
uploadFileToDriveFolder.call(fr, newFolderId).then(() => {
fr.resolve();
}, (error) => {
fr.reject(error);
});
},
(error) => {
if (error) {
showError(error.toString());
}
console.log("onFileReaderLoad Error2: ", error);
});
}
By this modification, I think that a CSV file like 01-01.csv is created to uploadParentFolderId folder.

JSPrintManager isn't detecting my installed scanner

I am trying to scan a document with the click of a button in javascript. This is my code:
HTML:
<div class="mb-3" style="width: 50%; margin: 0 auto; border: 2px solid white;">
<label for="scannerName">Select preferred scanner :</label><br>
<select name="scannerName" id="scannerName" style="text-align: center; width: 50%;"></select><br><br>
<label for="pixelMode">Select pixel mode :</label><br>
<select name="pixelMode" id="pixelMode" style="text-align: center; width: 50%;"></select><br><br>
<label for="resolution">Select resolution :</label><br>
<select name="resolution" id="resolution" style="text-align: center; width: 50%;"></select><br><br>
<label for="imageFormat">Select image format :</label><br>
<select name="imageFormat" id="imageFormat" style="text-align: center; width: 50%;"></select><br><br>
</div>
<div class="d-grid gap-*" style="position: absolute; top: 100%; left: 46%;">
<button type="button" class="btn btn-primary btn-block" onclick="doScanning()">Upload</button>
</div>
JS:
var scannerDevices = null;
var _this = this;
//JSPrintManager WebSocket settings
JSPM.JSPrintManager.auto_reconnect = true;
JSPM.JSPrintManager.start();
JSPM.JSPrintManager.WS.onStatusChanged = function () {
if (jspmWSStatus()) {
//get scanners
JSPM.JSPrintManager.getScanners().then(function (scannersList) {
scannerDevices = scannersList;
var options = '';
if(scannerDevices.length>0){
for (var i = 0; i < scannerDevices.length; i++) {
options += '<option>' + scannerDevices[i] + '</option>';
}
}
else{
var options_new='';
options_new += '<option>' + "Not applicable" + '</option>';
$('#pixelMode').html(options_new);
$('#resolution').html(options_new);
$('#imageFormat').html(options_new);
options += '<option>' + "No scanners found installed" + '</option>';
}
$('#scannerName').html(options);
});
}
};
//Check JSPM WebSocket status
function jspmWSStatus() {
if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Open)
return true;
else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Closed) {
console.warn('JSPrintManager (JSPM) is not installed or not running! Download JSPM Client App from https://neodynamic.com/downloads/jspm');
return false;
}
else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Blocked) {
alert('JSPM has blocked this website!');
return false;
}
}
//Do scanning...
function doScanning() {
if (jspmWSStatus()) {
//create ClientScanJob
var csj = new JSPM.ClientScanJob();
//scanning settings
csj.scannerName = $('#scannerName').val();
csj.pixelMode = JSPM.PixelMode[$('#pixelMode').val()];
csj.resolution = parseInt($('#resolution').val());
csj.imageFormat = JSPM.ScannerImageFormatOutput[$('#imageFormat').val()];
let _this = this;
//get output image
csj.onUpdate = (data, last) => {
if (!(data instanceof Blob)) {
console.info(data);
return;
}
var imgBlob = new Blob([data]);
if (imgBlob.size == 0) return;
var data_type = 'image/jpg';
if (csj.imageFormat == JSPM.ScannerImageFormatOutput.PNG) data_type = 'image/png';
//create html image obj from scan output
var img = URL.createObjectURL(imgBlob, { type: data_type });
//scale original image to be screen size friendly
/*var imgScale = { width: Math.round(96.0 / csj.resolution * 100.0) + "%", height: 'auto' };
$('#scanOutput').css(imgScale);
$('#scanOutput').attr("src", img);*/
}
csj.onError = function (data, is_critical) {
console.error(data);
};
//Send scan job to scanner!
csj.sendToClient().then(data => console.info(data));
}
}
I've followed each and every step mentioned in this site:
https://www.neodynamic.com/articles/How-to-scan-documents-images-from-Javascript/
But I keep getting the message "No scanners are installed" in my scannerName select tag. In fact, when I go to the JS console, I get this message:
JSPrintManager License: Objectresult: "Invalid License"[[Prototype]]:
Object...
My scanner is a Canon canoscan lide 25. It's TWAIN compatible so it should be detected. How do I fix this issue? Do I have to buy the license?

Web page text on mobile increasing in size when it receives a message from our mqtt broker

When I get a message from our mqtt broker, the text on my mobile web page increases and I have no idea why it is doing it. Please help. Look for yourself. Sorry for how messy it is; I am new to coding.
<!DOCTYPE html>
<html>
<body>
<style>
.myClass {
color: black;
background-color: white;
text-align: left;
margin: auto;
font-size: auto;
width: auto;
}
</style>
<template>
<div class="myClass"></div>
</template>
<title>Sprinkler System</title>
<p id="System" class="myClass"></p>
<p id="PumpPres" class="myClass"></p>
<p id="PumpCurrent" class="myClass"></p>
<h6><i>This is in develoupement build</i></h6>
<h3>Message<br>
<input type="text" id="InputRandom"></input> <input onclick="Random1()" type="button" value="Send Message" id="Input2"></input>
</h3>
<br>
<h4> Sprinkler System <br><input type="number" id="InputTxt" min="1" max="12"></input>
<input onclick="SS_On()" type="button" value="Turn On"></input>
<input onclick="SS_Off()" type="button" value="Turn Off" id="RandomBtn"></input>
</h4>
<p id="this" class="myClass"></p>
<input onclick="reset()" type="button" value="reset"></input>
<p id="mic"></p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script>
/*=============================================Variables================================================*/
var HomeLog = "home/irrigation/state";
var LogSS = "home/irrigation/log";
var SS_dest = "home/irrigation"; //SS == Sprinkler System
var SS_Pres = "home/irrigation/pressure";
var SS_Current = "home/irrigation/pump_current"
var Ip = "192.168.1.46"; //ip adress of the broker
var Port = Number(8083); //port of the broker
var Id = makeid(); //writes the ip
var mes; //makes mes global
var num = 0;
var Log;
/*==============================================MQTT====================================*/
client = new Paho.MQTT.Client(Ip, Port, Id);
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({
onSuccess: onConnect
});
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("Connected as " + makeid());
client.subscribe(SS_dest);
client.subscribe(LogSS);
client.subscribe(HomeLog);
client.subscribe(SS_Pres);
client.subscribe(SS_Current);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
var TimeOut;
var Object1 = responseObject.errorCode;
if (Object1 !== 0) {
console.log("ConnectionLost:" + responseObject.errorMessage);
//client = new Paho.MQTT.Client(Ip, Port, Id);
client.connect({
onSuccess: onConnect
});
TimeOut++;
}
if (TimeOut == 10) {
Object1 = 1;
}
}
// called when a message arrives
function onMessageArrived(message) {
var OnOff;
console.log("MessageArrived:" + message.payloadString);
mes = message.payloadString;
//alert(mes);
var res = mes.split(","); //holds if statement
if (res[1] == "on" || res[1] == "On") {
OnOff = "On";
} else if (res[1] == "Off" || res[1] == "Off") {
OnOff = "Off";
}
var Test1 = res.length;
if (Test1 >= 2) {
//alert(Test1);
document.getElementById("p" + res[0]).innerHTML = "Zone " + res[0] + " == " + OnOff;
}
console.log("Topic: " + message.destinationName);
Log = message.destinationName;
console.log(Log);
if (Log == "home/irrigation/state") {
document.getElementById("System").innerHTML = "Pump == " + mes;
}
if (Log == "home/irrigation/pressure") {
document.getElementById('PumpPres').innerHTML = "Presure == " + mes;
}
if (Log == "home/irrigation/pump_current") {
document.getElementById('PumpCurrent').innerHTML = "Current == " + mes;
}
if (Log != "home/irrigation/pump_current" && Log != "home/irrigation/pressure") {
document.getElementById("mic").innerHTML = document.getElementById("mic").textContent + "," + mes;
document.getElementById("mic").style.fontSize = "small";
num = num + 1;
Loop1();
}
}
/*==========================================Functions=================================*/
makeBigger();
test();
function SS_On() { //turn on the system
var elem = document.getElementById("InputTxt") //gets the input of the textbox
if (elem.value < 13 && elem.value >= 1) { //detects if the input is in a certan range
message = new Paho.MQTT.Message(elem.value + ",On"); //wrights a message
message.destinationName = SS_dest; //sets the destonation of the message
client.send(message); //sends the message to the broker
}
}
function SS_Off() { //turn off the system
var elem = document.getElementById("InputTxt") //gets the input of the textbox
if (elem.value < 13 && elem.value >= 1) { //detects if the input is in a certan range
message = new Paho.MQTT.Message(elem.value + ",Off"); //wrights a message
message.destinationName = SS_dest; //sets the destonation of the message
client.send(message); //sends the message to the broker
}
}
function makeid() { //this is made to make a randomized id
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.";
for (var i = 0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function Random1() { //made for a helloworld
var elem1 = document.getElementById("InputRandom");
message = new Paho.MQTT.Message(elem1.value); //wrights a message
message.destinationName = LogSS; //sets the destonation of the message
client.send(message); //sends the message to the broker
}
function Loop1() { //made to reset the log
if (num == 5) {
document.getElementById("mic").innerHTML = mes;
num = 0;
}
}
function reset() { //ment for the reset button
num = 0;
document.getElementById("mic").innerHTML = " ";
}
function test() { //this is made to make the p1-p12 in the HTML
for (nom = 1; nom <= 12; nom++) {
document.getElementById("this").innerHTML = document.getElementById("this").innerHTML + "<p id=p" + nom + " class=myClass>Zone " + nom + " == Off</p>";
}
}
function makeBigger() {
var txt = document.getElementById("InputTxt");
txt.style['width'] = '165px';
}
</script>
</body>
</html>
try to use a fixed font-size for your .myClass, hope helpful.

Checkers game - how to remove img or checker piece after a jump over

Just did a simple game of checkers, got the logic done of jumping or moving the checker pieces.
Now having problems on the actual logic of when a checker piece moves over or jumps over the other checker piece. How do i automatically remove or delete the checker piece that was jumped over?
Thanks so much :)
<html>
<head>
<style>
body { background-color: #D1CDDF; }
p { font-family: Verdana, Geneva, sans-serif;
font-size: 30; }
img { width: 35px;
height: 35px; }
label { font-family: "Lucida Console", Monaco, monospace;
font-size: 15; }
.focused{ border: 2px solid yellow; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
var moves = [];
function saveScore() {
// syntax: $.post(URL,data,callback);
$.post("scores.php",
{
TheFile: $("#filename").val(),
TheMessage: $("#winner").val() + "\r\n"
}
,function(dataFromtheServer) {
$("#result").html(dataFromtheServer);
});
}
function openBoard()
{
$(document).ready(function()
{
var p1Name = document.getElementById("p1name").value;
var p2Name = document.getElementById("p2name").value;
var heading = "<center><p><font color=\"red\"><b>" + p1Name + "</b></font> vs <font color=\"blue\"><b>" + p2Name + "</b></font></p></center>";
var table = $('<table width=500px cellspacing=0px cellpadding=0px border=1px ></table>');
var rc;
var picName;
var picName2;
for( y = 1; y <= 8; y++ )
{
var row = $('<tr></tr>');
for ( var x = 1; x <= 8; x++)
{
rc = y + x;
// creating the images
picName = "p" + 1 + ".png" ;
var pic1 = $('<img>').attr('src',picName);
picName2 = "p" + 2 + ".png";
var pic2 = $('<img>').attr('src',picName2);
if(rc % 2 === 0)
{
if(y === 1 || y === 2 || y === 3)
{
var col1 = $('<td align=center height=50px width=50px bgcolor=#4E9660 ></td>').attr('id',y + '-' + x);
col1.html(pic1);
row.append(col1);
}
else if(y === 6 || y === 7 || y === 8)
{
var col2 = $('<td align=center height=50px width=50px bgcolor=#4E9660 ></td>').attr('id',y + '-' + x);
col2.html(pic2);
row.append(col2);
}
else
{
var col3 = $('<td align=center height=50px width=50px bgcolor=#4E9660 ></td>').attr('id',y + '-' + x);
row.append(col3);
}
}
else
{
var col4 = $('<td align=center height=50px width=50px bgcolor=#C4C160 ></td>');
row.append(col4);
}
}
table.append(row);
}
document.getElementById("bBoard").style.visibility = "hidden";
$('#board').append(heading);
$('#board').append(table);
// setting the listener
$('td').click(function()
{
iAmtheClickListener(this.id);
});
});
}
function iAmtheClickListener(theID)
{
var r = $.inArray(theID,moves); // determine if the id is in the array
var content = $("#"+theID).html();
if( ((r < 0) && (content !== "")) || ((r<0) && (moves.length == 1)) )
{
moves.push(theID);
//change background color
changeBackground("#"+theID,"yellow");
}
else
{
moves.splice(r,1); // to remove
changeBackground("#"+theID,"#4E9660") ;
}
if (moves.length == 2)
{
var destId = moves[1] ;
var srcId = moves[0] ;
var srcImg = $("#" + srcId).html();
$("#" + destId).html(srcImg);
$("#" + srcId).html("");
moves = [] ; // remove all
changeBackground("#"+destId,"#4E9660") ;
changeBackground("#"+srcId,"#4E9660") ;
}
$('#result').html(theID);
}
function changeBackground(theIdUwant, theColor)
{
$(theIdUwant).css("background-color",theColor);
}
</script>
</head>
<body>
<center>
<p>~Checkers~</p>
<table border=1 cellpadding=25px>
<tr><td><label>Player 1: <input type=text id=p1name /></label><br/><br/>
<label>Player 2: <input type=text id=p2name /></label><br/><br/>
<button id="bBoard" onclick="openBoard();">Start Game</button><br/><br/></td>
<td><div class="b" id="board"></div></td>
<td>
<input type=hidden id=filename value="players.txt" />
<label>Register Winner: <input type=text id=winner /></label><br/><br/>
<button id="bReg" onclick="saveScore();">Submit</button><br/><br/>
<div id="result"></div>
</td>
</td></tr>
</table>
</center>
</body>
Suppose jumped piece is at board[row][col], you can assign a value of zero or empty at that particular cell after being jumped:
board[row][col] = EMPTY

Why doesn't my script work with checkboxes?

I am trying to make a little "game" and for some reason, if I try and get the checked of a checkbox, my script will flip out... sometimes it works, sometimes it just stops executing. Is there some sort of an error I missed?
<html>
<head>
<title>Untitled Document</title>
<script>
var check = "showcheck";
var number = 1234;
var lvl = 1;
var oldlvl = 1;
var multiplier = 10000;
var start = 1;
function exefunction() {
document.getElementById("boxv").focus();
if (check == "showcheck") {
document.getElementById("message").innerHTML = "What was the number?";
document.getElementById("num").style.display = "none";
document.getElementById("box").style.display = "inline";
document.getElementById("boxv").focus();
check = "checknum";
}
else if (check == "checknum") {
if (document.getElementById("boxv").value == number) {
document.getElementById("message").innerHTML = "CORRECT!";
document.getElementById("boxv").style.color = "#00DD00";
document.getElementById("boxv").value = number;
document.getElementById("level").innerHTML = "Level: " + lvl;
lvl++;
}
else if (document.getElementById("boxv").value != number) {
document.getElementById("message").innerHTML = "INCORRECT!";
document.getElementById("boxv").style.color = "#DD0000";
document.getElementById("boxv").value = number;
document.getElementById("level").innerHTML = "Level: " + lvl;
if (lvl>1) {lvl--;}
loselife();
}
check = "showmem";
}
else if (check == "showmem") {
if (lvl == oldlvl + 10) {
oldlvl = lvl;
multiplier = multiplier * 10;
document.getElementById("boxv").maxLength = multiplier.toString().length - 1;
}
else if (lvl < oldlvl) {
oldlvl = lvl - 10;
multiplier = multiplier / 10;
document.getElementById("boxv").maxLength = multiplier.toString().length - 1;
}
number = Math.floor(Math.random() * multiplier / 10 * 9) + multiplier / 10;
document.getElementById("boxv").style.color = "#000000";
document.getElementById("boxv").value = "";
document.getElementById("message").innerHTML = "Memorize this number: ";
document.getElementById("num").innerHTML = number;
document.getElementById("num").style.display = "inline";
document.getElementById("box").style.display = "none";
check = "showcheck";
}
}
function loselife(){
var life = 4;
var hearts = "♥ ";
alert(document.getElementById("lifebox").checked);
}
function submitenter() {
var keycode = window.event.keyCode;
if (keycode == 13) {
if (start === 0) {exefunction();}
else {startfunc();}
}
if (keycode < 47 || keycode > 58) {
return false;
}
}
function startfunc() {
document.getElementById("button").innerHTML = '<input name="" type="button" value="OK" onClick="exefunction()"/>';
document.getElementById("level").innerHTML = "Level: " + lvl;
document.getElementById("message").innerHTML = "Memorize this number: ";
document.getElementById("num").style.display = "inline";
document.getElementById("boxv").value = "";
document.getElementById("box").style.display = "none";
if (document.getElementById("lifecheck").checked === true) {
document.getElementById("life").innerHTML = "♥ ♥ ♥ ♥ ♥ ";
}
else if (document.getElementById("lifecheck").checked === false) {
document.getElementById("life").innerHTML = "";
}
if (document.getElementById("timercheck").checked === true) {
document.getElementById("timer").innerHTML = "3:00";
}
else if (document.getElementById("timercheck").checked === false) {
document.getElementById("timer").innerHTML = "";
}
start = 0;
}
function tests() {
alert(lfckv);
}
</script>
<style type="text/css">
#level, #life, #timer{
color: #666;
}
* {
text-align: center;
}
#num {
display: none;
}
#num {
font-size: x-large;
}
#body {
margin-top: 250px;
margin-right: auto;
margin-bottom: 100px;
margin-left: auto;
}
body {
background-color: #6FF;
}
</style></head>
<body onKeyPress="return submitenter()" >
<div id="body">
<span id="level"></span>
<table align="center">
<tr>
<td width="200" height="50" align="center" valign="middle"><span id="message">What level would you like to begin at?</span></td>
<td width="200" height="50" align="center" valign="middle"><span id="num">1234</span><span id="box"><input type="text" id="boxv" maxlength="4" value="1"/></span></td>
</tr>
</table>
<table align="center">
<tr>
<td width="200" id="life"><label><input id="lifecheck" type="checkbox" >Lives</label></td>
<td id="button"><input type="button" value="OK" onClick="startfunc()"/></td>
<td width="200" id="timer"><label><input id="timercheck" type="checkbox" >Timer</label></td>
</tr>
</table>
<input name="" type="button" onClick="tests()" value="tests()">
</div>
</body>
</html>
lifebox isnt defined in the loselife() function. Plus, also check the test() function, that alert() statement has a variable that isnt defined.
If you are using Google chrome (or any other browser that can help you debug), I would suggest you to debug through your lines of code.
I think you're better off using simple equality for checking the state of your checkboxes, because I'm pretty the outcome is not a Boolean.
So it would be something like that :
if (document.getElementById("lifecheck").checked == true) {
or simply
if (document.getElementById("lifecheck").checked) {
instead of
if (document.getElementById("lifecheck").checked === true) {
Ahah! I figured out the problem. Apparently, when I set the visibility of the checkbox to none, it also set the checkvalue to null for some reason. I had expected it to keep the checkvalue, but for some reason it does not.

Categories