HTML:
<li><textarea></textarea></li><br><a id="newPoints"></a>
<input type="button" value="+ Add new point" onclick="newPoint();">
CSS (if you need it):
textarea {
font-family: Georgia, 'Times New Roman', Times, serif;
vertical-align: text-top;
width: 300px;
height: 60px;
resize: vertical;
padding: 10px;
}
And Javascript:
function newPoint() {
var a = document.getElementById("newPoints");
a.innerHTML += '<li><textarea placeholder="To delete this point, select this textbox and press the "Delete" button on your keyboard." onkeydown="if(event.keyCode == 46) { this.parentNode.nextSibling.parentNode.removeChild(this.parentNode.nextSibling); this.parentNode.parentNode.removeChild(this.parentNode); }"></textarea></li><br>';
}
To better visualise, here's a fiddle.
So basically, with the code above, I'm trying to make it such that when the user clicks on the button, a new <li> (that comes with a <br> after it) that contains a <textarea> will get created. This new <li>, <textarea> and the following <br> will be deleted when the user presses the Delete button on their keyboard while selecting the textarea.
The problem is that, when the user creates a new <li> and types some text into its textarea, then create another <li>, the text from the textarea of the previous <li> will disappear.
How can I fix this?
Use CreateElement and appendChild to add the elements. I think what is happening is when you append to the innerHTML, it is overwriting everything in newPoints.
function newPoint() {
var a = document.getElementById("newPoints");
var l = document.createElement("li");
l.innerHTML = '<textarea placeholder="To delete this point, select this textbox and press the "Delete" button on your keyboard." onkeydown="if(event.keyCode == 46) { this.parentNode.nextSibling.parentNode.removeChild(this.parentNode.nextSibling); this.parentNode.parentNode.removeChild(this.parentNode); }"></textarea>';
var b = document.createElement("br");
a.appendChild(l);
a.appendChild(b);
}
http://jsfiddle.net/MzENe/1/
This might help:
function newPoint() {
var a = document.getElementById("newPoints");
var newcontent = document.createElement('li');
newcontent.innerHTML = "<textarea placeholder='To delete this point, select this textbox and press the "Delete" button on your keyboard.' onkeydown=\"if(event.keyCode == 46) { this.parentNode.parentNode.removeChild(this.parentNode);}\"></textarea>";
a.appendChild(newcontent);
}
Related
On clicking a button, I want an input element to get focus. When the input element looses focus, I want the button to receive focus. Here is a simple example.
<body>
<button id="b1"
onclick="document.getElementById('i1').focus();">1</button>
<input id="i1" type="text"
onblur="document.getElementById('b1').focus();"/>
<button id="b2"
onclick="document.getElementById('i2').focus();">2</button>
<input id="i2" type="text"
onblur="document.getElementById('b2').focus();"/>
</body>
When I click any of the buttons, the input element gets focus. This works as desired. When I leave any of the two inputs by clicking on the canvas, the focus does not go to the button. This is my main issue.
When I leave the first input with tab, all browsers pass the focus to the first button. But when I leave the second button with tab, only firefox passes the focus to the second button. Chrome and opera don't show a focus. I am puzzled as to why the second button is treated differently.
You don't need to use JavaScript. HTML and CSS is enough. Use label tag and convert it's look like button. :)
label.btn{
-webkit-appearance: button;
-moz-appearance: button;
appearance: button;
padding: 1px 6px;
border:1px solid
}
<label class="btn" for="i1" id="b1">1</label>
<input id="i1" type="text"/>
<label class="btn" for="i2" id="b2">2</label>
<input id="i2" type="text" />
If you add a :focus style in your CSS, you can see it works fine. I've moved your JS out of the HTML markup for visibility and added some listeners for keyboard users.
Caution: Forcing focus back to the button interferes with the page's natural flow, so I probably wouldn't advise unless you have it attached to some input validation that fires when needed; else, how do keyboard users move to the next element?
const inputOne = document.getElementById('i1');
const btnOne = document.getElementById('b1');
const inputTwo = document.getElementById('i2');
const btnTwo = document.getElementById('b2');
// Listen for click to button one
btnOne.addEventListener('click', function() {
inputOne.focus();
})
// Make sure we listen for keyboard users
btnOne.addEventListener('keydown', function(event) {
if(event.keyCode === 90) {
inputOne.focus();
}
})
// Leaving input one
inputOne.addEventListener('blur', function() {
btnOne.focus();
})
// Listen for click to button two
btnTwo.addEventListener('click', function() {
inputTwo.focus();
})
// Make sure we listen for keyboard users
btnTwo.addEventListener('keydown', function(event) {
if(event.keyCode === 90) {
inputTwo.focus();
}
})
// Leaving input two
inputTwo.addEventListener('blur', function() {
btnTwo.focus();
})
:focus {
border: 1px solid red;
}
<button id="b1">1</button>
<input id="i1" type="text"/>
<button id="b2">2</button>
<input id="i2" type="text" />
I'm trying to find a way to modify the value of my lightning-textarea.
Not the variable that holds the value internally.
Things like document.getElementById('textarea').value = 'value'; are not working.
My Textarea:
<lightning-textarea id="textarea" type="text" label="Enter some text" onchange={handleInputChange}></lightning-textarea>
Thanks!
In the solution below, clicking the item changes its content. The Element.innerHTML property or the Element.insertAdjacentHTML() method can be used to change the content of the element.
let textarea = document.getElementById("textarea");
let textarea2 = document.getElementById("textarea2");
/* Clicking on the item fires the following event. */
textarea.addEventListener('click', function(event) {
textarea.innerHTML = "Clicked First Element";
});
/* Clicking on the item fires the following event. */
function clickEvent() {
try {
this.textarea2.innerHTML = "Clicked Second Element";
}
catch(error) {
console.log(error);
}
}
#textarea, #textarea2 {
border: 1px solid red;
padding: 10px;
}
<!-- First Element -->
<br><lightning-textarea id="textarea" type="text" label="Enter some text">First</lightning-textarea><br><br><br>
<!-- Second Element -->
<lightning-textarea id="textarea2" type="text" label="Enter some text" onclick="clickEvent()">Second</lightning-textarea>
When I have focus on the input field and I click in any open area of the body, the body becomes the document.activeElement , Is there a way to prevent the body focus completely.
What I am looking for is :
To prevent focus the body and maintain focus on the input field.
To avoid the firing of the blur event on the input field.
I've tried adding tabindex=-1 but I believe its for Tab functionality and hence does not work in this case.
document.querySelector("#inpdontlosefocus")
.addEventListener("blur",function(){
const $log = document.querySelector("#log");
$log.innerText += "\r\nLost focus";
})
html,body {
width:100vw;
height: 100vh;
}
<body id="notokaytogetfocus">
<input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">
<input id="inpokaytofocus" type="" placeholder="allow focus">
<div id="log"></div>
</body>
Here is a solution that will always keep the focus on input fields in your document:
you will be able to switch the focus between input fields.
if you clicked outside an element that is not input, it will get the lastest input blurred and will apply focus on it.
var blurred, focused;
const $log = document.querySelector("#log");
var els = document.querySelectorAll('input');
Array.prototype.forEach.call(els, function(el) {
el.addEventListener('focus', function() {
focused = this;
});
el.addEventListener('blur', function() {
$log.innerText += "\r\nLost focus;"
blurred = this;
});
});
document.addEventListener("click", function(e) {
e.preventDefault();
if (focused && focused.tagName == "INPUT") {
$log.innerText += "\r\nactiveElement= " + document.activeElement.id;
focused.focus();
} else if (blurred) blurred.focus();
})
html,
label {
width: 100%;
height: 100%;
}
<body id="notokaytogetfocus">
<input id="inpdontloosefocus" placeholder="dont loose focus to body">
<input id="inpokaytofocus" placeholder="allow focus">
<div id="log"></div>
</body>
I'd added more html elements for a more accurate demonstration, the logic here is if the event source in body is not focus-able then we set focus back to the input we want, other wise the its a focusable element thus will get the focus(e.g. button, link, input, ...); notice that click event is attached to body and clicking outside body won't have this behavior.
document.querySelector('.notokaytogetfocus').addEventListener("click",function (e){
if(e.target == document.activeElement){
console.log("focusable element");
}else{
console.log("not focusable element");
// we'll set foucs on desired input
document.querySelector("#inpdontlosefocus").focus()
}
})
.notokaytogetfocus{height: 100vh; width:100vw;}
<div class="notokaytogetfocus">
<input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">
<input id="inpokaytofocus" type="" placeholder="allow focus">
<button>do!(focusable)</button>
<p>lorem ipsum</p>
<div>some text</div>
</div>
I have some code that seems to be working, but in a rather odd fashion. When I first refresh the page I have the close button that seems to work fine, but when I make a new to-do list item the close button seems to cease working and I can't pinpoint why.
let addItem = document.getElementById("submitButton");
let userInput = document.getElementById("toDoInput");
let output = document.getElementById("output");
let toDoItem = document.querySelector(".toDoItem");
let close = document.querySelector(".close");
let toDo = document.querySelector(".todo");
/*User clicked the addItem Button
If there is any text inside the text field then add that text to the todo list */
addItem.addEventListener("click", addToDo);
function addToDo(){
var html = `
<ul class="todo">
<li class="toDoItem">
<p>${userInput.value}</p>
<div class="close">X</div>
</li>
</ul>
`;
output.innerHTML += html;
// Resetting input to blank once a submit button has been added.
userInput.value = '';
}
// Figure out how to make closing functionality simple this implementation
// isn't working
close.addEventListener("click", function(e){
console.log("clicked");
let x = e.target.parentElement;
x.style.display = "none";
e.preventDefault();
});
<header>
<input type="text" placeholder="Enter Item Here..." id="toDoInput">
<button id="submitButton">+</button>
</header>
<section id="output">
<ul class="todo">
<li class="toDoItem">
<p>Clean Room!</p>
<div class="close">X</div>
</li>
</ul>
</section>
<script src="todo.js"></script>
I'm also not sure if I'm using best practice as I'm new to web development, so any tips would be thoroughly appreciated as well!
You need a live event handler on your close button(s). This example should help. To offer something more, it's easier and more straight forward to use jQuery for it if you can and don't mind using a JS library.
jQuery example:
$(document).on("click", ".close", function() {
$(this).parent().hide();
});
No need to prevent default behavior since it's a div.
The issue here is that when you re-render the content of the "output" section you lose the event listener bound to the original ".close" element. A few options to work around the issue, have a look at this thread for some examples.
You got pretty close man, and you definitely do not need jQuery.
As you can see below, you don't need to push the <ul> dynamically. It will never change!
<header>
<input type="text" placeholder="Enter Item Here..." id="toDoInput">
<button id="submitButton">+</button>
</header>
<section id="output">
<ul class="todo">
</ul>
</section>
And here is your refactored javascript:
let addItem = document.getElementById("submitButton");
let userInput = document.getElementById("toDoInput");
let output = document.getElementById("output");
let toDoItem = document.querySelector(".toDoItem");
let toDo = document.querySelector(".todo");
/*User clicked the addItem Button
If there is any text inside the text field then add that text to the todo
list */
addItem.addEventListener("click", addToDo);
function addToDo(e){
e.preventDefault();
var html = `<li class="toDoItem">
<p>${userInput.value} </p> <p class="close"
onclick="removeChildElement(this);">X</p>
</li>`;
output.innerHTML += html;
let close = document.querySelector(".close")
// Resetting input to blank once a submit button has been added.
userInput.value = '';
}
// Figure out how to make closing functionality simple this implementation
// isn't working
function removeChildElement(e) {
let x = e.parentElement;
let xParent = x.parentElement;
xParent.removeChild(x);
console.log(xParent);
}
As you can see i made a few changes. Most importantly your close button issue. The function gets the parent on its parent ( ^ 2 ) and then removes its child. Which would be your <li> element!
Enjoy the fiddle: https://jsfiddle.net/fjbyy6uw/35/
Use Event Delegation. Details are commented in Demo. Added a <form> so HTMLFormControlsCollection API can be used, it's simpler, less writing, and I'm lazy.
/* All form controls are referenced by HTMLFormControlsCollection */
var form = document.forms.toDo;
var td = form.elements;
var add = td.add;
var inp = td.input;
var out = td.output;
var toDo = document.querySelector('.toDo');
add.addEventListener("click", addToDo);
/* Limited the dynamically created node to `<li>`. It doesn't make sense to
|| have several `<ul>` having only one `<li>` each.
*/
function addToDo() {
var html = `
<li class="item">
<span>${inp.value}</span>
<b class="close">X</b>
</li>
`;
toDo.innerHTML += html;
}
/* Event Delegation is a way of leveraging event bubbling so
|| that a single ancestor node can be registered to listen for
|| an event (e.currentTarget) and by means event propagation
|| (bubbling) can locate the event origin (node clicked/e.target).
|| In this demo e.currentTarget is output#output and e.target are
|| any b.close. This was possibble by using e.target in conditions
*/
/* removeChild() is used because display:none is not entirely
|| gone. The markup remains just not in the DOM, so it may not
|| look like it's there, under certain conditions a node could be
|| considered present.
*/
out.addEventListener("click", function(e) {
if (e.target !== e.currentTarget) {
if (e.target.className === "close") {
let x = e.target.parentElement
x.parentElement.removeChild(x);
}
}
});
.item {
display: flex;
max-width: 250px;
justify-content: space-between;
}
.item span,
.item b {
display: table-cell;
}
.item b {
cursor: pointer
}
input,
output,
button {
font: inherit
}
<form id='toDo'>
<header>
<input type="text" placeholder="Enter Item Here..." id="input">
<button id="add" type='button'>+</button>
</header>
<output id="output">
<ul class="toDo">
<li class="item">
<span>Clean Room!</span>
<b class="close">X</b>
</li>
</ul>
</output>
</form>
I want to make a popup text box that shows source codes from the textarea in the popup as a web page wile at the same time it will not show the print button codes in the textarea because that text is meant to be as functions for the popup only. As you can see my textarea content has both javascript and html who needs to be hidden from the textarea, but at the same time needs to be inside the text area for the popup to work.
This means I can not put them outside the textarea because then that function will not show in the popup window who will show everything that is in the textarea of the web editor editor unless the popup is made to target a div that holds the textarea and and not the textarea directly. Even so that presents a problem as the textarea will not anymore be converted into a web page when getting the popup.
I am using this textarea for my popup:
<textarea name="textfield" cols="107" rows="31" id="CodeExample" wrap="soft" style="font-size:12px; font-family: Arial, Helvetica, sans-serif; color:#ffffff; background-color:rgba(0,0,0,0.8); resize: none;" placeholder="The is Source Codes here"><script language="Javascript">
function printit(){
if (NS) {
window.print() ;
} else {
var WebBrowser = '<OBJECT id="WebBrowser1" width=0 height=0 CLASSid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
document.body.insertAdjacentHTML('beforeEnd', WebBrowser);
WebBrowser1.ExecWB(6, 2);//Use a 1 vs. a 2 for a prompting dialog box WebBrowser1.outerHTML = "";
}
}
</script>
<script language="Javascript">
var NS = (navigator.appName == "Netscape");
var VERSION = parseInt(navigator.appVersion);
if (VERSION > 3) {
document.write('<form><input type=button value="Print this Page" name="Print" onClick="printit()" style="margin-bottom: 0px; font: bold 11px Arial, Sans-Serif;"></form>');
}
</script></textarea>
<br>
<!-- Run Textarea field in popup BEGIN -->
<script type="text/javascript">
var win = null;
function NewWindow(mypage,myname,w,h,scroll) {
LeftPosition = (screen.width) ? (screen.width-w)/2 : 0;
TopPosition = (screen.height) ? (screen.height-h)/2 : 0;
settings =
'height='+h+',width='+w+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scroll+',resizable'
win = window.open(mypage,myname,settings);
if (window.focus) {win.focus()}
var t = document.form1.textfield.value;
win.document.write(t);
}
</script>
<input type = "button" value = "Preview" name = "preview" onclick = "NewWindow('','myPop','500','400','yes')">
<!-- Run Textarea field in popup END -->
So now what I want is for the print button codes to not be visible in the textarea, but that they are visible as a print button when the popup button is run. So that the print button adds to the visible source codes added into the box by the web designer.
UPDATE
When I posted this question I found no answer no were on the entire internet.
After fiddling with it for a long time I posted the question here. And by luck I found an answer of how to do it after a few minute of after posted the question. I will not delete the question since I am the FIRST on the internet to find and answer to this question.
Solution:
I solved the problem by simply making a hidden textarea linked to the input popup javascript who is also linked to the visible textera. That way what ever is put inside the visble textarea will come up in the popup and so will also the function from hidden in the hidden textarea come on the same popup when clicked on the "Preview" button.
You can put any HTML, CSS or JavaScript code inside the visible and inside the hidden textarea wile having all the input codes hidden from the visible textarea it but active when the popup is turned on.
<form name = "form1">
<textarea name="textfield" cols="107" rows="31" id="CodeExample" wrap="soft" style="font-size:12px; font-family: Arial, Helvetica, sans-serif; color:#ffffff; background-color:rgba(0,0,0,0.8); resize: none;" placeholder="Put your Source Codes here">
</textarea>
<textarea hidden="on" name="textfield2" cols="1" rows="1" id="CodeExample2">
<script language="Javascript">
function printit(){
if (NS) {
window.print() ;
} else {
var WebBrowser = '<OBJECT id="WebBrowser1" width=0 height=0 CLASSid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
document.body.insertAdjacentHTML('beforeEnd', WebBrowser);
WebBrowser1.ExecWB(6, 2);//Use a 1 vs. a 2 for a prompting dialog box WebBrowser1.outerHTML = "";
}
}
</script>
<script language="Javascript">
var NS = (navigator.appName == "Netscape");
var VERSION = parseInt(navigator.appVersion);
if (VERSION > 3) {
document.write('<form><input type=button value="Print this Page" name="Print" onClick="printit()" style="margin-bottom: 0px; font: bold 11px Arial, Sans-Serif;"></form>');
}
</script>
</textarea>
<br>
<!-- Run Textarea field in popup BEGIN -->
<script type="text/javascript">
var win = null;
function NewWindow(mypage,myname,w,h,scroll) {
LeftPosition = (screen.width) ? (screen.width-w)/2 : 0;
TopPosition = (screen.height) ? (screen.height-h)/2 : 0;
settings =
'height='+h+',width='+w+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scroll+',resizable'
win = window.open(mypage,myname,settings);
if (window.focus) {win.focus()}
var t1 = document.form1.textfield.value;
var t2 = document.form1.textfield2.value;
win.document.write(t1);
win.document.write(t2);
}
</script>
<input type = "button" value = "Preview" name = "preview" onclick = "NewWindow('','myPop','500','400','yes')">
<!-- Run Textarea field in popup END -->
</form>
NOTE:
If you are making a web editor online as I am with preview function then it all of a sudden it is making sense. Because you will want to preview your codes that you text inside the textarea box and when previewing you will also want that the textarea box shows some extra buttons such as print the preview you made. Perfect to test a design or a page and such and then print it out by the click of one button on the popup generated by the textarea box. Look at the solution I found and test it yourself and see what I mean and why. It will work with any HTML, CSS and JS source codes.
Test it yourself if you do not understand why it was needed and how it works.