struggling with creating asterisks in Javascript - javascript

I've been struggling with this for some time now. What I wanted to create is to output a triangle of asterisks based on user's input. Let say user entered size 5, it would look something like this:
*
**
***
****
*****
My HTML looks like:
<p>
Size: <input type="text" id="size">
<input type="button" value="Draw" onclick="draw()">
</p>
<pre id="output">
</pre>
In my Javascript, I have:
function draw()
{
var size = customJS.get ( "size" ); //I have a custom library where it get the Id from HTML
var theTriangle = makeTriangle( size.value ); //sending in the size
customJS.set ("output", theTriangle); //will set theTriangle to display to "output" in HTML
}
function makeTriangle( theSize )
{
var allLines = ""; // an empty string to hold the entire triangle
for ( var i = 0; i <= size; i++) // this loop size times
{
var oneLine = createLine ( i <= size ); // amount of asterisks for this line
allLines += oneLine;
}
return allLines;
}
function createLine ( length )
{
var aLine = ""; // an empty string to hold the contents of this one line
for ( var j = 0; j <= i; j++ ) //this loop length times
{
aLine += '*';
}
return aLine + "<br>";
}
anyone have any tip on how I go about this? thank you so much!

Newlines in HTML normally display as spaces, but you want them to show as newlines. The pre tag makes newlines actually appear as new lines, so wrap the output in a pre tag:
customJS.set ("output", "<pre>" + theTriangle + "</pre>");
Also, you're calling createLine like this:
var oneLine = createLine ( i <= size );
i <= size yields a boolean (true or false) rather than a number. You probably mean to just pass it i:
var oneLine = createLine ( i );
Additionally, you're setting size like this:
var size = customJS.get = ( "size" );
You probably want to drop the second equals, since as is, it sets the variable size to the string "size".
And finally, you've got a few variables wrong: in makeTriangle, you're looping size times, but size is undefined; you probably meant theSize. In createLine, you're looping i times, but i is undefined; you probably meant length.
With all that, it works.

There were several bugs in your code. For example using theSize instead size as parameter in the function makeTriangle(), using i instead of length in the createLine() function in the for loop condition.
Another one was:
use
return aLine + "<br/>";
instead of
return aLine + "\n";
The working solution for your code can be found in this jsFiddle: http://jsfiddle.net/uwe_guenther/wavDH/
And below is a copy of the fiddle:
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>Size:
<input type="text" id="sizeTextField">
<input id='drawButton' type="button" value="Draw">
<div id='output'></div>
</p>
<script src='main.js'></script>
</body>
</html>
main.js
(function (document) {
var drawButton = document.getElementById('drawButton'),
sizeTextField = document.getElementById('sizeTextField'),
output = document.getElementById('output');
function makeTriangle(size) {
var allLines = '';
for (var i = 0; i <= size; i++) {
var oneLine = createLine(i); // amount of asterisks for this line
allLines += oneLine;
}
return allLines;
}
function createLine(length) {
var aLine = '';
for (var j = 0; j <= length; j++) {
aLine += '*';
}
return aLine + "<br/>";
}
drawButton.onclick = function () {
output.innerHTML = makeTriangle(sizeTextField.value);
};
})(document);

You can leverage some JavaScript tricks to make the code a bit more terse:
<div style="text-align: center">
<label>Size:
<input type="text" id="size" value="5">
</label> <pre id='output'></pre>
</div>
<script>
var size = document.getElementById('size'),
output = document.getElementById('output');
function update() {
var width = +size.value, // Coerce to integer.
upsideDown = width < 0, // Check if negative.
width = Math.abs(width), // Ensure positive.
treeArray = Array(width).join('0').split('0') // Create an array of 0s "width" long.
.map(function(zero, level) { // Visit each one, giving us the chance to change it.
return Array(2 + level).join('*'); // Create a string of *s.
});
upsideDown && treeArray.reverse(); // If width was negative, stand the tree on its head.
output.innerHTML = treeArray.join('\n'); // Join it all together, and output it!
}
size.onkeyup = update;
update();
size.focus();
</script>
http://jsfiddle.net/mhtKY/4/

