How can I store the returned result into a variable without it being changed? I basically want the function to be only called once and be stored in the variable.
Right now the var word changes its value each time I press the button. I want it to get the retired value from the read() function and keep the value the same for validation
Here is my code:
function read() {
// var result gets a random line from a file
var lines = result.split(", ");
var randLineNum = Math.floor(Math.random() * lines.length);
return lines[randLineNum];
}
function Check(strParam){
var guessWord = strParam;
var word = read();
if(guessWord != ""){
if(guessWord !== word){
console.log(word); // I am checking here for the word and it keeps changing
}
}
}
$('#button').on('click', function() {
Check($('#txtbox').val());
});
Try
function read() {
// var result gets a random line from a file
var lines = result.split(", ");
var randLineNum = Math.floor(Math.random() * lines.length);
return lines[randLineNum];
}
var word = read();
function Check(strParam){
var guessWord = strParam;
if(guessWord != ""){
if(guessWord !== word){
// I am checking here for the word and it keeps changing
console.log(word);
}
}
}
$('#button').on('click', function() {
Check($('#txtbox').val());
});
How about this:
var lines = result.split(", ");
var randLineNum = Math.floor(Math.random() * lines.length);
var word = lines[randLineNum];
function Check(strParam){
var guessWord = strParam;
if(guessWord != ""){
if(guessWord !== word){
console.log(word); // I am checking here for the word and it keeps changing
}
}
}
$('#button').on('click', function() {
Check($('#txtbox').val());
});
Evertime you click the Button , the OnClick Function calls read which does what its exactly supposed to do . Choose a random line from the file . You need to cache the result before checking it .
function read() {
// var result gets a random line from a file
var lines = result.split(", ");
var randLineNum = Math.floor(Math.random() * lines.length);
return lines[randLineNum];
}
var word = read();
function Check(strParam){
var guessWord = strParam;
//var word = read();
if(guessWord != ""){
if(guessWord !== word){
console.log(word);
}
}
}
$('#button').on('click', function() {
Check($('#txtbox').val());
});
Related
I started writing this piece of code for InDesign to underline all letters except from the one with descendants, and added a dialog window to chose stroke and offset of the line.
Now I have two problems:
the program underlines all letters
the stroke and offset won't change
I'm a beginner in Javascript and it's the first time coding for InDesign. Does someone have a clue? Thank you!
// UNDERLINE ALL BUT NO DESCENDANTS
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if (app.documents.length != 0){
try {
// Run script with single undo if supported
if (parseFloat(app.version) < 6) {
main();
} else {
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Expand State Abbreviations");
}
// Global error reporting
} catch ( error ) {
alert( error + " (Line " + error.line + " in file " + error.fileName + ")");
}
}else{
alert("Open a document first before running this script.");
}
///MAIN FUNCTION
function main(){
if(app.selection.length != 0){
myDisplayDialog();
}
}
//INTERFACE
function myDisplayDialog(){
//declare variables
//general
var myDoc = app.activeDocument;
var mS = myDoc.selection;
// dialog
var myDialog = app.dialogs.add({name:"Underliner"});
var myLabelWidth = 70;
with(myDialog.dialogColumns.add()){
with(borderPanels.add()){
with(dialogColumns.add()){
with(dialogRows.add()){
staticTexts.add({staticLabel:"Stroke:", minWidth:myLabelWidth});
staticTexts.add({staticLabel:"Offset:", minWidth:myLabelWidth});
}
}
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:1, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue: 15, editUnits:MeasurementUnits.points});
}
}
}
var myResult = myDialog.show();
if(myResult == true){
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS,myStroke,myOffset);
}
else{
myDialog.destroy();
alert("Invalid page range.");
}
}
//REAL FUNCTION
function underline(charList,stroke, offset){
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'];
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
//console.log(typeof myText);
if (includes(myChar, doNotUnderline) == false)
{
myChar.underline = true;
myChar.underlineWeight == stroke;
myChar.underlineOffset == offset;
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
//function to know if char is in array
function includes(elemento,array)
{
var len = array.length;
for(var i=0; i<len ;i++)
{
if(array[i]==elemento){return true;}
}
return false;
}
Try these changes in the function underline():
//REAL FUNCTION
function underline(words,stroke, offset) { // <------ here 'words' instead of 'charList'
var charList = words[0].characters; // <------ here get 'characters' of the 'words'
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'].join(); // <------- here '.join()'
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
// if (includes(myChar, doNotUnderline) == false) // <----- no need
if (doNotUnderline.indexOf(myChar.contents) < 0) // <------ 'indexOf()' instead of 'includes()'
{
myChar.underline = true;
myChar.underlineWeight = stroke; // <------- here '=' instead of '=='
myChar.underlineOffset = offset; // <------- here '=' instead of '=='
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
Probably there can be another improvements as well. It's need additional researches. But if you change these lines it should work to a degree.
And there is one little thing that improves user experience greatly: to keep last used values in the input fields. It can be done pretty easy, let me know it you need it.
Update
Here is the way I'm using to store and restore any preferences of my scripts.
Add somewhere at the start of your script these lines:
// get preferences
var PREFS = { stroke: 1, offset: 15 }; // set default prefs
var PREFS_FILE = File(Folder.temp + '/underline_prefs.json'); // the file with preferences
if (PREFS_FILE.exists) PREFS = $.evalFile(PREFS_FILE); // get the prefs from the file
Now you can use the global values PREFS.stroke and PREFS.offset anywhere you want. In your case they go here:
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:PREFS.stroke, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue:PREFS.offset, editUnits:MeasurementUnits.points});
}
This way script will get the stroke and weight from the file underline_prefs.json that will be stored in the standard temporary folder of current user.
Final step is to save the values back into the file after the script got them from the dialog window.
I'd put this piece of code here:
if (myResult == true) {
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS, myStroke, myOffset);
// save preferences here
PREFS.stroke = myStroke;
PREFS.offset = myOffset;
PREFS_FILE.open('w');
PREFS_FILE.write(PREFS.toSource());
PREFS_FILE.close();
} else {
myDialog.destroy();
alert("Invalid page range.");
}
Voilá. Now don't need to type the values every time they differ from default ones.
I wrote the code below to set the first letter to upper case and set the data in CKEditor. The first letter is converting fine, but afterward, the cursor focus is set before the first letter. How can I set the cursor after the character?
CKEDITOR.on('instanceCreated', function (e) {
e.editor.on('contentDom', function () {
e.editor.document.on('keyup', function (event) {
var data = CKEDITOR.instances.editor1.getData();
var str = $(data).text();
var n = str.length;
if (str != null && n == 1) {
CKEDITOR.instances['editor1'].setData(titleCase(str))
function titleCase(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
}
});
});
});
this code is work for you :
$(document).ready(function() {
CKEDITOR.on('instanceReady', function(ev) {
ev.editor.focus();
var s = ev.editor.getSelection(); // getting selection
var selected_ranges = s.getRanges(); // getting ranges
var node = selected_ranges[0].startContainer; // selecting the starting node
var parents = node.getParents(true);
node = parents[parents.length - 2].getFirst();
while (true) {
var x = node.getNext();
if (x == null) {
break;
}
node = x;
}
s.selectElement(node);
selected_ranges = s.getRanges();
selected_ranges[0].collapse(false); // false collapses the range to the end of the selected node, true before the node.
s.selectRanges(selected_ranges); // putting the current selection there
});
});
I am a beginner at js and have a project due by the end of day. I have to display an array with temps added and have set up an object to hold this array. My problem is that the message won't display and the for statement doesn't increment. When passed through both the var i and count come back undefined. I know there is a lot missing from this code but at this point I have tried to stream line it so that I can debug this issue. The date I will deal with later.
Here is my code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
Here is my new code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
There are some big issues with your code:
You should never compare anything to NaN directly. The correct comparison should be:
if (isNaN(lowTemp)) {
You're using curly braces when not needed. You should remove both curly braces:
{window.location.href = "temps.html";}
The function parseFloat expects only one parameter: the string to be converted. You're probably confusing it to parseInt which expects both the string and the radix of the conversion.
You're using the temp's property value, but you have never setted it, so, the condition where you check if it exists will always return false, and the push method that you want to debug will never be called, since it's inside that if statement.
Finally, you're closing a li tag at the end, but you have never opened it. You should probably be closing the ol tag you have opened in the begining.
The rest of your code seems pretty OK for me.
Talking about debugging, you should read the Google Chrome's Debugging Javascript Tutorial.
I've been struggling for the past day trying to solve this one.
I'm trying to get some funky text effects going, basically a glorified string creation.
It writes a line a bit like a billboard and to do it I've used setTimeout.
Thing is I would like to put it in a function so I can reuse it and call it multiple times on different elements.
The problem is that I then need to update the text maybe halfway to a new text.
To do so I clear the timeout, but unless the timer variable is outside the scope it doesn't clear.
I can't really have it outside the function because of practicality;
I'm not sure how many times it is going to be called and it just feels wrong to declare 20 time variables outside the function.
Here's the code working CORRECTLY on one item
(click multiple times to interrupt and restart)
var t;
function writeStats(str,dest) {
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
str = str.split('');
var types = [],
letters = [];
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
clearTimeout(t);
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
//el.text(strCopy.join(""));
el = strCopy.join("");
//console.log(el);
$('.'+dest).text(el);
t = setTimeout(function(){
shuffle(start+1);
},500/options.fps);
})(-options.step);
}
$(document).ready(function(){
$(document).click(function(){
writeStats('this sentence is a great one','t1');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
and a Fiddle script: https://jsfiddle.net/phjzfw15/
If I bring the t variable inside the function like so it doesn't work as before:
function writeStats(str,dest) {
var t;
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
str = str.split('');
var types = [],
letters = [];
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
clearTimeout(t);
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
//el.text(strCopy.join(""));
el = strCopy.join("");
//console.log(el);
$('.'+dest).text(el);
t = setTimeout(function(){
shuffle(start+1);
},500/options.fps);
})(-options.step);
}
$(document).ready(function(){
$(document).click(function(){
writeStats('this sentence is a great one','t1');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
... and the relative fiddle if you prefer it there: https://jsfiddle.net/phjzfw15/1/
If you run the snippet you'll see it doesn't work properly anymore.
Clicking repeatedly will show you that the old sentence is still there and it gets overwritten.
How can I get this working clearing the timeout correctly inside the function?
I thought the "t" variable was local to each function and a separate instance of it would have been created?
Thanks!
Ok, here's a dumbed down version (maybe the amount of code was too much before)
CORRECT VERSION
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
var timer;
function writeStats(str, dest) {
$('.'+dest).text('');
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
$(document).ready(function(){
var index = 0;
$(document).click(function(){
writeStats(starr[index],'t1');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
Correct version
<div class="t1">Click anywhere multiple times</div>
NOT WORKING VERSION
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
function writeStats(str, dest) {
var timer;
$('.'+dest).text('');
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
$(document).ready(function(){
var index = 0;
$(document).click(function(){
writeStats(starr[index],'t1');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
NOT WORKING VERSION (please note I just moved the timer declaration inside the function)
<div class="t1">Click anywhere multiple times fast</div>
Finally made it to work.
For posterities...
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
var writer = function(){
var timer;
this.writeStat = function(str,dest) {
var options = { "step" : 8, "fps" : 25, "text" : "" }
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
}
$(document).ready(function(){
var index = 0;
w = new writer;
y = new writer;
$(document).click(function(){
w.writeStat(starr[index],'t1');
y.writeStat(starr[index],'t2');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
I want to retrieve a random row from the table of meals, how is the way to do that?
My code :
var transaction = db.transaction(["meals"], "readonly");
var store = transaction.objectStore("meals");
var index = store.index("time"); // to search in the field time type
range = IDBKeyRange.only(3); // 3 means it is a lunch
index.openCursor(range).onsuccess = function (e) {
var dt = event.target.result;
if (dt) {
var s = dt.value['fno1'];
}
};
Instead of advancing one row at a time until you hit your random result, what about using advance(n) to jump up a random set? Here is a complete example. It assumes two buttons to seed data and to call the random selection. I'm going to be blogging this Monday.
/* global $,document,indexedDB,console */
/**
* Returns a random integer between min and max
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
$(document).ready(function() {
var db;
var openRequest = indexedDB.open("randomidb",1);
openRequest.onupgradeneeded = function(e) {
var thisDB = e.target.result;
console.log("running onupgradeneeded");
if(!thisDB.objectStoreNames.contains("notes")) {
thisDB.createObjectStore("notes", {autoIncrement:true});
}
};
openRequest.onsuccess = function(e) {
console.log("running onsuccess");
db = e.target.result;
$("#seedButton").on("click", function() {
var store = db.transaction(["notes"],"readwrite").objectStore("notes");
for(var i=0; i<10; i++) {
var note = {
title:"Just a random note: "+getRandomInt(1,99999),
created:new Date()
};
var request = store.add(note);
request.onerror = function(e) {
console.log("Error",e.target.error.name);
//some type of error handler
};
request.onsuccess = function(e) {
console.log("Woot! Did it");
};
}
});
$("#randomButton").on("click", function() {
//success handler, could be passed in
var done = function(ob) {
console.log("Random result",ob);
};
//ok, first get the count
var store = db.transaction(["notes"],"readonly").objectStore("notes");
store.count().onsuccess = function(event) {
var total = event.target.result;
var needRandom = true;
console.log("ok, total is "+total);
store.openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(needRandom) {
var advance = getRandomInt(0, total-1);
console.log("going up "+advance);
if(advance > 0) {
needRandom = false;
cursor.advance(advance);
} else {
done(cursor);
}
} else {
done(cursor);
}
};
};
});
};
});
OK, I have developed this solution and it works just perfect to retrieve random row from table:
var transaction = db.transaction(["meals"], "readonly");
var store = transaction.objectStore("meals"); // name of table
var index = store.index("time"); // time is name of field and it is a number
range = IDBKeyRange.only(2); // query when time = 2
var y = 1;
var z = true;
var x = 0; // it will equal the random number
index.openCursor(range).onsuccess = function (e) {
var dt = event.target.result;
if (z) {
x = RandInt(1, dt.key); // get random number between 1 and count of rows
z = false; // to only make the above line one time only
}
if (dt) {
if (x == y) {
var s = dt.value['fno1'];
}
else
{ y += 1; dt.continue();}
}
};
Function to get the random number between two values :
function RandInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}