I'm getting the following error in my app's script when replacing strings in a template file to generate reports.
Index (-1) value must be greater or equal to zero.
The function is listed bellow.
/**
* Search a String in the document and replaces it with the generated newString, and sets it Bold
*/
function replaceString(doc, String, newString) {
var ps = doc.getParagraphs();
for(var i=0; i<ps.length; i++) {
var p = ps[i];
var text = p.getText();
//var text = p.editAsText();
if(text.indexOf(String) >= 0) {
//look if the String is present in the current paragraph
//p.editAsText().setFontFamily(b, c, DocumentApp.FontFamily.COMIC_SANS_MS);
p.editAsText().replaceText(String, newString);
// we calculte the length of the string to modify, making sure that is trated like a string and not another ind of object.
var newStringLength = newString.toString().length;
// if a string has been replaced with a NON empty space, it sets the new string to Bold,
Logger.log([newString,newStringLength]);
if (newStringLength > 0) {
// re-populate the text variable with the updated content of the paragraph
text = p.getText();
Logger.log(text);
p.editAsText().setBold(text.indexOf(newString), text.indexOf(newString) + newStringLength - 1, true);
}
}
}
}
When it errors out
[newString,newStringLength] = [ The Rev Levels are at ZGS 003 on the electric quality standard. The part has a current change to ZGS 005!,108]
Does anyone have any suggestions?
Thanks in advance,
Michael
You are not handling the case where the string isnt there. Thus indexOf returns -1 and you use that. Also dont use reserved words like String for variable names.
I have the following code:
<DOCTYPE HTML>
<html>
<body>
<script type="text/javascript">
//Chat Encoder
//Made by Hducke aka Hunter Ducker
//VARS
var userInputA = "";
var userInputB = "";
var result = userInputB.split("");
//FUNCTIONS
var encodeMessage = function(){
var output = "";
userInputB = prompt("Type your message here:", "PLEASE TYPE YOUR MESSAGE IN LOWER CASE!");
for(var i = 0; i <= result.length; i++){
switch(result[i]){
case("a"):
result[i] = "1";
break;
case("b"):
result[i] = "2";
break;
case("c"):
result[i] = "3";
break;
}
var tempStr = "";
result[i] + tempStr;
}
return tempStr;
}
var decodeMessage = function(){
}
var promptUser = function(){
var tempBool = true;
while(tempBool){
userInputA = prompt("Type '1' to encode a message and '2' to decode a message!", "Type '1' or '2' here.");
switch(userInputA){
case("1"):
encodeMessage();
tempBool = false;
break;
case("2"):
decodeMessage();
tempBool = false;
break;
default:
alert("Try again. Please type a '1' or a '2'.");
}
}
}
var printMessage = function(){
alert(encodeMessage);
}
//LOGIC
promptUser();
printMessage();
</script>
</body>
</html>
Info: The way it is atm is it takes in the users input userInputB and parses it into separate characters. Then it sets the characters to a different character (scambles the character). Then it outputs the string to the user. My goal is to have it to where you can enter a message I love this website! and turn it into 1 2324 5654 7503947. Then another user can enter the encoded message and the decodeMessage function will decode the message and output it to the user.
First issue: It won't currently work as is.*
*EDIT: Now when I run the code after fixing the result[i].
Output I Get Now
Second issue: How can I do this (IE. Is there a better way of doing this)
Any tips can help. I'm kinda a noob at javascript. Thanks!
The first problem is with your input; result is not going to be updated when the user enters the prompt.
function encodeMessage() {
var output = '';
userInputB = prompt(...);
result = userInputB.split('');
...
}
The second problem is the encoding itself. Instead of using a giant switch, create an algorithm to perform the encoding. In your case, you have a simple 1:1 mapping of a character to a number, conveniently in the natural order.
Did you know that your computer stores those letters as numbers? 'a' is 97, 'b' is 98, etc. so you could simply subtract 96 from the character to get a=1, b=2, etc.
However, this poses a problem for your decoder once you reach 'j'. "java" is going to be turned into "101221", and if you simply perform the reverse of your encoder on that, you'll end up with "a`abba".
One option would be to return to your encoding scheme and the ASCII table. '1' is character 49; perhaps you could subtract 48 from your characters instead? 'a' would then become '1' (not much different from 1) and so on. 'j' becomes ':', and if you encode "java" you get ":1F1".
Once you're doing that, the reverse of your encoding scheme will become your decoder. Iterate over the encoded string, and add 48 instead of subtracting it.
UPDATE
I've updated the http://jsfiddle.net/ntyt4/5/ with a sample scenario of the encoding and decoding process. It should give you enough to get started.
A simpler way would be to use a dictionary with keys and their translated values. You could store this in an object literal as:
var translation = {
"a": 1,
"b": 2,
"c": 3,
"d": "A"
};
I've included a jsfiddle to show you an example. Just change the textbox value to one value to see the translation.
One thing to keep in mind though is that you will have to add every single character that needs to be translated to the object literal. For example "a" will not translate the upper case version "A" for you because it is a different character.
I don't know very well the javascript but you have three options:
Mapping the chars with two Vector
If you want to include the simple characters you need 25(a-z)+25(A-Z)+9(0-9)=59 conversion.
You can do this with an algoritm that if found a letter in the first vector for example at index "6", take the value from the corrispondent position in the second vector.
Decoding is the same way, only take from second vector and convert it in the equivalent for the first vector.
ASCII Table
The char letter '0' casted in integer is 48.
From 48-57 you have the number, in the range 65-90 you have the Upper char and in the range 97-122 you have the lower char. If you try to subtrack for example two your text is encoded in a simple system.
MD5 Algoritm
You can use/create a function that generate the md5 hash of a text, for example "encoding" in md5 is "84bea1f0fd2ce16f7e562a9f06ef03d3". If you want use an encript system for encript an area this is the better way.
I am using two text areas. Project is about online typing test. I used two text area. First textarea contains the matter to be typed in second textarea. For calculating the the net typing speed I need a javascript diff algorithm.
Javascript Diff Algorithm algo fits my all requirements..which uses this
jsdiff.js
javascript file for differencing of two strings. and
JS Diff Demo
is a demo which uses the same javascript file...You should have look of this demo. But I how can I know count correct words typed? Trouble is that the javascript file provided is not using any comments nor gives any documentation.
I'm not sure if you need much more explanation than the comment I placed above. I like the diff-highlighting your link shows, but if all you're after is counting the diffs, why does something like this not work? http://jsfiddle.net/vSySu/
var arr1 = $('#text1').val().split(' ');
var arr2 = $('#text2').val().split(' '); // split on whatever string or regex you want.
var diffs = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) {
diffs++;
}
}
alert(diffs);
You could use a combination of a lenvenshtein algorithm to find the accuracy, and some basic string manipulation to count the words that are different. This can be improved but you get the idea:
function wordAccuracy(str1, str2) {
var len = str1.length,
distance = levenshtein(str1, str2),
words1 = str1.split(' '),
words2 = str2.split(' ');
return {
accuracy: 100 - (0|(distance * 100) / len) +'%',
fail: words1.filter(function(word, idx){
return word != words2[idx];
}).length
}
}
// Example:
var str1 = 'Lorem ipsum dolor sit amet consectetur adipiscing elit';
var str2 = 'Lorme ipsmu dolor sit maet cnsectetur adipiscing elot';
console.log(wordAccuracy(str1, str2));
//^ {
// accuracy: '86%'
// fail: 5
// }
I am currently learning Javascript, and I'd like to create my own Lorem Ipsum generator.
Basically, I would have a list of the paragraphs (in javascript, or in the HTML document?).
When the user presses the Generate button, it would then output 3 random paragraphs from the list.
I've looked around on here, but can't really find anything that helps.
Thanks
You could simply have a Javascript Array and pick a random index and inject that paragraph into the DOM element. I've also updated the code to not repeat the previous random integer per your comment below.
Example (code untested)
//global to store previous random int
_oldInt = null;
var paragraphArray = ["Lorem ipsum delor...", "The great white...", "Chitty-chitty-bang-bang..."];
//update element content (e.g. `<div>` with paragraph)
document.getElementById("MyID").innerHTML = pickRandom(paragraphArray);
var pickRandom = function(paragraphArray){
//random index of paragraphArray
var randomInt = Math.floor(Math.random()*paragraphArray.length);
//ensure random integer isn't the same as last
if(randomInt == _oldInt)
pickRandom(paragraphArray);
else{
_oldInt = randomInt;
return paragraphArray[randomInt];
}
}
You can use Math.random to generate a random index from your list:
var paragraphs = [...]; # This is your list of paragraphs
function get_random_paragraph() {
var index = Math.floor(paragraphs.length * Math.random());
return paragraphs[index];
};
The expression Math.floor(MAX_VALUE * Math.random()) generates a random integer x, where 0 <= x < MAX_VALUE.
You need some paragraphs (here, a JavaScript array), a result box (here, a <div>) and a button (here, a... <button>).
When you click on the button, you want to add a paragraphs into the result.
var paragraphs = ['Lorem', 'ipsum', 'dolor', 'sit', 'amet'],
nbParagraphs = paragraphs.length
paragraph = null,
result = document.getElementById('result'),
button = document.getElementsByTagName('button')[0];
button.addEventListener('click', function() {
/*
* Math.random() return a number between 0 and 1
* parseInt() return an integer (the 10 is here to say that we are in decimal)
* parseInt(Math.random() * nbParagraphs, 10) return a number between 0 and the number of paragraphs, so we can use it to select a paragraph in the paragraphs array
*/
paragraph = paragraphs[parseInt(Math.floor(Math.random() * nbParagraphs, 10))]
result.innerHTML += '<p>' + paragraph + '</p>'
})
Here is a demo.
I want to display YouTube videos on my website, but I need to be able to add a unique id for each video that's going to be shared by users. So I put this together, and I have run into a little problem. I am trying to get the JavaScript to add a random string for the div id, but it's not working, showing the string:
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript'>
function randomString(length) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');
if (! length) {
length = Math.floor(Math.random() * chars.length);
}
var str = '';
for (var i = 0; i < length; i++) {
str += chars[Math.floor(Math.random() * chars.length)];
}
return str;
}
var div = randomString(8);
</script>
<div id='div()'>This text will be replaced</div>
<script type='text/javascript'>
jwplayer('div()').setup({
'flashplayer': 'player.swf',
'file': 'http://www.youtube.com/watch?v=4AX0bi9GXXY',
'controlbar': 'bottom',
'width': '470',
'height': '320'
});
</script>
I really like this function:
function guidGenerator() {
var S4 = function() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
From Create GUID / UUID in JavaScript?
2018 edit: I think this answer has some interesting info, but for any practical applications you should use Joe's answer instead.
A simple way to create a unique ID in JavaScript is to use the Date object:
var uniqid = Date.now();
That gives you the total milliseconds elapsed since January 1st 1970, which is a unique value every time you call that.
The problem with that value now is that you cannot use it as an element's ID, since in HTML, IDs need to start with an alphabetical character. There is also the problem that two users doing an action at the exact same time might result in the same ID. We could lessen the probability of that, and fix our alphabetical character problem, by appending a random letter before the numerical part of the ID.
var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
var uniqid = randLetter + Date.now();
This still has a chance, however slim, of colliding though. Your best bet for a unique id is to keep a running count, increment it every time, and do all that in a single place, ie, on the server.
Here is the reusable function to generate the random IDs :
function revisedRandId() {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
}
// It will not start with the any number digit so it will be supported by CSS3
I think some folks here haven't really focused on your particular question. It looks like the problem you have is in putting the random number in the page and hooking the player up to it. There are a number of ways to do that. The simplest is with a small change to your existing code like this to document.write() the result into the page. I wouldn't normally recommend document.write(), but since your code is already inline and what you were trying do already was to put the div inline, this is the simplest way to do that. At the point where you have the random number, you just use this to put it and the div into the page:
var randomId = "x" + randomString(8);
document.write('<div id="' + randomId + '">This text will be replaced</div>');
and then, you refer to that in the jwplayer set up code like this:
jwplayer(randomId).setup({
And the whole block of code would look like this:
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript'>
function randomString(length) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'.split('');
if (! length) {
length = Math.floor(Math.random() * chars.length);
}
var str = '';
for (var i = 0; i < length; i++) {
str += chars[Math.floor(Math.random() * chars.length)];
}
return str;
}
var randomId = "x" + randomString(8);
document.write('<div id="' + randomId + '">This text will be replaced</div>');
jwplayer(randomId).setup({
'flashplayer': 'player.swf',
'file': 'http://www.youtube.com/watch?v=4AX0bi9GXXY',
'controlbar': 'bottom',
'width': '470',
'height': '320'
});
</script>
Another way to do it
I might add here at the end that generating a truly random number just to create a unique div ID is way overkill. You don't need a random number. You just need an ID that won't otherwise exist in the page. Frameworks like YUI have such a function and all they do is have a global variable that gets incremented each time the function is called and then combine that with a unique base string. It can look something like this:
var generateID = (function() {
var globalIdCounter = 0;
return function(baseStr) {
return(baseStr + globalIdCounter++);
}
})();
And, then in practical use, you would do something like this:
var randomId = generateID("myMovieContainer"); // "myMovieContainer1"
document.write('<div id="' + randomId + '">This text will be replaced</div>');
jwplayer(randomId).setup({
i like this simple one:
function randstr(prefix)
{
return Math.random().toString(36).replace('0.',prefix || '');
}
since id should (though not must) start with a letter, i'd use it like this:
let div_id = randstr('youtube_div_');
some example values:
youtube_div_4vvbgs01076
youtube_div_1rofi36hslx
youtube_div_i62wtpptnpo
youtube_div_rl4fc05xahs
youtube_div_jb9bu85go7
youtube_div_etmk8u7a3r9
youtube_div_7jrzty7x4ft
youtube_div_f41t3hxrxy
youtube_div_8822fmp5sc8
youtube_div_bv3a3flv425
I also needed a random id, I went with using base64 encoding:
btoa(Math.random()).substring(0,12)
Pick however many characters you want, the result is usually at least 24 characters.
Based on HTML 4, the id should start from letter:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
So, one of the solutions could be (alphanumeric):
var length = 9;
var prefix = 'my-awesome-prefix-'; // To be 100% sure id starts with letter
// Convert it to base 36 (numbers + letters), and grab the first 9 characters
// after the decimal.
var id = prefix + Math.random().toString(36).substr(2, length);
Another solution - generate string with letters only:
var length = 9;
var id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, length);
Or you could use Cripto since it's already built in(except in IE11, I swear these guys havent updated in years!)
https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples
var id = new Uint32Array(10);
window.crypto.getRandomValues(id);
I also found this:
https://gist.github.com/6174/6062387#gistcomment-3255605
let length = 32;
let id = crypto.randomBytes(length).toString("base64");
There's a lot of ways to do this, but for most people, there's no reason to reinvent the wheel :)
A edited version of #jfriend000 version:
/**
* Generates a random string
*
* #param int length_
* #return string
*/
function randomString(length_) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'.split('');
if (typeof length_ !== "number") {
length_ = Math.floor(Math.random() * chars.length_);
}
var str = '';
for (var i = 0; i < length_; i++) {
str += chars[Math.floor(Math.random() * chars.length)];
}
return str;
}
For generating random ids, you can also use the standard crypto API with its randomUUID() function which is available in node.js (>=v16.7.0) and all relevant browsers except Safari:
const uuid = crypto.randomUUID()
console.log(uuid)
// prints e.g. "7f3f4512-fcf9-45fe-b726-512bba403426"
I would suggest that you start with some sort of placeholder, you may have this already, but its somewhere to append the div.
<div id="placeholder"></div>
Now, the idea is to dynamically create a new div, with your random id:
var rndId = randomString(8);
var div = document.createElement('div');
div.id = rndId
div.innerHTML = "Whatever you want the content of your div to be";
this can be apended to your placeholder as follows:
document.getElementById('placeholder').appendChild(div);
You can then use that in your jwplayer code:
jwplayer(rndId).setup(...);
Live example: http://jsfiddle.net/pNYZp/
Sidenote: Im pretty sure id's must start with an alpha character (ie, no numbers) - you might want to change your implementation of randomstring to enforce this rule. (ref)
May I an share an intuitive way to generate a randomID ?
const getRandomID = (length: number) => {
let text = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
Here is an easy one liner:
const generateUniqueID = (idLength) => [...Array(idLength).keys()].map((elem)=>Math.random().toString(36).substr(2, 1)).join("")
Where all you do is enter the idLength and it will return a unique id of that length.
generateUniqueID(23)
>>>'s3y9uebzuo73ih79g0s9p2q' // Id of length 23
First. Assign an id to your div. Like this:
<div id="uniqueid">This text will be replaced</div>
After that, add inside your <script> tag following code:
Document.getElementById("uniqueid").id = randomString(8);
window.btoa(String.fromCharCode(...window.crypto.getRandomValues(new Uint8Array(5))))
Using characters except ASCII letters, digits, '_', '-' and '.' may cause compatibility problems, as they weren't allowed in HTML 4. Though this restriction has been lifted in HTML5, an ID should start with a letter for compatibility.
function id(prefix = '', length = 7) {
let result = prefix;
for(let i = 0; i < length; i++) {
const random = Math.random();
result += String.fromCharCode(Math.floor(random * 26) + (random < .5 ? 65 : 97));
}
return result;
}
a random number between 0 and 25 is generated then added to either 65 or 97. When added to 65 it will give you an ascii code for a capital letter and when added to 97, an ascii code for a small letter.
Just use built-int crypto.randomUUID() which is supportted by all major browsers:
let uuid = crypto.randomUUID();
console.log(uuid);