Related

The sum cannot show although i click on the button

What I want is, after the user enters the number of subjects, the system will show the number of input box according to the number of subjects entered, then when the user clicks on the button, it should show the sum. I tried many ways, but I failed to show the sum, anyone knows what is the mistake I made?
Below is my code:
function select() {
var x = parseInt(document.getElementById('1').value);
if (document.getElementById('1').value == "") {
alert("Please fill up number of subject");
} else if (isNaN(x) == true) {
alert("Please fill up number of subject with number");
} else {
var subject = parseInt(document.getElementById('1').value);
var sum = 0;
for (var num = 1; num <= subject; num++) {
document.write("Enter the mark for subject " + num + " : ");
var value = parseFloat(document.write("<input/><br>"));
sum += value;
}
var calc = document.write("<button>Next</button><br>");
calc.onclick = function() {
next()
};
function next() {
document.write("Total marks: " + sum + "%");
}
}
}
<html>
<body>
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</body>
</html>
That's how I have rewritten a big part of your code. I have place inline comments to explain what I do.
function select() {
var x = parseInt(document.getElementById('1').value, 10);
// Getting the div that wraps the initial form.
var formWrapper = document.querySelector('.formWrapper');
// Getting the div, that is going to display the new fields and the results.
var results = document.querySelector('.results');
// I have switch your statement from x == '' to '' === x as it
// consists a good practice
if ( '' === x ) {
alert("Please fill up number of subject");
// I have remove the isNaN(x) == true, because the isNan will
// be either true or false.
} else if ( isNaN(x) ) {
alert("Please fill up number of subject with number");
} else {
// Using parseInt(x, 10) to set the base.
var subject = parseInt(x, 10);
// In this array, I store the auto-generated fields.
var fieldsList = [];
// Removing the first div from the DOM
formWrapper.parentElement.removeChild(formWrapper);
for ( var num = 1; num <= subject; num++ ) {
// I am creating a new field
var newField = document.createElement('input');
// I push the field into the array I made for the fields.
fieldsList.push(newField);
// I append the field in the HTML
results.appendChild(newField);
// I create a <br> tag
var br = document.createElement('br');
// And I append the tag in the DOM
results.appendChild(br);
}
// I create the button that is going to handle the Next functionality
var nextButton = document.createElement('button');
// I set the button text
nextButton.innerText = 'Next';
// I add an Event Listener for the click event.
nextButton.addEventListener(
'click',
function() {
// I reset the sum to 0
var sum = 0;
// I itterate the fields auto-generated and saved in the array
fieldsList.forEach(
function(field) {
// I get the value
sum += parseInt(field.value, 10);
}
);
// I create the field that is going to display the output
let resultText = document.createElement('div');
// I set the text based on the sum
resultText.innerText = "Total marks: " + sum + "%";
// I append the text message to the DOM
results.appendChild(resultText);
}
);
// I append the button to the DOM
results.appendChild(nextButton);
}
}
<html>
<body>
<div class="formWrapper">
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</div>
<div class="results"></div>
</body>
</html>

Display times table up to 12 based on the users input

