Changing the css of code ouput on an HTML page with Skulpt - javascript

I have the following program (using skulpt) which generates python output in the browser on hitting "run". The output code is in the "pre" tags. I have tried various different things to apply the CSS to the executed output, but it isn't working.
This is my css
<style>
.running {
border: 20px outset black ;
background-color: black;
text-align: center;
p: color:white;
pre
{
white-space: pre-wrap !important;
}
}
</style>
This is the HTML part of the code.
<h3>Heading here</h3>
<form>
<textarea id="yourcode" cols="40" rows="10">
print("Hello World")
</textarea><br />
<button type="button" onclick="runit()">Run</button>
<button type="button" onclick="clearit()">Clear</button>
<button type="button" onclick="clearit()">--X--</button>
<button type="button" onclick="clearit()">--Y--</button>
<button type="button" onclick="clearit()">--Z--</button>
</form>
<br>
<br>
<br>
<div class="running">
<pre id="output" ></pre>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas">
</div>
I assume it is this that is responsible for generating the output code:
<pre id="output" ></pre>
This is the javascript functionality (for reference) that produces the output code
<body>
<center>
<script type="text/javascript">
// output functions are configurable. This one just appends some text
// to a pre element.
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
// Here's everything you need to run a python program in skulpt
// grab the code from your textarea
// get a reference to your pre element for output
// configure the output function
// call Sk.importMainWithBody()
function runit() {
var prog = document.getElementById("yourcode").value;
var mypre = document.getElementById("output");
mypre.innerHTML = '';
Sk.pre = "output";
Sk.configure({output:outf, read:builtinRead});
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(function(mod) {
console.log('success');
},
function(err) {
console.log(err.toString());
});
}
function clearit(){
document.getElementById('yourcode').value = 'Your awesome code here';
document.getElementById('output').innerHTML = '';
}
</script>
Question: How do I format the code such that the background is black (this works) but the output code on pressing "run" is WHITE.
I don't know if it is due to missing out an ID - I notice the pre tags in the HTML have an id or incorrect use of the tags in the css. An explanation along with a solution (code) would be appreciated.
Other things I have tried in the CSS: (doesn't work either)
<style>
.running {
border: 20px outset black ;
background-color: black;
text-align: center;
p: color:white;
pre {
color:white;
display: block;
font-family: monospace;
white-space: pre;
margin: 1em 0;
}
}
</style>

It seems p: color: white; is invalid css, since p is an element not a style property. Instead, this line should be just color: white;.
Example snippet below:
.running {
border: 20px outset black;
background-color: black;
text-align: center;
color:white;
pre {
white-space: pre-wrap !important;
}
}
<h3>Heading here</h3>
<form>
<textarea id="yourcode" cols="40" rows="10">
print("Hello World")
</textarea><br />
<button type="button" onclick="runit()">Run</button>
<button type="button" onclick="clearit()">Clear</button>
<button type="button" onclick="clearit()">--X--</button>
<button type="button" onclick="clearit()">--Y--</button>
<button type="button" onclick="clearit()">--Z--</button>
</form>
<br>
<br>
<br>
<div class="running">
<pre id="output">Test output should be white!</pre>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas">
</div>

Related

Avoid line break when using span tag

I've created an HTML script that allows the user to update keywords in a block of text, then copy that text to their clipboard. The text should display like this:
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
But because of the "span" tags, the formatting is completely off (run the code below to see what I mean). I believe span is adding a line break before and after the text it is covering.
Here is my code:
<p>Enter value 1</p>
<input type="text" id="myText1" value="1st value">
<br>
<p>Enter value 2</p>
<input type="text" id="myText2" value="2nd value">
<br>
<button onclick="myFunction()">Update text block</button>
<br>
<br>
<pre style="color: #000; background: #cccccc; padding:10px; display: inline-flex" id="TextToCopy">
{
"key1":"<span id="var1">value1</span>",
"key2":"<span id="var2">value2</span>",
"key3":"value3"
}</pre>
<button style="display: grid" onclick="copyToClipboard()">Click to Copy</button>
<script>
function myFunction() {
var x = document.getElementById("myText1").value;
document.getElementById("var1").innerHTML = x;
 var y = document.getElementById("myText2").value;
document.getElementById("var2").innerHTML = y;
}
</script>
<script>
function copyToClipboard() {
var copyText = document.getElementById("TextToCopy");
navigator.clipboard.writeText(copyText.innerText);
}
</script>
Any help would be greatly appreciated! Thank you
You need to remove display: inline-flex; property, and it should work:
<pre style="color: #000; background: #cccccc; padding:10px;" id="TextToCopy">
{
"key1":"<span id="var1">value1</span>",
"key2":"<span id="var2">value2</span>",
"key3":"value3"
}</pre>
You can use a CSS style to remove the white space before and after the text:
<pre style="color: #000; background: #cccccc; padding:10px; display: inline-flex; white-space: pre-wrap;" id="TextToCopy">
{
"key1":"<span id="var1">value1</span>",
"key2":"<span id="var2">value2</span>",
"key3":"value3"
}</pre>
The white-space: pre-wrap; style will preserve any line breaks in the text, while still preventing the text from breaking to a new line when the text is too wide to fit the container.
It can be done without span or ids
<!DOCTYPE html>
<html>
<body>
<p>Enter value 1</p>
<input type="text" id="myText1" value="1st value">
<br>
<p>Enter value 2</p>
<input type="text" id="myText2" value="2nd value">
<br>
<button onclick="myFunction()">Update text block</button>
<br>
<br>
<pre style="color: #000; background: #cccccc; padding:10px; display: inline-flex" id="TextToCopy">
</pre>
<button style="display: grid" onclick="copyToClipboard()">Click to Copy</button>
<script>
function myFunction() {
var x = document.getElementById("myText1").value;
var y = document.getElementById("myText2").value;
document.getElementById("TextToCopy").innerHTML =
`
{
"key1":"${x}",
"key2":"${y}",
"key3":"value3"
}
`;
}
</script>
<script>
function copyToClipboard() {
var copyText = document.getElementById("TextToCopy");
navigator.clipboard.writeText(copyText.innerText);
}
</script>
</body>
</html>

Trying to add a submit button and then it would display the "msg" - I am very new, just trying to cobble something together :)

