Unable to edit textarea with JavaScript - javascript

I want to edit my textarea manually after updating it with JavaScript, but when I write some text on it, the text I write is positioned over the text which is already in the textarea (written by JS).
So I'm searching of why can't I do it. Here is my code:
function initTextIA() {
var txt = document.createElement('textarea');
txt.style.rows = "5";
txt.style.cols = "45";
txt.style.top = "2300px";
txt.style.left = "250px";
txt.style.position = "absolute";
txt.style.background = "none";
txt.style.color = "green";
txt.id = "txtIA";
document.getElementById("cool").appendChild(txt);
}
initTextIA();
var doc = document.getElementById("txtIA")
doc.value += "txtxtxtxt.\n";
<div id="cool"></div>
The resulting HTML code of the textarea is :
<textarea id="txtIA" style="top: 2300px; left: 250px; position: absolute; background: none; color: green;"></textarea>

From comments it sounds to me like your line-height property is not properly set for textarea. Since you set textarea value with line break on the end:
txtxtxtxt.\n
newly written text should go in second row but it overlaps old text entered with JS. So try the following inside your initTextIA function:
txt.style.lineHeight = "2";

Since there is little original HTML provided in question so there are a lot of assumptions here. What I feel from all the discussion in comments is you are not able to append text then type in a value then continue appending it via some button.
I have written a simple case where I have commented out the positioning of textarea so testing can be done with ease. I have added two buttons but no error checks just to give a direction. Please let me know if this does not resolve the issue.
function initTextIA() {
var txt = document.createElement('textarea');
txt.style.rows = "5";
txt.style.cols = "45";
//txt.style.top = "2300px";
//txt.style.left = "250px";
//txt.style.position = "absolute";
txt.style.background = "none";
txt.style.color = "green";
txt.id = "txtIA";
document.getElementById("cool").appendChild(txt);
document.getElementById('addButton').style = 'display:none';
document.getElementById('appendButton').style = 'display:block';
}
function fillTextIA() {
var doc = document.getElementById("txtIA")
doc.value += "txtxtxtxt.\n";
}
<div>
<button id='addButton' onclick='initTextIA()'>add text area</button>
<button id='appendButton' onclick='fillTextIA()' style='display:none'>append text</button>
</div>
<div id='cool'>
<p>An element.</p>
</div>

Related

Dynamically increasing font size

