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.
Related
I'm having one of those days where I can't put into words what I'm trying to find. So, forgive me if this question has been asked before, if it has, I simply cannot find it.
If I have ten different lots of text, how can I randomly select one of them with Javascript, and display it.
The closest I've got is this:
var textArray = [
'Hello Fred',
'Hello Jimmy',
'Hello Terry'
];
var randomNumber = Math.floor(Math.random() * textArray.length);
audioElement.setAttribute('src', textArray[randomNumber]);
<p id="text-here">This is where I want the text to go</p>
I'm pretty sure this isn't close to what I need though.
I've tested it and it works just fine. Just enclose your array string values in double quotes and everything will work as you expected.
Here it is just setting the innerHTML value of p tag which is selected by id randomNumber and then set it with random text value of your array.
getElementById: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
innerHTML: https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
var textArray = [
"Hello I'm Fred1",
"Hello I'm Jimmy1",
"Hello I'm Terry1",
"Hello I'm Fred2",
"Hello I'm Jimmy2",
"Hello I'm Terry2",
"Hello I'm Fred3",
"Hello I'm Jimmy3",
"Hello I'm Terry3"
];
var randomNumber = Math.floor(Math.random() * textArray.length);
document.getElementById("randomNumber").innerHTML = textArray[randomNumber];
<p id="randomNumber"> </p>
Create a function to create random number
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
Call the function to get a random number which will act as the array index
var index = getRandomInt(9)
Now considering you have array as 'textArray' then you can write
var text = textArray[index]
Now to update the value in paragraph
document.getElementById("text-here").innerHTML=text;
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.
This probably is a very easy solution, but browsing other questions and the internet did not help me any further.
I made a javascript function which will give me a random value from the array with its according points:
function random_card(){
var rand = Math.floor(Math.random()*cards.length);
var html = "card: "+cards[rand][0]+"<br/>points: "+cards[rand][1]+"<br/><br/>";
document.getElementById("Player").innerHTML += html;
var punten = cards[rand][1];
document.getElementById("Points").innerHTML += punten;
}
I've added a += punten so i can see that it works correctly. It shows me all the point in the div with the id Points.
But what i wanted to do is count it all together so if i were to draw a 4, King and a 10 it should show 24 instead of 41010.
Thanks in advance! And if you're missing any information please let me know
Currently you are just adding strings together, which concatenate (join together) hence why you end up with 41010. You need to grab the current innerHTML (total) and use parseInt() to convert from a string to a number, then add your new cards that have been chosen, then assign this new value to the innerHTML of your element.
Try the following
function random_card(){
var rand = Math.floor(Math.random()*cards.length);
var html = "card: "+cards[rand][0]+"<br/>points: "+cards[rand][1]+"<br/><br/>";
document.getElementById("Player").innerHTML += html;
var punten = cards[rand][1];
var curPoints = parseInt(document.getElementById("Points").innerHTML, 10) || 0;
var total = curPoints + parseInt(punten, 10);
document.getElementById("Points").innerHTML = total;
}
More info on parseInt() here
EDIT
I've added this line -
var curPoints = parseInt(document.getElementById("Points").innerHTML, 10) || 0;
Which will try and convert the innerHTML of the "Points" div, but if it is empty (an empty string converts to false) then curPoints will be equal to 0. This should fix the issue of the div being blank at the start.
innerHTML is a string and JavaScript uses + for both string concatenation as numeric addition.
var pointsInHtml = parseInt(document.getElementById("Points").innerHTML, 10);
pointsInHtml += punten;
document.getElementById("Points").innerHTML = punten;
The second parameter 10 of the parseInt method is usually a good idea to keep there to avoid the function to parse it as an octal.
It might be easier to keep a points variable and only at the end put it in the #Points container, that would make the parseInt no longer necessary
innerHTML will be a string, so you need to convert it into an integer prior to adding the card value :)
function random_card(){
var rand = Math.floor(Math.random()*cards.length);
var html = "card: "+cards[rand][0]+"<br/>points: "+cards[rand][1]+"<br/><br/>";
document.getElementById("Player").innerHTML += html;
var punten = cards[rand][1],
curPunten = parseInt(document.getElementById('Points').innerHTML);
document.getElementById("Points").innerHTML = curPunten + punten;
}
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);
What I would like is to count the number of lines in a textarea, e.g:
line 1
line 2
line 3
line 4
should count up to 4 lines. Basically pressing enter once would transfer you to the next line
The following code isn't working:
var text = $("#myTextArea").val();
var lines = text.split("\r");
var count = lines.length;
console.log(count);
It always gives '1' no matter how many lines.
The problem with using "\n" or "\r" is it only counts the number of returns, if you have a line that is long it could wrap and then it wouldn't be counted as a new line. This is an alternative way to get the number of lines - so it may not be the best way.
Edit (thanks alex):
Script
$(document).ready(function(){
var lht = parseInt($('textarea').css('lineHeight'),10);
var lines = $('textarea').attr('scrollHeight') / lht;
console.log(lines);
})
Update: There is a much more thorough answer here: https://stackoverflow.com/a/1761203/145346
If you are just wanting to test hard line returns, this will work cross platform:
var text = $("#myTextArea").val();
var lines = text.split(/\r|\r\n|\n/);
var count = lines.length;
console.log(count); // Outputs 4
I have implemented the lines and lineCount methods as String prototypes:
String.prototype.lines = function() { return this.split(/\r*\n/); }
String.prototype.lineCount = function() { return this.lines().length; }
Apparently the split method will not count a carriage return and/or newline character at the end of the string (or the innerText property of a textarea) in IE9, but it will count it in Chrome 22, yielding different results.
So far I have accomodated for this by subtracting 1 from the line count when the browser is other than Internet Explorer:
String.prototype.lineCount = function() { return this.lines().length - navigator.userAgent.indexOf("MSIE") != -1); }
Hopefully someone has a better RegExp or another workaround.
user \n instead of \r
var text = $("#myTextArea").val();
var lines = text.split("\n");
var count = lines.length;
console.log(count);
However this is working if you need use it because it respond to your problem
let text = document.getElementById("myTextarea").value;
let lines = text.split(/\r|\r\n|\n/);
let count = lines.length;
console.log(count);
What about splitting on "\n" instead?
It will also be a problem where one line wrapped to 2 lines in the textarea.
To do it accurately like this, you could use a fixed height font and measure pixels. This could be problematic though.
This function counts the number of lines which have text in a textarea:
function countLine(element) {
var text = $(element).val();
var lines = text.split("\n");
var count = 0;
for (var i = 0; i < lines.length-1; i++) {
if (lines[i].trim()!="" && lines[i].trim()!=null) {
count += 1;
}
}
return count;
}
Counting the newlines is not a reliable way for finding the number of lines, since long text could simply break and still only count as a single line.
What you want to do, is find out the scrollHeight of the textarea and divide it by the height of a single line.
This is answered in detail here:
https://stackoverflow.com/a/1761203/9863305
I've used the original answer of Mottie but some functions were changed in the JQuery API. Here is the working function for the current API v3.1.0:
var lht = parseInt($('#textarea').css('lineHeight'),10);
var lines = $('#textarea').prop('scrollHeight') / lht;
console.log(lines);
All tumbs up for Mottie's answer!
This will aim to consider lines with both hard and soft returns:
//determine what the fontsize will be
let fontsize = 12;
//get number of characters that can fit in a row
let charsperrow = textarea.clientWidth / fontsize;
//get any hard returns
let hardreturns = textarea.textContent.split(/\r|\r\n|\n/);
let rows = hardreturns.length;
//loop through returns and calculate soft returns
for(let i = 0,len = rows; i < len; i++){
let line = hardreturns[i];
let softreturns = Math.round(line.length / charsperrow);
//if softreturns is greater than 0, minus by 1 (hard return already counted)
softreturns = Math.round(softreturns > 0 ? (softreturns - 1) : 0);
rows += softreturns;
}
console.log(Math.round(rows));
The normal newline character is "\n". The convention on some systems is to also have "\r" beforehand, so on these systems "\r\n" is often found to mean a new line. In a browser, unless the user intentionally enters a "\r" by copying it from somewhere else, the newline will probably be expressed as just "\n". In either case splitting by "\n" will count the number of lines.
<html>
<head>
<script>
function countLines(theArea){
var theLines = theArea.value.replace((new RegExp(".{"+theArea.cols+"}","g")),"\n").split("\n");
if(theLines[theLines.length-1]=="") theLines.length--;
theArea.form.lineCount.value = theLines.length;
}
</script>
</head>
<body>
<form>
<textarea name="myText" onKeyUp="countLines(this)" cols="10" rows="10">
</textarea>
<br>
Lines:
<input type=text name="lineCount" size="2" value="0">
</form>
</body>
</html>
Your ans can be done in very simple way.
var text = $("#myTextArea").val();
// will remove the blank lines from the text-area
text = text.replace(/^\s*[\r\n]/gm, "");
//It will split when new lines enter
var lines = text.split(/\r|\r\n|\n/);
var count = lines.length; //now you can count thses lines.
console.log(count);
This code for exact lines filled in the textarea.
and will work for sure.
Instead of textarea you could use a div with the attribute contenteditable="true". On a div with this attribute you can write anything, just like in a textarea, but any new line (except the first) is automatically wrapped inside a div. You can use jQuery or JS to count the div's and add +1, which is the first line.
It's a no brainer, i would use this instead of textarea with every occasion. It has several advantages. It auto resizes, you can easily count blank lines, you can customize every div or add spans with colors or font sizes or anything, you can use any line-height and any font-size, you can add rich text features and more, it's better for SEO and more. Here is a working example with jQuery:
$("#Editor").on("keyup mouseup", function(){
blankSpace = $(this).find("br").length; //count blank lines
urlCounter = $(this).find("div").length + 1 - blankSpace;
$(".lineCounter").text("Number of links: "+ urlCounter);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Editor" contenteditable="true" style="color:aqua;width: 100%;height: 100%;background: blue;"></div>
<div class="lineCounter" style="position: absolute;bottom: 0;z-index: 999;left: 0;"></div>
Try calling this function every time you change its value.
textArea.addEventListener('input', function() {
setDynamicHeight();
});
function setDynamicHeight() {
textArea.style.height = 0; // set the height to 0 in case of it has to be shrinked
textArea.style.height = textArea.scrollHeight + 'px'; // set the dynamic height
}
Each line break is defined by '\n'. The goal is to count them. For this, we will have to iterate on this with a loop on each character. See the example below
let count = 0
const a = document.querySelector('textarea')
for (let i = 0; i < a.value.length; i++) {
if (a.value[i] == '\n') {
count++
}
}
console.log(count)
In this live demonstration we can see a concrete case with 3 sentences :
const textareaLineCount = () => {
let count = 0
const a = document.querySelector('textarea')
for (let i = 0; i < a.value.length; i++) {
if (a.value[i] == '\n') {
count++
}
}
return count
}
const displayTotalTextareaLine = (total) => {
document.querySelector('p').innerText = total
}
document.querySelector('button').addEventListener('click', () => {
const total = textareaLineCount()
displayTotalTextareaLine(total)
})
<textarea>
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
</textarea>
<button>count</button>
<p></p>
⚠️ It's possible that the last phase is not a line break, so I advise you to add 1 to the total result