I am not sure what i am doing exactly, but have some code that is working at the moment. I want to have a whole bunch of zip codes and when someone enters their zip and clicks submit it will return a message. Instead of the message just displaying as you type.
Any help is appreciated!
<!DOCTYPE html>
<html>
<body>
<h1 style="color:black; font-family: arial; font-size: 110%; ">Not sure if we deliver to your area?</h1>
<h2 style="color:black; font-family: arial; font-size: 90%; font-weight:40; ">Enter your zip code to find out.</h1>
<input type="text" id="zipCode" placeholder="ZIP code" onKeyUp="validateZip()"/>
<div id="msg" style="color:black; font-family: arial; font-size: 90%; font-weight:40; margin-top: 10px;"></div>
<script>
function checkIfAvailable(zip)
{
let zones = ["55075","55118","55115"]
return( zones.indexOf(zip) >= 0 )
}
function validateZip()
{
let zip = document.getElementById("zipCode").value;
let msg =""
if(checkIfAvailable(zip))
{
msg="We deliver to your area!";
}
else
{
msg="Sorry, we do not deliver to your area.";
}
document.getElementById("msg").innerHTML = msg;
}
</script>
</body>
</html>
Your script is working as expected here, currently you're running validateZip every time a key is pressed, because it's on the onKeyUp attribute of your input element.
To run this function when the submit button is clicked, run the script on the "onClick" attribute of a button.
For example:
<input type="text" id="zipCode" placeholder="ZIP code" />
<div id="msg" style="color:black; font-family: arial; font-size: 90%; font-weight:40; margin-top: 10px;"></div>
<button onclick="validateZip()">Submit</button>
This way it only runs once, not every time you press a key.
So, just added a eventListener to a button
<!DOCTYPE html>
<html>
<body>
<h1 style="color:black; font-family: arial; font-size: 110%; ">Not sure if we deliver to your area?</h1>
<h2 style="color:black; font-family: arial; font-size: 90%; font-weight:40; ">Enter your zip code to find out.</h2>
<input type="text" id="zipCode" placeholder="ZIP code" />
<button id="sendButton">Send</button>
<div id="msg" style="color:black; font-family: arial; font-size: 90%; font-weight:40; margin-top: 10px;"></div>
<script>
var button = document.getElementById("sendButton");
function checkIfAvailable(zip) {
let zones = ["55075", "55118", "55115"]
return (zones.indexOf(zip) >= 0);
}
button.addEventListener("click", function validateZip() {
let zip = document.getElementById("zipCode").value;
let msg = "";
if (checkIfAvailable(zip)) {
msg = "We deliver to your area!";
} else {
msg = "Sorry, we do not deliver to your area.";
}
document.getElementById("msg").innerHTML = msg;
});
</script>
</body>
</html>