I would like to increase the font size of the paragraph as well as the font size of the number in the button.
I copied and pasted my sizer function from StackOverflow (a few alterations) and thought it would work and still can't get it to work. Can someone help?
Since I've spent so much time on just the first part, as a beginner programmer, I'm wondering what I am missing. Does anyone have any ideas from my code or their experience as to what I might be missing?
Thanks as always.
<html>
<button onclick='incrementer(); sizer()' id='count' value=0 />0</button>
<p id='test'>a</p>
<script>
clicks = 0
incrementer = function () {
clicks += 1
click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
}
sizer = function changeFontSize() {
div = document.getElementById("test");
currentFont = div.style.fontSize.replace("pt", "");
div.style.fontSize = parseInt(currentFont) + parseInt(clicks) + "pt";
}
</script>
</html>
Some things here:
I woudn't append two functions to your onclick here. Just append one and call your second function from the first one that gets fired via onclick. That looks a lot more tidy
Don't forget to put var before every variable, without it's not valid JavaScript
I didn't quite understand what you tried with your currentFont variable, so I removed it. It's not necessary and causes the script to not working correctly
<html>
<button onclick='incrementer()' id='count' value=0 />0</button>
<p id='test'>a</p>
<script>
var clicks = 0;
var incrementer = function() {
clicks += 1;
var click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
sizer();
}
var sizer = function changeFontSize() {
var div = document.getElementById("test");
div.style.fontSize = parseInt(clicks) + "pt";
}
</script>
</html>
Here's a from-scratch version that does what you're asking for. I'll point out a few things that I did to help you out.
https://codepen.io/anon/pen/VBPpZL?editors=1010
<html>
<body>
<button id="count">0</button>
<p id="test">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</p>
</body>
</html>
JS:
window.addEventListener('load', () => {
const button = document.querySelector('#count');
const paragraph = document.querySelector('#test');
const startingFontSize = window.getComputedStyle(document.body, null)
.getPropertyValue('font-size')
.slice(0, 2) * 1;
let clicks = 0;
button.addEventListener('click', () => {
clicks++;
// this is a template literal
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
const fontSize = `${startingFontSize + clicks}px`;
button.innerHTML = clicks;
button.style.fontSize = fontSize;
paragraph.style.fontSize = fontSize;
});
});
The code runs when the page is loaded, so we attach an event listener on the window object listening for the load event.
We then store references to the button and the paragraph elements. These are const variables because their values won't change. This also limits their scope to the containing function.
We get the initial font size for the body element, because in this example we aren't explicitly setting a base font in css so we're just using the one for the document. getComputedStyle is a somewhat expensive operation, and in this case we only need to get it in the beginning because it won't change, so we also store it as a const. The value is returned as a string like "16px" but we need the number, hence the slice and multiplying by one to cast the string into a number. parseInt would also do the same thing.
Notice that clicks is defined with let. This means that the variable can be changed. var still works of course, but in modern practices its best to use const and let when declaring variables. This is partly because it forces you to think about what kind of data you're working with.
We add an event listener to the button element and listen for the click event. First, we increment the clicks variable. Then we declare fontSize using a template literal which adds our new clicks count to the startingFontSize and "px" to get a string.
Finally, the innerHTML value of the button element is updated. Then we update the fontStyle property for both elements.
The issue here is that there is no initial value for the fontSize of your <p> tag so div.style.fontSize returns an empty string.
You can use window.getComputedStyle instead of div.style.fontSize and you will get the current fontSize.
There is already a post explaining this method
https://stackoverflow.com/a/15195345/7190518
You don't have an initial font-size style on your <p> tag, so it div.style.fontSize is always empty. Also, best practice is to always use var when introducing new variables in javascript.
One good trick to help debugging things like these is to use console.log() at various points, and see whats coming out in your browser console. I used console.log(div.style.fontSize) and the answer became clear.
Working below after adding <p style='font-size:12px'>a</p>:
<html>
<button style='font-size:12px;' onclick='incrementer(); sizer()' id='count' value=0 />0</button>
<p id='test' style='font-size:12px;'>a</p>
<script>
var clicks = 0
incrementer = function () {
clicks += 1
click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
}
var sizer = function changeFontSize() {
var div = document.getElementById("test");
var btn = document.getElementById("count");
var newSize = parseInt(div.style.fontSize.replace("pt", "")) + parseInt(clicks);
div.style.fontSize = newSize + "pt";
btn.style.fontSize = newSize + "pt";
}
</script>
</html>
I don't understand the logic of this solution, but you can simplify it avoiding to use a lot of var (anyway always prefer let or const if you don't need to change), using a single function and writing less code.
function increment(e){
const ctrl = document.getElementById('test');
let current = parseInt(e.dataset.size);
current += 1;
e.innerHTML = current;
e.dataset.size = current;
ctrl.style.fontSize = current + 'pt';
}
<button onclick="increment(this);" data-size="20">20</button>
<p id='test' style="font-size:20pt;">A</p>

How to pass a variable in document.getElementById. As well as getting undefined when calling a value in an array

<iframe id="frmFile" src="Book1.txt" onload="generateInventory();" style="display: none;"></iframe>
<script>
function csvpls() {
var oFrame = document.getElementById("frmFile");
var strRawContents = oFrame.contentWindow.document.body.childNodes[0].innerHTML;
while (strRawContents.indexOf("\r") >= 0)
strRawContents = strRawContents.replace("\r", "");
var arrLines = strRawContents.split(",");
return arrLines
}
function generateInventory(a, b) {
var xx = csvpls()
var div = document.createElement("div");
div.style.width = "1000px";
div.style.height = "100px";
div.style.background = "red";
div.style.color = "white";
div.innerHTML = "Hello " + xx[a] + " yes!";
document.getElementById(b).appendChild(div);
}
</script>
<div id="Q1"></div>
<script>
generateInventory(20, Q1);</script>
</body>
I am trying to create edit multiple divs with the following code. I hope to call each function with parameters to create the divs and put content in them.
So I have some problems with the code above. First off, document.getElementById(str).appendChild(div); is not working the way I want it to. It works if I put the div id "Q1" instead of b. Just wondering, if I can pass a variable through it. Secondly, when I change the div to "Q1", the div is generated, but the content in there is "Hello undefined Yes". If I call the array with xx[20] instead of xx[a], I would get what I want which is "Hello content yes". Sorry, this probably seems like a nuisance, any help is appreciated.