it seems to think ttinput is a string when I console.log the variable it says "". All else seems to working I just can't figure out how to have ttinput as a number.
document.getElementById("enter").addEventListener("click", ttcalc)
var ttinput = document.getElementById("table").value;
var ttoutput;
function ttcalc(){
var display = "";
for(var i = 1; i <= 12; i++){
ttoutput = ttinput * i;
display += ttinput + "*" + i + "=" + ttoutput + "<br>"
console.log(ttoutput, ttinput, i);
}
document.getElementById("output").innerHTML = display;
}
this is my html
<form>
<h1>Enter what times table you wish to see</h1>
<input type="number" id="table"><br>
</form>
<button id="enter">Show Times Table</button>
</div>
The problem is that the value of
var ttinput = document.getElementById("table").value;
is read on page load (while the input field is empty). If you move that line of code inside your function it will read the value of the input field after the button is clicked.
If you want to be sure the value entered is a number you can use the parseInt() function and then check if the result is a number with the isNaN() function like this:
var ttinput = parseInt(document.getElementById("table").value);
and then use isNaN():
if( !isNaN(ttinput) ) {
// ttinput is a number
} else {
// ttinput is not a number
}
More here: parseInt and isNaN.
Check example below:
document.getElementById("enter").addEventListener("click", ttcalc)
function ttcalc() {
var ttinput = parseInt(document.getElementById("table").value);
var ttoutput;
var display = "";
if( !isNaN(ttinput) ) {
for(var i = 1; i <= 12; i++) {
ttoutput = ttinput * i;
display += ttinput + "*" + i + "=" + ttoutput + "<br>"
console.log(ttoutput, ttinput, i);
}
document.getElementById("output").innerHTML = display;
} else {
console.log("value is not a number");
}
}
<button id="enter">Enter</button>
<input type="text" id="table" value="">
<div id="output"></div>

How to get filter value for each effect?