How to wrap div element around newly typed text so that associated css result will be shown in real time

I have created a simple text editor which shows the associated CSS results in real time. for example if a user clicks Bold Then text becomes bold while user is typing (it shows real time change). Same like this I want a button after click it will wrap the new text with a div tag with specified class or id.
I know wrap method can wrap the div or other tag. But after adding new div tags through wrap() I want store its result which contains newly added div tags. so that I can use those result to generate new html pages.
Here is the html code:
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script src="texteditor.js"></script>
</head>
<body>
<div id="content" style="margin-top: 10px; height: 70%; text-align: center;">
<h2><u>Simple Text Editor Created Using jQuery</u></h2>
<div class="ze ie"></div>
<style>
.font-bold.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.selected {
background-color: orange;
}
#openpb {
margin: 15px;
}
</style>
<button type="button" class="g-button g-button-submit" id='stext'>Text</button>
<button type="button" class="g-button g-button-submit" id='shtml'>HTML</button>
<div id="controls" style="margin-bottom: 10px;">
<a id="bold" style="color: black; display: inline-block;" class="font-bold">
<button type="button">B</button>
</a>
<a id="italic" style="color: black !important; display: inline-block;" class="italic">
<button type="button">I</button>
</a>
<a id="link" class="link" style="display: inline-block;">
<button type="button">Link</button>
</a>
<select id="fonts" class="g-button">
<option value="Normal">Normal</option>
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma New">Tahoma</option>
<option value="Times">Times</option>
<option value="Trebuchet New">Trebuchet</option>
<option value="Ubuntu">Ubuntu</option>
</select>
</div>
<iframe frameborder="0" id="textEditor" style="width: 500px; height: 80px; border: 2px solid #CCC; border-radius: 20px; overflow: auto;"></iframe>
<textarea name="text" id='text' style="border-radius: 20px; overflow: auto; display: none; padding-left: 10px;" rows="6" cols="53"></textarea>
</div>
</body>
</html>
here is Jquery: as you can I have used setinterval method to show result in real time in textarea. same like this I want a button which will wrap new or selected text with div tag with specified id and class and I want store this changes(newly added div tag) in textarea.
$(document).ready(function () {
document.getElementById('textEditor').contentWindow.document.designMode = "on";
document.getElementById('textEditor').contentWindow.document.close();
var edit = document.getElementById("textEditor").contentWindow;
edit.focus();
$("#bold").click(function () {
if ($(this).hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
boldIt();
});
$("#italic").click(function () {
if ($(this).hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
ItalicIt();
});
$("#fonts").on('change', function () {
changeFont($("#fonts").val());
});
$("#link").click(function () {
var urlp = prompt("What is the link:", "http://");
url(urlp);
});
$("#stext").click(function () {
$("#text").hide();
$("#textEditor").show();
$("#controls").show()
});
$("#shtml").on('click', function () {
$("#text").css("display", "block");
$("#textEditor").hide();
$("#controls").hide();
});
});
function boldIt() {
var edit = document.getElementById("textEditor").contentWindow;
edit.focus();
edit.document.execCommand("bold", false, "");
edit.focus();
}
function ItalicIt() {
var edit = document.getElementById("textEditor").contentWindow;
edit.focus();
edit.document.execCommand("italic", false, "");
edit.focus();
}
function changeFont(font) {
var edit = document.getElementById("textEditor").contentWindow;
edit.focus();
edit.document.execCommand("FontName", false, font);
edit.focus();
}
function url(url) {
var edit = document.getElementById("textEditor").contentWindow;
edit.focus();
edit.document.execCommand("Createlink", false, url);
edit.focus();
}
setInterval(function () {
var gyt = $("#textEditor").contents().find("body").html().match(/#/g);
if ($("#textEditor").contents().find("body").html().match(/#/g) >= 0) { } else {
$("#text").val($("#textEditor").contents().find("body").html());
}
$("#text").val($("#textEditor").contents().find("body").html());
}, 1000);
I don't want use third party text editor plugins. in short I want texteditor which contain a button, after clicking this button it will wrap new text with div tag with specified class or id. something like Stack Overflow text editor...with facility of adding custom div with specified class or id.
<html>
<head>
<style>
#Problem{margin: 5px; outline: 1px dotted red; padding: 5px}
#Solution{margin: 5px; outline: 1px dotted green; padding: 5px}
#Solution textarea{
height: 200px;
width: 500px;
}
</style>
<script>
//Wraps the text in a new div with optional id and classname.
//Returns the new div.
function wrapMe(text, id, classname){
var tE = null;
if (text && text.trim() != ''){
tE = document.createElement('div');
tE.id = (id || '');
tE.className = (classname || '');
tE.innerHTML = (text || '');
}
return tE
}
//Adds the outer html of passed element to the textarea with a linebreak
function addElementToTextarea(e){
var tA = document.querySelector('textarea');
if (tA && e){
tA.innerHTML = (tA.innerHTML || '') + e.outerHTML + '
&#010'
}
}
</script>
</head>
<body>
<div id = 'Problem'>
Problem: I don't want use third party text editor plugins. in short i want texteditor which contain a button, after clicking this button it will wrap new text with div tag with specified class or id. something like stackover flow text editor...with facility of adding custom div with speicifed class or id.
</div>
<div id = 'Solution'>
<input type = 'text' />
<button onclick = "addElementToTextarea(wrapMe(this.parentNode.querySelector('input').value, 'testid', 'testclass'))">Wrap me</button>
<br /><br />
<textarea readonly = 'readonly'></textarea>
</div>
</body>
</html>

CSS Lines Appearing

Edit: the issue seems to only appear on OSX Mavericks w/ Latest Google Chrome (for me)
I have an event log that posts messages from the top down, and with every message, small black lines are appearing at the bottom right of each message and I can't figure out why.
Here is a working version of my game, click "Hunt for Blood" and when a few event log messages stack up, you'll see what I'm talking about.
http://codepen.io/RUJordan/pen/dcwLC
Here's a picture as well:
Here is my CSS relevant to the log div and msg div
.msg {
float: left;
width:auto;
overflow:auto;
padding: 5px;
font-size: small;
}
.column {
padding:3px;
float: left;
width:30%;
border:1px solid black;
background-color:#222222;
} /* Hidden Elements */
.hp, .cycle, .gold, .log, .middleCol,
.battle, .hiddenCounter {
display:none;
}
And here is my HTML schema.
<!DOCTYPE html>
<html>
<head>
<title>A Vampire's Hunt</title>
<link rel="stylesheet" href="vamp.css">
</head>
<body>
<h1 class="title">A Vampire's Hunt</h1>
<div class="main">
<div id="stats" class="column">
<div>
<h3 class="miniTitle">Stats</h3>
<hr />
<span id="spanCounter" class="hiddenCounter noRed">You have been dead for <span id="counter">0</span> hour<span id="singularHours" class="noRed"></span>..</span>
<span id="spanInitMsg" class="spanInitMsg noRed">You are dead!</span>
</div>
<div id="divCycle" class="cycle">It is currently: <span id="cycle"></span></div>
<div>Blood: <span id="blood">0</span></div>
<div class="hp" id="hpDiv">HP: <span id="hp">20</span></div>
<div class="gold" id="goldDiv">Gold: <span id="gold">0</span></div>
<h3 class="miniTitle">Actions</h3>
<hr />
</div>
<div id="middleCol" class="column middleCol">
<div id="shop" class="shop">
<h4 class="miniTitle">A Dark Alleyway</h4>
<hr />
Herp Derp Derp
</div>
<div id="battle" class="battle">
<hr />
</div>
</div>
<div id="log" class="log column">
<h3 class="miniTitle">Event Log</h3>
<hr />
<div id="msg" class="msg"></div>
</div>
</div>
<script src="player.js"></script>
<script src="element.js"></script>
<script src="engine.js"></script>
<script src="vampire.js"></script>
<div class="footer">
Follow This Project on Github!
</div>
</body>
</html>
I do not think the JavaScript is the culprit, but just in case, here is the event log function, along with the functions it calls.
eventMsg : function(txt) {
this.addBorder("log");
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
This appears to work on FireFox and Safari, but not on Chrome.
Try using display: inline-table on div id "log". Note that it uses inline CSS that is reset on each click, so you'll have to overwrite this, otherwise it won't work.
EDIT : display: table should work too.
The lines seem to appear because you had border-width: 0 0 1px 0; instead of this:
hr:before {
border-width: 0;
}
Although, I have not tested on other browsers, but it seems to work with chrome.
Chrome Version 31.0.1650.57 m
fixed the line issue by changing:
eventMsg : function(txt) {
this.addBorder("log");
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
to:
eventMsg : function(txt) {
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
Have another potential fix for you, change the css from:
.msg {
float: left;
width:auto;
overflow:auto;
padding: 5px;
font-size: small;
}
to
.msg {
float: left;
width:100%;
overflow:auto;
padding: 5px;
font-size: small;
}

Is there a limitation when applying the style via the class attribute in javascript?

I am trying to create a label via javascript but the css does not seem to be applied.
Example code (tested in Chrome):
<html>
<head>
<style type="text/css">
#wrapper {
width:700px;
}
#form_groups .label {
float:left;
clear:left;
width:180px;
margin-right:3px;
margin-top:2px;
background-color:red;
}
#the_id {
background-color: #FBEF99;
font-family:"Lucida Console", Monaco, monospace;
font-size: .9em;
width: 300px;
margin-top: 2px;
}
</style>
</head>
<body>
<input type="submit" value="Create" onclick="createForm()"/>
<div id="wrapper">
<form id="form_groups" action="">
<label class="label">Id</label>
<input id="the_id" type="text" value="1">
</form>
</div>
<script type="text/javascript">
function createForm () {
var wrapper = document.getElementById('wrapper');
var form = document.getElementById('form_groups');
wrapper.removeChild(form);
form = document.createElement('form');
form.id='form_groups';
var lbl = document.createElement('label');
lbl.textContent = 'Name';
lbl.class = 'label';
var name = document.createElement('input');
name.type = 'text';
name.id='the_id';
form.appendChild(lbl);
form.appendChild(name);
wrapper.appendChild(form);
}
</script>
</body>
</html>
The text gets the css but the label does not when I press the button Create.
Is there a limitation when assigning a style using class attribute dynamically via javascript?
You should be using className and not class.
lbl.className = 'label';
Modern Day browsers support classList
lbl.classList.add("label");

Categories

Resources