Why won't my JavaScript work!? It's selecting the ID but won't apply display changes

Before I get in to this, I know I should learn jQuery but I haven't got to that yet, I want to learn raw JavaScript first! Well, mostly. Can someone help me without the use of jQuery please just for understanding, thank you!:
Hi, I'm new to JavaScript, not long started learning it as you can see by the first code (which works so I'm leaving it) for the navigation.
However, my problem comes on the 2nd piece of code I'm trying something from a different angle after watching videos on event listeners etc and everything I have written makes sense, to me, I'm going through it step by step, it's selecting all the right stuff, but it's still not showing the desired result!!
When you click CSS i want it to show the div with id "cs", and same for the HTML and JavaScript ones.
I really don't know JavaScript enough to solve this myself, I can not think of anything AT ALL to help with the problem!
Somebody save me, please, my mind is going crazy and I want to go to bed!
Here is the code, and here is the JS fiddle: https://jsfiddle.net/pmj26o9p/2/
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
EDIT: On reading through the code again I don't think it will achieve what I want even if it works. This will let me show and hide whichever I'm clicking right?
I want to show the clicked one but then hide / apply display:none to all others that aren't clicked.
My example below will show the chosen block and hide the others, as per your EDIT comment.
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
function contentShow(el) {
var whichOne = el.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
// show selected block, hide the others
switch (switcheroo) {
case htm:
htm.style.display = "block";
css.style.display = "none";
js.style.display = "none";
break;
case js:
htm.style.display = "none";
css.style.display = "none";
js.style.display = "block";
break;
case css:
htm.style.display = "none";
css.style.display = "block";
js.style.display = "none";
break;
}
}
<span data-id="htm" onClick="contentShow(this)" style="margin-right:10px;color:red; cursor:pointer">Click to show the HTML Block</span>
<span data-id="css" onClick="contentShow(this)" style="margin-right:10px;color:green; cursor:pointer">Click to show the CSS Block</span>
<span data-id="js" onClick="contentShow(this)" style="margin-right:10px;color:blue; cursor:pointer">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
you are binding a second event handler to the switcheroo element, but the click event is not triggered so nothing happens.
If you want to make a toggle function on the switcheroo variable, you should do this instead:
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
return toggleDisplay(switcheroo);
}
function toggleDisplay(elem) {
if (elem.style.display === "none") {
elem.style.display = "";
} else {
elem.style.display = "none";
}
}
Ignoring your other bad practices, change
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
to something more like:
var doc = document;
function E(id){
return doc.getElementById(id); // you guessed it - same as document.getElementById, without typing it every time
}
var htm = E('htm'), css = E('css'), js = E('js');
contentShow = (function(){ // self-executing scopes off var showing - variable style assignment requires function definition before execution
var showing = false;
return function(){ // returns unexecuted function
var ht = E('ht').style, cs = E('cs').style, jsc = E('jsc').style;
if(showing){
ht.display = cs.display = jsc.display = 'none'; showing = false;
}
else{
ht.display = cs.display = jsc.display = 'block'; showing = true;
}
}
})();
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
See updated JSFiddle here.
If there are no other click Events on those Elements, you could even change
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
to
htm.onclick = css.onclick = js.onclick = contentShow;
JSFiddle here
but keep in mind this technique overwrites previous Events of the same type.
Here is a variation of #K Scandrett answer which add some scalability/flexibility
var navElements = document.getElementsByClassName("nav");
//Add Event Listeners
for(var i = 0; i < navElements.length; i ++)
{
navElements[i].addEventListener('click', contentShow, false);
}
function contentShow(el) {
var whichOne = el.target.attributes["data-id"].value;
var target = document.getElementById(whichOne);
for(var i = 0; i < navElements.length; i ++)
{
var content = document.getElementById(navElements[i].attributes["data-id"].value)
content.style.display = content === target ? "block" : "none";
}
}
<span data-id="htm" style="margin-right:10px;color:red; cursor:pointer" class="nav">Click to show the HTML Block</span>
<span data-id="css" style="margin-right:10px;color:green; cursor:pointer" class="nav">Click to show the CSS Block</span>
<span data-id="js" style="margin-right:10px;color:blue; cursor:pointer" class="nav">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
I know you're looking for a javascript solution here.and kudos to you for wanting to understand javascript before getting into jquery, but here is an out of the box solution for you.... pure HTML and CSS
.info {display:none;}
.info:target{display:block;}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div id="htm" class="info">Some HTML info here</div>
<div id="css" class="info">Some CSS info here</div>
<div id="js" class="info">Some JavaScript info here</div>
What I've done here is, leverage internal page id links and the :target selector. In my mind, this is more semantic and can also still be extended by scripting while still maintaining semantics. This option also gives your uses the option of bookmarking selections etc.
CSS OPTION 2
This option achieves the initial display. It is not as clean and uses absolute positioning and z-indexes. Alos note that is uses a background color to conceal the initial option.
.info {position:relative;}
.info > div {
position:absolute;
top:0;
left:0;
background-color:#FFF;
z-index:10;
display: none;
}
#htm
{
display:block;
z-index:1;
}
.info > div:target {
display: block;
}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div class="info">
<div id="htm">Some HTML info here</div>
<div id="css">Some CSS info here</div>
<div id="js">Some JavaScript info here</div>
</div>
On a side note you should consider adding/removing css classes using javascript instead of the display property directly. This will enable the use of CSS transitions.