How to get filter value for each effect with % and px and only numbers without % and px.
In the codec I have listed 3 filters (of course there may be more).
What is the best way?
<button onclick="myFunction()">Try it</button><br><br>
<img id="myImg"
src="https://www.roadrunnerrecords.com/sites/g/files/g2000005056/f/sample-4.jpg"
width="300"
height="300"
style="filter:grayscale(100%) blur(5px) brightness(150%)" />
function myFunction() {
var grayscale = document.getElementById("myImg").style.filter;
var blur = document.getElementById("myImg").style.filter;
var brightness = document.getElementById("myImg").style.filter;
alert("grayscale value = , blur value= , brightness value= "); //without % and px
alert("grayscale value = , blur value= , brightness value= "); //with % and px
}
function myFunction() {
var effects = document.getElementById("myImg").style.filter.split(" ");
var imgFilter = {};
for (var i = 0; i < effects.length; ++i) {
var split = effects[i].split("(");
imgFilter[split[0]] = split[1].substring(0,split[1].length-1);
}
alert("grayscale value = "+imgFilter.grayscale+" , blur value= "+imgFilter.blur+", brightness value= "+imgFilter.brightness);//with % and px
alert("grayscale value = "+imgFilter.grayscale.replace(/[^\d.]/g,"")+" , blur value= "+imgFilter.blur.replace(/[^\d.]/g,"")+", brightness value= "+imgFilter.brightness.replace(/[^\d.]/g,""));//without % and px
} // How to add Hue-rotate???
Using string parsing techniques to separate out the needed parts and create an object:
function myFunction() {
var element = document.getElementById("myImg");
// split filter string into an array of effects
var effects = element.style.filter.split(" ");
var imgFilter = {};
for (var i = 0; i < effects.length; ++i) {
// use regex to match value before parenthesis and value inside
var matches = effects[i].match(/(.*)\((.*)\)/);
// create a key with the effect name (ex. "grayscale")
imgFilter[matches[1]] = {};
// set the withUnits value to the number that is in the parenthesis
imgFilter[matches[1]]["withUnits"] = matches[2];
// remove characters that are not digits or periods using regex
imgFilter[matches[1]]["withoutUnits"] = matches[2].replace(/[^\d.]/g,"");
}
//with % and px
for (var i = 0, log = ""; i < Object.keys(imgFilter).length; ++i) {
log += Object.keys(imgFilter)[i] + " value = " + imgFilter[Object.keys(imgFilter)[i]].withUnits + ", ";
}
alert(log);
//without % and px
for (var i = 0, log = ""; i < Object.keys(imgFilter).length; ++i) {
log += Object.keys(imgFilter)[i] + " value = " + imgFilter[Object.keys(imgFilter)[i]].withoutUnits + ", ";
}
alert(log);
}
<button onclick="myFunction()">Try it</button><br><br>
<img id="myImg"
src="https://www.roadrunnerrecords.com/sites/g/files/g2000005056/f/sample-4.jpg"
width="300"
height="300"
style="filter:grayscale(100%) blur(5px) brightness(150%) hue-rotate(180deg)" />
For the effects: "grayscale(100%) blur(5px) brightness(150%)", the object imgFilter that is created has these value:
{
"grayscale": {
"withUnits": "100%",
"withoutUnits": "100"
},
"blur": {
"withUnits": "5px",
"withoutUnits": "5"
},
"brightness": {
"withUnits": "150%",
"withoutUnits": "150"
}
}
You can access any particular value by using, for example imgFilter.grayscale.withUnits to get "100%" or imgFilter.blur.withoutUnits to get "5".
For accessing effects that contain hyphens (such as hue-rotate), you will need to access the value using quotes and brackets, for example, imgFilter["hue-rotate"].withUnits.
Adding hue-rotate to the version you are using in your edit:
function myFunction() {
var effects = document.getElementById("myImg").style.filter.split(" ");
var imgFilter = {};
for (var i = 0; i < effects.length; ++i) {
var split = effects[i].split("(");
imgFilter[split[0]] = split[1].substring(0,split[1].length-1);
}
alert("hue-rotate value = "+imgFilter["hue-rotate"]+" , grayscale value = "+imgFilter.grayscale+" , blur value= "+imgFilter.blur+", brightness value= "+imgFilter.brightness);//with % and px
alert("hue-rotate value = "+imgFilter["hue-rotate"].replace(/[^\d.]/g,"")+" , grayscale value = "+imgFilter.grayscale.replace(/[^\d.]/g,"")+" , blur value= "+imgFilter.blur.replace(/[^\d.]/g,"")+", brightness value= "+imgFilter.brightness.replace(/[^\d.]/g,""));//without % and px
}
<button onclick="myFunction()">Try it</button><br><br>
<img id="myImg"
src="https://www.roadrunnerrecords.com/sites/g/files/g2000005056/f/sample-4.jpg"
width="300"
height="300"
style="filter:grayscale(100%) blur(5px) brightness(150%) hue-rotate(180deg)" />
You'll need to parse it manually somehow, regex will do:
let filter = document.getElementById("myImg").style.filter;
let filterProps = Object.fromEntries(filter.split(" ").map((v) => {let m=v.match(/([a-z-]+)\((\d+)(%|px)\)/); return [m[1], m[2]]}));
filterProps.grayscale; // 100
filterProps.blur; // 5
filterProps.brightness; // 150

Using for loop to generate text boxes

