I want to replace an element by another.
The element however is placed in an div with other elements.
When I run my code the whole div is replaced.
How do I prevent this behavior?
function edit(e) {
selectedElement = e.id
var newElement = document.createElement("input");
var newElementA = document.createTextNode("bla");
newElement.appendChild(newElementA);
var oldElement = document.getElementById(selectedElement);
var parentDiv = oldElement.parentNode
parentDiv.replaceChild(newElement, oldElement);
}
You shouldn't be appending a text node to an input box. You should set the value.
Here is a working codepen, based on your comments.
<div id="parentDiv">
<div>
hi
</div>
<a id="pleaseReplace" onclick="edit(event)">hi2</a>
<div>
hi3
</div>
</div>
function edit(e) {
selectedElement = document.getElementById(e.srcElement.id);
var newElement = document.createElement("input");
newElement.value = selectedElement.innerHTML;
var parentDiv = selectedElement.parentNode
selectedElement = parentDiv.replaceChild(newElement, selectedElement);
}
Related
Pardon the bad title, it's hard to explain. If you know how to phrase it better, please comment and I will update as soon as I can.
So, I was messing around with a random generator site (perchance.org) and writing my own HTML/Javascript to make my generator work. It has a behavior that is what I want, but that shouldn't be happening according to my knowledge of HTML.
Let me explain with a minimal example.
The example code here is to produce a simple page that has a button.
This button should generate <input>s with <button>s next to them, attached with similar ID's.
The button, when clicked, deletes the <input> and <button>.
Here is a snippet to show you the code/let you reproduce the results:
<html>
<head>
<script>
var current_id = 0;
function add_input () {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + current_id;
delete_button.id = "button_" + current_id;
br.id = "br_" + current_id;
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.onclick = function () {
delete_input(this.id.slice(7)) //To get the numerical ID
}
list.appendChild(input);
list.appendChild(delete_button);
list.appendChild(br);
current_id++;
}
function delete_input (id) {
var input = document.getElementById("input_"+id);
var button = document.getElementById("button_"+id);
var br = document.getElementById("br_"+id);
input.remove();
button.remove();
br.remove();
current_id--;
}
</script>
</head>
<body>
<div id="list">
</div>
<button onclick="add_input()">Add</button>
</body>
</html>
When you add two inputs, then delete the first, and add one more, it leaves you with two inputs using the same ID. It also leaves you with two buttons with the same ID. And yet, both buttons delete their intended target.
Why?
You really should delegate - here I wrap in a div that can be removed in one go
You can rename each input to have incremented IDs but just letting the cnt run, gives you unique IDs
let cnt = 0;
function add_input() {
var list = document.getElementById("list");
var div = document.createElement("div");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + (cnt++)// list.querySelectorAll("div").length
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.classList.add("delete")
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div);
}
window.addEventListener("load", function() {
document.getElementById("list").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("delete")) tgt.closest("div").remove();
})
})
<div id="list">
</div>
<button onclick="add_input()">Add</button>
I changed your code to be more effective.
I'm not using IDs as they aren't adding any benefit instead making it more complex.
Instead I target the element via the event handler and an argument.
I also wrap each set of inputs/buttons in a div so I can just remove that div and it will remove all of the children.
function add_input() {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
delete_button.textContent = "Delete";
delete_button.onclick = function(e) {
e.target.parentNode.remove();
}
var div = document.createElement("div");
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div)
}
<div id="list">
</div>
<button onclick="add_input()">Add</button>
There is html on the screen that looks like this.
screen:
target1 target2 target3 target4
code:
<div>
target1
<span>target2</span>
<span>target3</span>
target4
</div>
When i click on target4,
I want to get the text "target4"
How do you approach it?
This answer both questions you had
var div = document.querySelector("div"); // get the div wrapper
div.childNodes.forEach(function(node) { // loop over the nodes
var text = node.textContent; // get the text
if (node.nodeName=="#text" && text.trim()!="") { // if text and not empty
var span = document.createElement("span"); // wrap in a span
span.textContent = node.textContent.trim();
node = div.replaceChild(span,node);
}
});
div.onclick=function(e) {
console.log(e.target.textContent);
}
span { color:red }
<div>
target1
<span>target2</span>
<span>target3</span>
target4
</div>
you can get the value of your last text node, this is not a problem. Unfortunately :
childNodes may include text nodes, which don't support event handlers
var x = document.getElementsByTagName("div")[0];
x.addEventListener("click",function(e){
console.log(e.currentTarget.childNodes[4].textContent)});
<div>
target1
<span>target2</span>
<span>target3</span>
target4
</div>
scraaapy has answered your question. But if you have the control over the HTML, then just do this:
HTML
<div>
<span>target1</span>
<span>target2</span>
<span>target3</span>
<span>target4</span>
</div>
JavaScript
var el = document.querySelector("div");
el.addEventListener("click", (e) => {
console.log(e.target.textContent);
});
This way, your code is much easier to maintain and work with. Hope this help!
I have some id div with elements(classes and Ids), I need to clone it and append to my clone new class. How can I do it?
window.onload = Func ();
function Func () {
var temp = document.getElementById("start");
var cl = temp.cloneNode(true);
var div = document.createElement('div');
div.className = "class";
div.innerHTML = "MyText";
var result = cl.getElementById("second").append(div);
alert(result.innerHTML);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="start">
<div id="second">
Link
</div></div>
use following code
$(function(){
var $Div = $('.start').clone();
$('.second').html($Div);
});
Using JQuery,
var clone = $("#divName");
or var clone = $(".className")
var secondDiv = $("#secondDiv");
or var secondDiv = $(".secondDivClassName");
//Or you can get the html of your second div like this:
var myHtml = secondDiv.html(); //if you don't give any parameter, it takes the inner html of the given element.
//and finally insert your html into the clone like this :
clone.html(myHtml);// in this case, the html() methode takes a parameter and inserts the given parameters into the given element.
You should reference JQuery to your page.
Tell me if it works.
I need a function which creates element and than adds text to that element and than adds that new element to a some location in DOM. I am noob to this.
I find this function but I don't know how to automaticaly specify location so that I can just call function and for example specify third argument as an element to which I want to append new element.
function appendElement (elemNode,textNode) {
var element = document.createElement(elemNode);
var text = document.createTextNode(textNode);
element.appendChild(text);
document.body.appendChild(element);
}
appendElement("b","lorem");
function appendElement (elemNode,textNode,containerToAppend) {
var container = document.getElementById(containerToAppend);
var element = document.createElement(elemNode);
var text = document.createTextNode(textNode);
element.appendChild(text);
container.appendChild(element);
}
appendElement("b","lorem","ContainerId");
Here's a way to do it in one line:
function appendElement (elemNode, textContent, parent) {
parent.appendChild(document.createElement(elemNode)).textContent = textContent;
}
appendElement("b","lorem", document.getElementById("container"));
div { background-color: aqua }
<div id="container"></div>
function appendElement (elemNode,textNode,containerToAppend) {
var container = document.getElementById(containerToAppend);
var element = document.createElement(elemNode);
var text = document.createTextNode(textNode);
element.appendChild(text);
container.appendChild(element);
}
appendElement("p","this is text","ContainerId");
Here is my attempt. Completely ripped off from developer.Mozilla.org with a minor tweak.
JSFIDDLE DEMO
Javascript:
function addElement() {
// Create a new div element and give it some content
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hi there and greetings!");
newDiv.appendChild(newContent); //Add the text node to the newly created div.
// Add the newly created element and its content into the Parent of the clicked button
var parentDiv = event.target.parentNode;
document.body.insertBefore(newDiv, parentDiv);
}
HTML
<div id="div1">
<input type="button" onclick="addElement(event)" value="Click me to add div" />
</div>
<div id="div2">
<input type="button" onclick="addElement(event)" value="Click me to add div" />
</div>
<div id="div3">
<input type="button" onclick="addElement(event)" value="Click me to add div" />
</div>
I'm building a submission form for a static blog. The form is located here:
https://archwomen.org/blog/submit
I have a markdown preview, but I would also like to have an html preview.
Here is the idea:
When someone clicks on the "html" button, I need this html markup:
<div id="preview"></div>
To get changed to this:
<textarea readonly id="preview"></textarea>
And when someone clicks on the "live" button, I want the html markup to get changed back. I was hoping to do this with pure javascript but so far I haven't had much luck. I setup a jsfiddle here:
http://jsfiddle.net/Lc2Yg/
function transformTag(tagId){
var elem = document.getElementById(tagId);
var children = elem.childNodes;
var parent = elem.parentNode;
var newNode = document.createElement("textarea readonly id="preview"");
for(var i=0;i<children.length;i++){
newNode.appendChild(children[i]);
}
parent.replaceChild(newNode,elem);
}
Any help will be greatly appreciated.
Try
window.transformTag = function(type, tagId){
var elem = document.getElementById(tagId), newNode;
var children = elem.childNodes;
var parent = elem.parentNode;
if(type == 'input'){
newNode = document.createElement("textarea");
newNode.readOnly = true;
newNode.value = elem.innerHTML;
} else {
newNode = document.createElement("div");
newNode.readOnly = true;
newNode.innerHTML = elem.value;
}
newNode.id = tagId;
parent.replaceChild(newNode, elem);
}
Demo: Fiddle
jQuery: how to change tag name?
http://www.webmaster-talk.com/javascript-forum/71713-changing-a-tag-one-element-another.html
Better create two elements and switch their visibility.
I've changed the code a little bit: http://jsfiddle.net/Lc2Yg/2/
function transformTag() {
var elem = document.getElementById('preview');
var edited_area = document.getElementById('text-input');
var parent = elem.parentNode;
var newNode = document.createElement("textarea");
newNode.rows = 25
newNode.cols = 25
newNode.readOnly = true
newNode.value = edited_area.value
parent.replaceChild(newNode,elem);
}