Element becomes undefined

I created a simple library, and I'm trying to change the style of an element in the library. Very simple thing.
content[0].removeChild(content[0].firstElementChild);
content[0].style.backgroundColor = 'green';
I tried it in Chrome, and it works like a charm. I then tested it in Microsoft Edge and Internet Explorer, and they both don't recognize the element I'm trying to change.
They give the following error:
Unable to get property 'removeChild' of undefined or null reference
How can I fix this so that it works in all browsers?
codePen
function veryUsefullLibrary(parentElem) {
var outerWrapper = document.createElement('div'),
innerWrapper = document.createElement('div'),
content = parentElem.children;
function changeFunction(e) {
console.log(content);
content[0].removeChild(content[0].firstElementChild);
content[0].style.backgroundColor = 'green';
}
while (content.length)
innerWrapper.appendChild(content[0]);
content = innerWrapper.children;
var radio = document.createElement('input');
radio.type = 'radio';
radio.name = 'simSlider';
radio.addEventListener('change', changeFunction);
parentElem.appendChild(radio);
outerWrapper.appendChild(innerWrapper);
parentElem.appendChild(outerWrapper);
}
var overall = document.getElementById('overall'),
lib = new veryUsefullLibrary(overall);
#first {
width: 500px;
height: 386px;
}
<div id="overall">
<div class="content" id="first">
<img src="https://verkoren.files.wordpress.com/2013/05/junk-dump-22918.jpg" />
</div>
</div>
This seems to make it work.
function changeFunction(e) {
content = innerWrapper.children;
console.log(content);
content[0].removeChild(content[0].firstElementChild);
content[0].style.backgroundColor = 'green';
}

Create div above other div only with javascript

I need create a div above another div, but I dont have access to the css file, thus everything needs to be done via JavaScript.
This is my wrong code:
var div = document.getElementById("down");
var divAbove = document.createElement("div");
divAbove.id = "up";
divAbove.style.background = "red";
divAbove.style.position = "absolute";
divAbove.style.width = "150px"
div.appendChild(divAbove );
I can't see the new div.
If you can pinpoint the container element you can make use of .insertBefore()
More Info (docs)
var container = document.getElementById("container");
var div = document.getElementById("down");
var divAbove = document.createElement("div");
divAbove.id = "up";
divAbove.style.backgroundColor = "red";
divAbove.style.width = "110px"
divAbove.style.height = "60px"
divAbove.innerHTML = "Added via JS"
container.insertBefore(divAbove, div);
<div id='container'>
<div id='down' style='height: 60px; width: 110px; background-color: yellow'>
Existing element
</div>
</div>
This work.
var div = document.getElementById("down");
var divAbove=document.createElement("div");
divAbove.id = "up";
divAbove.style.background = "red";
divAbove.style.position = "absolute";
divAbove.style.width = "150px";
divAbove.style.height= "150px";
div.appendChild(divAbove);
From this point I would say that the div is there, but due to a typo in divAbov.style.background = "red"; it does not have a visible background. Try fixing the typo.
If the problem persists, please post your console log if there is any errors in there.
The reason you can't see new div is that you didn't give any body to it. For example, it may be a case to write before appending divAbove the following:
divAbove.innerHTML = "Hello World";

Categories

Resources