I want to be able to enter a number into a text box and then on a button click generate that number of text boxes in another div tag and automatically assign the id
Something like this but not sure how to generate the text boxes and assign automatically assign the id
function textBox(selections) {
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<form><input type="text" id="1" name=""><br></form>");
}
}
Try this one:
function textBox(selections){
selections = selections*1; // Convert to int
if( selections !== selections ) throw 'Invalid argument'; // Check NaN
var container = document.getElementById('divSelections'); //Cache container.
for(var i = 0; i <= selections; i++){
var tb = document.createElement('input');
tb.type = 'text';
tb.id = 'textBox_' + i; // Set id based on "i" value
container.appendChild(tb);
}
}
A simple approach, which allows for a number to be passed or for an input element to be used:
function appendInputs(num){
var target = document.getElementById('divSelections'),
form = document.createElement('form'),
input = document.createElement('input'),
tmp;
num = typeof num == 'undefined' ? parseInt(document.getElementById('number').value, 10) : num;
for (var i = 0; i < num; i++){
tmp = input.cloneNode();
tmp.id = 'input_' + (i+1);
tmp.name = '';
tmp.type = 'text';
tmp.placeholder = tmp.id;
form.appendChild(tmp);
}
target.appendChild(form);
}
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(); // no number passed in
});
JS Fiddle demo.
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(12);
});
JS Fiddle demo.
The above JavaScript is based on the following HTML:
<label>How many inputs to create:
<input id="number" type="number" value="1" min="0" step="1" max="100" />
</label>
<button id="create">Create inputs</button>
<div id="divSelections"></div>
See below code sample :
<asp:TextBox runat="server" ID="textNumber"></asp:TextBox>
<input type="button" value="Generate" onclick="textBox();" />
<div id="divSelections">
</div>
<script type="text/javascript">
function textBox() {
var number = parseInt(document.getElementById('<%=textNumber.ClientID%>').value);
for (var i = 0; i < number; i++) {
var existingSelection = document.getElementById('divSelections').innerHTML;
document.getElementById('divSelections').innerHTML = existingSelection + '<input type="text" id="text' + i + '" name=""><br>';
}
}
</script>
Note: Above code will generate the N number of textboxes based on the number provided in textbox.
It's not recommended to user innerHTML in a loop :
Use instead :
function textBox(selections) {
var html = '';
for (i=0; i < selections +1; i++) {
html += '<form><input type="text" id="'+i+'" name=""><br></form>';
}
document.getElementById('divSelections').innerHTML = html;
}
And be carefull with single and double quotes when you use strings
You have to change some code snippets while generating texboxes, Learn use of + concatenate operator, Check code below
function textBox(selections) {
for (var i=1; i <= selections; i++) {
document.getElementById('divSelections').innerHTML += '<input type="text" id="MytxBox' + i + '" name=""><br/>';
}
}
textBox(4); //Call function
JS Fiddle
Some points to taken care of:
1) In for loop declare i with var i
2) your selection + 1 isn't good practice at all, you can always deal with <= and < according to loop's staring variable value
3) += is to append your new HTML to existing HTML.
ID should be generate manually.
var inputName = 'divSelections_' + 'text';
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<input type='text' id= " + (inputName+i) + " name=><br>");
}
edit : code formated
Instead of using innerHTML, I would suggest you to have the below structure
HTML:
<input type="text" id="id1" />
<button id="but" onclick="addTextBox(this)">click</button>
<div id="divsection"></div>
JS:
function addTextBox(ops) {
var no = document.getElementById('id1').value;
for (var i = 0; i < Number(no); i++) {
var text = document.createElement('input'); //create input tag
text.type = "text"; //mention the type of input
text.id = "input" + i; //add id to that tag
document.getElementById('divsection').appendChild(text); //append it
}
}
JSFiddle

How do i make text = integers

I have a problem that i've been trying to solve for days.
I was wondering if it was possible to let a text turn into an integer.
So everytime i write in my textarea("ALC") Load, then on the textarea("MLC") 001. And also including 1-15 to binary at the end
E.g. Load #1 will show 001 0 00001
<html>
<head>
<center><font size ="24"> Simple Assembler </font></center>
<script type="text/javascript">
var Load = "001";
var Store = "010";
var Add = "011";
var Sub = "100";
var Equal = "101";
var Jump = "110";
var Halt = "111";
var # = "1";
</script>
</head>
<body>
<form name="AssemblyLanguagecode" action="" method="">
<textarea Id="ALC" style="resize:none;width:35%;height:35%;margin-left:15%" value="">Insert Assembly Language Code</textarea>
<textarea Id="MLC" style="resize:none;width:35%;height:35%;" ReadOnly="True">Machine Language Code will be displayed here</textarea><br />
<p align="center"><input type="button" value="Assemble" onclick="ALCtoMLC()";" /></p>
</form>
<script type= "text/javascript">
function ALCtoMLC() {
var x = document.getElementById("ALC").value;
x = parseInt(x);
var bin = x.toString(2);
document.getElementById("MLC").innerHTML = bin;
}
</script>
</body>
</html>
I think I understand what you want to do. You want to use what you type into "ALC" as a key to a value. In that case, you want to use a javascript object and assign the instructions as keys, and the binary to the value. Such as
var instruction_set = {
"Load" : "001",
"Store" : "010",
"Add" : "011",
"Sub" : "100",
"Equal" : "101",
"Jump" : "110",
"Halt" : "111"
}
function ALCtoMLC() {
var x = document.getElementById("ALC").value;
x = instruction_set[x];
}
Updated:
Try this:
<html>
<head>
<center><font size ="24"> Simple Assembler </font></center>
<script type="text/javascript">
var Load = "001";
var Store = "010";
var Add = "011";
var Sub = "100";
var Equal = "101";
var Jump = "110";
var Halt = "111";
var # = "1";
</script>
</head>
<body>
<form name="AssemblyLanguagecode" action="" method="">
<textarea Id="ALC" style="resize:none;width:35%;height:35%;margin-left:15%" value="">Insert Assembly Language Code</textarea>
<textarea Id="MLC" style="resize:none;width:35%;height:35%;" ReadOnly="True">Machine Language Code will be displayed here</textarea><br />
<p align="center"><input type="button" value="Assemble" onclick="ALCtoMLC();" /></p>
</form>
<script type= "text/javascript">
var Dict = { 'Load':"001",'Store':"010"}; //example Instruction set
function ALCtoMLC() {
var x = document.getElementById("ALC").value;
var instrType = '';
for (var instr in Dict){
var ind = x.indexOf(instr);
if( ind > -1){
instrType = instrType + Dict[instr];
x = x.replace(instr,'');
}
}
console.log(instrType, "::", x);
x = parseInt(x);
var bin = x.toString(2);
bin = instrType + bin;
document.getElementById("MLC").innerHTML = bin;
}
</script>
</body>
</html>
Lets say you have a way to get the tokens. Then your function should look like this
var tokens = getTokens( document.getElementById("ALC").value ) ;
var vocabulary = { "Load" : "001" , " ... " } ;
var output = []
var i = 0;
var tokensLength = tokens.length;
for ( ; i < tokensLength; i++){
var token = tokens[i];
if ( isNaN(token) && typeof(vocabulary[token]) != "undefined" ){
output.push( vocabulary[token] );
}else if ( !isNaN(token) ){
output.push( Number(token).toString(2) );
}else{
console.log(["error : unknown token ", token]);
}
}
document.getElementById("MLC").value = output.join(" ");
I see in the question that Load translates to 0010 and not 001, so I would simply modify the vocabulary.
Explanation :
I assume you have a way to split the input to tokens. (the ALC syntax is still unclear to me).
The tokens array will contains, for example ["Load","#","15", "Load","#","16"] and so on.
Then I loop on the tokens.
If a token is a number - I turn it to binary string.
If the token is translatable by vocabulary - I switch it to its binary representation.
Otherwise I print an error.
NOTE: if output should be padded with "0" - even though it is not specified in the question, I would use "0000".substring(n.length) + n
This is how I would do it:
var opcodes = {
Load: 1,
Store: 2,
Add: 3,
Sub: 4,
Equal: 5,
Jump: 6,
Halt: 7
};
var assemblyTextarea = document.querySelector("#assembly");
var machineTextarea = document.querySelector("#machine");
document.querySelector("#assemble").addEventListener("click", function () {
var instruction = assemblyTextarea.value.split(" ");
var operand =+ instruction[1].slice(1);
var opcode = instruction[0];
var code = opcodes[opcode] * 16 + operand;
var bits = ("0000000" + code.toString(2)).slice(-8);
machineTextarea.value = bits;
}, false);
See the demo here: http://jsfiddle.net/fs5mb/1/
The input should be formatted as follows: Load #15

Categories

Resources