I have the following code:
<div class="className" id="div-1" onClick="selPic(this.id);">
<span>some text</span>
</div>
<div class="className" id="div-2" onClick="selPic(this.id);">
<span>some text</span>
</div>
<div class="className" id="div-3" onClick="selPic(this.id);">
<span>some text</span>
</div>
I'd like to give the span of the clicked element some styling but I'd prefer to use the parent element's id for reference rather than giving each span an id as well.
I have tried this, but it doesn't work:
function selPic(id) {
document.getElementById(id).childNone[0].style.opacity = "1";
}
Any ideas?
Access to the element 1 of childNodes (not childNode) array to modify the span opacity:
document.getElementById(id).childNodes[1].style.opacity = "1";
Just correct the typos in your code:
function selPic(id) {
document.getElementById(id).childNodes[0].style.opacity = "1";
}
Replace childNone with childNodes.
function selPic(id) {
document.getElementById(id).childNodes[0].style.opacity = "1";
}
It should be childNodes not childNode:
function selPic(id) {
document.getElementById(id).childNodes[0].style.opacity = "1";
}
Also, habituate to use return the function:
function selPic(id) {
var ss = document.getElementById(id).childNodes[0].style.opacity = "1";
return ss;
}
You have a bit of error code
function selPic(id) {
document.getElementById(id).childNodes[0].style.opacity = "1";
}
Your idea of selecting a child node by index number will not work in general. That's because you cannot know for sure what number the span element will have. Depending on how you built the list, there may be invisible child nodes, such as whitespace text nodes, before the span that interests you. That's why you were surprised to find that you had to use index value 1 rather than 0.
A more robust approach is to call getElementsByTagName('span') on the parent element to retrieve all the spans inside it. Then get the first item in the returned array.
In addition, I suggest that the argument to the function should be the element you want to highlight and not just the ID of the element. If you follow my suggestion, your HTML would look like this:
<div class="className" id="div-1" onClick="selectPicture(this);">
<span>some text</span>
</div>
<div class="className" id="div-2" onClick="selectPicture(this);">
<span>some text</span>
</div>
<div class="className" id="div-3" onClick="selectPicture(this);">
<span>some text</span>
</div>
And the function would look like this:
function selectPicture(container) {
container.getElementsByTagName('span')[0].style.opacity = 1;
}
It would be even better to implement the style change by modifying the className of the span and writing appropriate CSS, but I'll leave those considerations up to you.
Related
<div>
<br>
<br>
<br>
</div>
I have an HTML page that has the above div element in it. How can I scan the page an look for a DIV that contains specific items? In this example I know I have three <br> in a row and that's it. The DIV element does not have a class or an ID, and I would like to delete it.
You can target elements in a row by using the sibling selector, +. You can make sure the target elements are a direct child of the div by using the > selector.
You can find the div that contains the three br elements like so:
document.querySelector('div > br + br + br').parentNode;
To remove this element from the DOM use the remove method.
const elToDelete = document.querySelector('div > br + br + br')?.parentNode;
elToDelete?.remove();
Edit:
Added optional chaining syntax to the answer to show how to prevent undefined errors from being thrown.
You can use the :has pseudo-class to select the div directly
var elem = document.querySelectorAll("div:has(>br+br+br)");
console.log([...elem])
elem.forEach(x=>x.remove())
<div id=a> a
<br/>
<br/>
<br/>
</div>
<div id=b> b
<br/>
<br/>
</div>
<div id=c> c
<br/>
<br/>
<not-br/>
<br/>
</div>
You can try this:
[].slice.call(document.getElementsByTagName("div")).forEach(function(div){
var count = 0;
if(div.children.length === 3)
[].slice.call(div.children).forEach(function(br, i){
if(br.nodeName === "BR")
count++;
});
if(count > 2)
div.parentElement.removeChild(div);
});
You can just hide it with CSS
div:has(>br+br+br) {
display: none;
}
<div>1</div>
<div><br/><br/><br/></div>
<div>3</div>
Best solution that will work cross-browser is to tackle this programmatically. Note that :has() pseudo class doesn't work on Firefox, IE or Opera (see https://caniuse.com/css-has).
Here's a concise functional Javascript approach:
[].filter.call(document.querySelectorAll('div'), el => el.querySelectorAll('br').length === 3)
I'd like to update element's text dynamically:
<div>
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
I'm new to jQuery, so this task seems to be quite challenging for me.
Could someone point me to a function/selector to use?
If it is possible, I'd like to do it without adding a new container for the text I need to change.
Mark’s got a better solution using jQuery, but you might be able to do this in regular JavaScript too.
In Javascript, the childNodes property gives you all the child nodes of an element, including text nodes.
So, if you knew the text you wanted to change was always going to be the first thing in the element, then given e.g. this HTML:
<div id="your_div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
You could do this:
var your_div = document.getElementById('your_div');
var text_to_change = your_div.childNodes[0];
text_to_change.nodeValue = 'new text';
Of course, you can still use jQuery to select the <div> in the first place (i.e. var your_div = $('your_div').get(0);).
Update 2018
Since this is a pretty popular answer I decided to update and beautify it a little by adding the textnode selector to jQuery as a plugin.
In the snippet below you can see that I define a new jQuery function that gets all (and only) the textNodes. You can chain of this function as well with for example the first() function.
I do a trim on the text node and check if it's not empty after the trim because spaces, tabs, new lines, etc. are also recognized as text nodes. If you need those nodes too then simple remove that from the if statement in the jQuery function.
I added an example how to replace first text node and how to replace all text nodes.
This approach makes it easier to read the code and easier to use it multiple times and with different purposes.
The Update 2017 (adrach) should still work as well if you prefer that.
As jQuery extension
//Add a jQuery extension so it can be used on any jQuery object
jQuery.fn.textNodes = function() {
return this.contents().filter(function() {
return (this.nodeType === Node.TEXT_NODE && this.nodeValue.trim() !== "");
});
}
//Use the jQuery extension
$(document).ready(function(){
$('#replaceAll').on('click', () => {
$('#testSubject').textNodes().replaceWith('Replaced');
});
$('#replaceFirst').on('click', () => {
$('#testSubject').textNodes().first().replaceWith('Replaced First');
});
});
p {
margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
**text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**also text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>
Javascript (ES) equivalent
//Add a new function to the HTMLElement object so it can be used on any HTMLElement
HTMLElement.prototype.textNodes = function() {
return [...this.childNodes].filter((node) => {
return (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() !== "");
});
}
//Use the new HTMLElement function
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#replaceAll').addEventListener('click', () => {
document.querySelector('#testSubject').textNodes().forEach((node) => {
node.textContent = 'Replaced';
});
});
document.querySelector('#replaceFirst').addEventListener('click', function() {
document.querySelector('#testSubject').textNodes()[0].textContent = 'Replaced First';
});
});
p {
margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
**text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**also text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>
Update 2017 (adrach):
It looks like several things changed since this was posted. Here is an updated version
$("div").contents().filter(function(){ return this.nodeType == 3; }).first().replaceWith("change text");
Original answer (Not working for current versions)
$("div").contents().filter(function(){ return this.nodeType == 3; })
.filter(':first').text("change text");
Source: http://api.jquery.com/contents/
See In action
Markup :
$(function() {
$('input[type=button]').one('click', function() {
var cache = $('#parent').children();
$('#parent').text('Altered Text').append(cache);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">Some text
<div>Child1</div>
<div>Child2</div>
<div>Child3</div>
<div>Child4</div>
</div>
<input type="button" value="alter text" />
Just wrap the text you want to change in a span with a class to select.
Doesn't necessarily answer your question I know, but, probably a better coding practice. Keep things clean and simple
<div id="header">
<span class="my-text">**text to change**</span>
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
Voilà!
$('#header .mytext').text('New text here')
<div id="divtochange">
**text to change**
<div>text that should not change</div>
<div>text that should not change</div>
</div>
$(document).ready(function() {
$("#divtochange").contents().filter(function() {
return this.nodeType == 3;
})
.replaceWith("changed text");
});
This changes only the first textnode
For the specific case you mentioned:
<div id="foo">
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
... this is very easy:
var div = document.getElementById("foo");
div.firstChild.data = "New text";
You don't state how you want to generalize this. If, say, you want to change the text of the first text node within the <div>, you could do something like this:
var child = div.firstChild;
while (child) {
if (child.nodeType == 3) {
child.data = "New text";
break;
}
child = child.nextSibling;
}
$.fn.textPreserveChildren = function(text) {
return this.each(function() {
return $(this).contents().filter(function() {
return this.nodeType == 3;
}).first().replaceWith(text);
})
}
setTimeout(function() {
$('.target').textPreserveChildren('Modified');
}, 2000);
.blue {
background: #77f;
}
.green {
background: #7f7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="target blue">Outer text
<div>Nested element</div>
</div>
<div class="target green">Another outer text
<div>Another nested element</div>
</div>
Simple answer:
$("div").contents().filter(function(){
return this.nodeType == 3;
})[0].nodeValue = "The text you want to replace with"
Here is yet another method : http://jsfiddle.net/qYUBp/7/
HTML
<div id="header">
**text to change**
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
JQUERY
var tmp=$("#header>div").html();
$("#header").text("its thursday").append(tmp);
Problem with Mark's answer is that you get empty textnodes aswell. Solution as jQuery plugin:
$.fn.textnodes = function () {
return this.contents().filter(function (i,n) {
return n.nodeType == 3 && n.textContent.trim() !== "";
});
};
$("div").textnodes()[0] = "changed text";
Lots of great answers here but they only handle one text node with children. In my case I needed to operate on all text nodes and ignore html children BUT PRESERVE THE ORDERING.
So if we have a case like this:
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
We can use the following code to modify the text only AND PRESERVE THE ORDERING
$('#parent').contents().filter(function() {
return this.nodeType == Node.TEXT_NODE && this.nodeValue.trim() != '';
}).each(function() {
//You can ignore the span class info I added for my particular application.
$(this).replaceWith(this.nodeValue.replace(/(\w+)/g,"<span class='IIIclassIII$1' onclick='_mc(this)' onmouseover='_mr(this);' onmouseout='_mt(this);'>$1X</span>"));
});
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
Here is the jsfiddle of it working
I think you're looking for .prependTo().
http://api.jquery.com/prependTo/
We can also select an element on the
page and insert it into another:
$('h2').prependTo($('.container'));
If an element selected this way is
inserted elsewhere, it will be moved
into the target (not cloned):
<div class="container">
<h2>Greetings</h2>
<div class="inner">Hello</div>
<div class="inner">Goodbye</div>
</div>
If there is more than one target
element, however, cloned copies of the
inserted element will be created for
each target after the first.
This is an old question but you can make a simple function like this to make your life easier:
$.fn.toText = function(str) {
var cache = this.children();
this.text(str).append(cache);
}
Example:
<div id="my-div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
Usage:
$("#my-div").toText("helloworld");
2019 vesrsion - Short & Simple
document.querySelector('#your-div-id').childNodes[0].nodeValue = 'new text';
Explanation
document.querySelector('#your-div-id') is used for selecting the parent (the element which text you are about to change)
.childNodes[0] selects the text node
.nodeValue = 'new text' sets text node value to "new text"
This answer is possibly inspired by Dean Martin's comment. Can't say for sure since I've been using this solution for years now. Just thought I should post this probability here because some people care about it more than the fact that this is the best solution.
Javascript approach. select the parent div and we can use the firstChild.textContent
let myDiv = document.getElementById("parentDiv");
myDiv.firstChild.textContent = "** New Text **"
Here's a recursive way:
function changeInnerText(elm,text,newText) {
if (elm == null) {
return;
}
changeInnerTextHelper(elm.firstChild, text, newText);
}
function changeInnerTextHelper(elm, text, newText) {
if (elm == null) {
return;
}
if (elm.nodeType == 3 && elm.data == text) {
elm.data = newText;
return;
}
changeInnerTextHelper(elm.firstChild, text, newText);
changeInnerTextHelper(elm.nextSibling, text, newText);
}
I'd like to update element's text dynamically:
<div>
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
I'm new to jQuery, so this task seems to be quite challenging for me.
Could someone point me to a function/selector to use?
If it is possible, I'd like to do it without adding a new container for the text I need to change.
Mark’s got a better solution using jQuery, but you might be able to do this in regular JavaScript too.
In Javascript, the childNodes property gives you all the child nodes of an element, including text nodes.
So, if you knew the text you wanted to change was always going to be the first thing in the element, then given e.g. this HTML:
<div id="your_div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
You could do this:
var your_div = document.getElementById('your_div');
var text_to_change = your_div.childNodes[0];
text_to_change.nodeValue = 'new text';
Of course, you can still use jQuery to select the <div> in the first place (i.e. var your_div = $('your_div').get(0);).
Update 2018
Since this is a pretty popular answer I decided to update and beautify it a little by adding the textnode selector to jQuery as a plugin.
In the snippet below you can see that I define a new jQuery function that gets all (and only) the textNodes. You can chain of this function as well with for example the first() function.
I do a trim on the text node and check if it's not empty after the trim because spaces, tabs, new lines, etc. are also recognized as text nodes. If you need those nodes too then simple remove that from the if statement in the jQuery function.
I added an example how to replace first text node and how to replace all text nodes.
This approach makes it easier to read the code and easier to use it multiple times and with different purposes.
The Update 2017 (adrach) should still work as well if you prefer that.
As jQuery extension
//Add a jQuery extension so it can be used on any jQuery object
jQuery.fn.textNodes = function() {
return this.contents().filter(function() {
return (this.nodeType === Node.TEXT_NODE && this.nodeValue.trim() !== "");
});
}
//Use the jQuery extension
$(document).ready(function(){
$('#replaceAll').on('click', () => {
$('#testSubject').textNodes().replaceWith('Replaced');
});
$('#replaceFirst').on('click', () => {
$('#testSubject').textNodes().first().replaceWith('Replaced First');
});
});
p {
margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
**text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**also text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>
Javascript (ES) equivalent
//Add a new function to the HTMLElement object so it can be used on any HTMLElement
HTMLElement.prototype.textNodes = function() {
return [...this.childNodes].filter((node) => {
return (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() !== "");
});
}
//Use the new HTMLElement function
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#replaceAll').addEventListener('click', () => {
document.querySelector('#testSubject').textNodes().forEach((node) => {
node.textContent = 'Replaced';
});
});
document.querySelector('#replaceFirst').addEventListener('click', function() {
document.querySelector('#testSubject').textNodes()[0].textContent = 'Replaced First';
});
});
p {
margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testSubject">
**text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**also text to change**
<p>text that should not change</p>
<p>text that should not change</p>
**last text to change**
</div>
<button id="replaceFirst">Replace First</button>
<button id="replaceAll">Replace All</button>
Update 2017 (adrach):
It looks like several things changed since this was posted. Here is an updated version
$("div").contents().filter(function(){ return this.nodeType == 3; }).first().replaceWith("change text");
Original answer (Not working for current versions)
$("div").contents().filter(function(){ return this.nodeType == 3; })
.filter(':first').text("change text");
Source: http://api.jquery.com/contents/
See In action
Markup :
$(function() {
$('input[type=button]').one('click', function() {
var cache = $('#parent').children();
$('#parent').text('Altered Text').append(cache);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">Some text
<div>Child1</div>
<div>Child2</div>
<div>Child3</div>
<div>Child4</div>
</div>
<input type="button" value="alter text" />
Just wrap the text you want to change in a span with a class to select.
Doesn't necessarily answer your question I know, but, probably a better coding practice. Keep things clean and simple
<div id="header">
<span class="my-text">**text to change**</span>
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
Voilà!
$('#header .mytext').text('New text here')
<div id="divtochange">
**text to change**
<div>text that should not change</div>
<div>text that should not change</div>
</div>
$(document).ready(function() {
$("#divtochange").contents().filter(function() {
return this.nodeType == 3;
})
.replaceWith("changed text");
});
This changes only the first textnode
For the specific case you mentioned:
<div id="foo">
**text to change**
<someChild>
text that should not change
</someChild>
<someChild>
text that should not change
</someChild>
</div>
... this is very easy:
var div = document.getElementById("foo");
div.firstChild.data = "New text";
You don't state how you want to generalize this. If, say, you want to change the text of the first text node within the <div>, you could do something like this:
var child = div.firstChild;
while (child) {
if (child.nodeType == 3) {
child.data = "New text";
break;
}
child = child.nextSibling;
}
$.fn.textPreserveChildren = function(text) {
return this.each(function() {
return $(this).contents().filter(function() {
return this.nodeType == 3;
}).first().replaceWith(text);
})
}
setTimeout(function() {
$('.target').textPreserveChildren('Modified');
}, 2000);
.blue {
background: #77f;
}
.green {
background: #7f7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="target blue">Outer text
<div>Nested element</div>
</div>
<div class="target green">Another outer text
<div>Another nested element</div>
</div>
Simple answer:
$("div").contents().filter(function(){
return this.nodeType == 3;
})[0].nodeValue = "The text you want to replace with"
Here is yet another method : http://jsfiddle.net/qYUBp/7/
HTML
<div id="header">
**text to change**
<div>
text that should not change
</div>
<div>
text that should not change
</div>
</div>
JQUERY
var tmp=$("#header>div").html();
$("#header").text("its thursday").append(tmp);
Problem with Mark's answer is that you get empty textnodes aswell. Solution as jQuery plugin:
$.fn.textnodes = function () {
return this.contents().filter(function (i,n) {
return n.nodeType == 3 && n.textContent.trim() !== "";
});
};
$("div").textnodes()[0] = "changed text";
Lots of great answers here but they only handle one text node with children. In my case I needed to operate on all text nodes and ignore html children BUT PRESERVE THE ORDERING.
So if we have a case like this:
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
We can use the following code to modify the text only AND PRESERVE THE ORDERING
$('#parent').contents().filter(function() {
return this.nodeType == Node.TEXT_NODE && this.nodeValue.trim() != '';
}).each(function() {
//You can ignore the span class info I added for my particular application.
$(this).replaceWith(this.nodeValue.replace(/(\w+)/g,"<span class='IIIclassIII$1' onclick='_mc(this)' onmouseover='_mr(this);' onmouseout='_mt(this);'>$1X</span>"));
});
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<div id="parent"> Some text
<div>Child1</div>
<div>Child2</div>
and some other text
<div>Child3</div>
<div>Child4</div>
and here we are again
</div>
Here is the jsfiddle of it working
I think you're looking for .prependTo().
http://api.jquery.com/prependTo/
We can also select an element on the
page and insert it into another:
$('h2').prependTo($('.container'));
If an element selected this way is
inserted elsewhere, it will be moved
into the target (not cloned):
<div class="container">
<h2>Greetings</h2>
<div class="inner">Hello</div>
<div class="inner">Goodbye</div>
</div>
If there is more than one target
element, however, cloned copies of the
inserted element will be created for
each target after the first.
This is an old question but you can make a simple function like this to make your life easier:
$.fn.toText = function(str) {
var cache = this.children();
this.text(str).append(cache);
}
Example:
<div id="my-div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>
Usage:
$("#my-div").toText("helloworld");
2019 vesrsion - Short & Simple
document.querySelector('#your-div-id').childNodes[0].nodeValue = 'new text';
Explanation
document.querySelector('#your-div-id') is used for selecting the parent (the element which text you are about to change)
.childNodes[0] selects the text node
.nodeValue = 'new text' sets text node value to "new text"
This answer is possibly inspired by Dean Martin's comment. Can't say for sure since I've been using this solution for years now. Just thought I should post this probability here because some people care about it more than the fact that this is the best solution.
Javascript approach. select the parent div and we can use the firstChild.textContent
let myDiv = document.getElementById("parentDiv");
myDiv.firstChild.textContent = "** New Text **"
Here's a recursive way:
function changeInnerText(elm,text,newText) {
if (elm == null) {
return;
}
changeInnerTextHelper(elm.firstChild, text, newText);
}
function changeInnerTextHelper(elm, text, newText) {
if (elm == null) {
return;
}
if (elm.nodeType == 3 && elm.data == text) {
elm.data = newText;
return;
}
changeInnerTextHelper(elm.firstChild, text, newText);
changeInnerTextHelper(elm.nextSibling, text, newText);
}
I have this code:
<div class="input">
<input type="number" id="myID" oninput="myFunction()">
<div>
<h3>MY TEXT</h3>
</div>
</div>
and I want to make a javascript code to remove the div below the input field whenever I write anything in the input
..........
I tried this code:
function myFunction(){
var field = document.getElementById("myID");
var num = field.value;
var parent = field.parentNode;
parent.innerHTML = field.outerHTML;
field.value = num;
}
but it have a problem each time I make an input, I have to re-click inside the input to make it active again
check out the code here
You should not use inline HTML event attributes to wire up event handlers. That technique is 25+ years old and will not die the death it deserves because people just keep copying it from other code they've seen.
See the comments for the simple explanation:
// Add the event handler to the input in JavaScript, not in HTML
document.getElementById("myID").addEventListener("input", removeElement);
function removeElement(){
// Remove the sibling element that follows the input
document.querySelector("#myID").nextElementSibling.remove();
// Now that the element has been removed, this function is no
// longer required, so remove the event handler to prevent attempts
// to remove it again when it's no longer there. "this" refers to
// the object that caused this function to be invoked (the input
// element in this case).
this.removeEventListener("input", removeElement);
}
<div class="input">
<input type="number" id="myID">
<div>
<h3>MY TEXT</h3>
</div>
</div>
How to remove an HTML element using JavaScript ?
Given an HTML element and the task is to remove the HTML element from the document using JavaScript.
Approach:
Select the HTML element which need to remove.
Use JavaScript remove() and removeChild() method to remove the
element from the HTML document.
Exemple to remove a div :
div.parentNode.removeChild(div);
Follow this link for more information.
I hope I was able to help you.
<div class="input">
<input type="number" id="myID" >
<div id="id2">
<h3>MY TEXT</h3>
</div>
</div>
<script>
document.getElementById("myID").oninput = function() {myFunction()};
function myFunction() {
document.getElementById("id2").innerHTML="";
}
</script>
Problem with using innerHTML is you are basically using a whiteboard. You erase everything on it and you have to redraw it all. That means you would need to reset the value and focus. It is doable, just not practical.
The better thing to do would be to select the element and remove it with .remove()
var field = document.getElementById("myID");
var num = field.value;
if (num.length) {
field.nextElementSibling.remove()
}
It will work, but you will be better off using a class to hide the element. It also has the benefit that if the user deletes the text in the input, you can reshow the message. I would just hide it with a css class with toggle. I would select the div with nextElementSibling.
function myFunction(){
var field = document.getElementById("myID");
var num = field.value;
field.nextElementSibling.classList.toggle('hidden', num.length)
}
.hidden {
display: none;
}
<div class="input">
<input type="number" id="myID" oninput="myFunction()">
<div>
<h3>MY TEXT</h3>
</div>
</div>
I'm trying to find out if it's possible to clone an HTML div with JS, edit it and append it again as a new element. So my source is, for example, this code here:
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
</div>
After copying this element, I need to find a way to change the attribute id of the new cloned input, clear the input value and paste it again in the wrapper so that it looks like this at the end:
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
<div class="element">
<input id="test--2" value=""/>
</div>
</div>
Does that make sense to you? If yes, how can I get this done? Or is it better to assign the content to a variable to append it? I'm looking for the best way here and maybe my idea is a solution too.
You can use pure JavaScript to do this by just cloning the .element div using the cloneNode() method, assign new id and value to the clone div and finally append it back to the document using the insertBefore() method like this:
let x = document.querySelector(".element");
let y = x.cloneNode(true);
y.children[0].id = "test--2";
y.children[0].defaultValue = "";
x.parentNode.insertBefore(y, x.nextSibling);
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
</div>
JSFiddle with the above code: https://jsfiddle.net/AndrewL64/jvc7reza/18/
Based on this answer you could do like:
$('#cloneBtn').on('click', function() {
// get the last input having ID starting with test--
var $inp = $('[id^="test--"]:last'); // Or use :first if you need
// Get parent element
var $div = $inp.closest('.element');
// Create clone
var $div_clone = $div.clone();
// Retrieve number from ID and increment it
var num = parseInt($inp.prop("id").match(/\d+/g), 10) + 1;
// Generate new number and assign to input
$div_clone.find('[id^="test--"]').prop({id: 'test--' + num, value: ''});
// Insert cloned element
$div.after($div_clone); // Or use .before() if you need
});
.element {
padding: 10px;
outline: 2px solid #0bf;
}
<button id="cloneBtn">CLICK TO CLONE</button>
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC" />
</div>
</div>
Once done inspect the input elements to see the new IDs
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
Scrambled elements, retrieve highest ID, increment, clone, append.
If your numbered IDs are scrambled, we first need a way to retrieve the highest ID number. Here's an implementation in pure JavaScript:
function cloneElement () {
const inpAll = document.querySelectorAll('[id^="test--"]');
if (!inpAll.length) return; // do nothing if no elements to clone
const maxID = Math.max.apply(Math, [...inpAll].map(el => +el.id.match(/\d+$/g)[0]));
const incID = maxID + 1;
const element = document.querySelector('.element'); // Get one for cloning
const eleClone = element.cloneNode(true);
const inpClone = eleClone.querySelector('[id^="test--"]');
inpClone.id = 'test--'+ incID;
inpClone.value = incID; // just for test. Use "" instead
document.querySelector('.wrapper').prepend(eleClone);
}
document.querySelector('#cloneBtn').addEventListener('click', cloneElement);
.element {
padding: 10px;
outline: 2px solid #0bf;
}
<button id="cloneBtn">CLICK TO CLONE</button>
<div class="wrapper">
<div class="element">
<input id="test--1" value="1" />
</div>
<div class="element">
<input id="test--23" value="23" />
</div>
<div class="element">
<input id="test--7" value="7" />
</div>
</div>
Once done inspect the input elements to see the new IDs
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
I don't know what data you know, why you want to do such a thing but it can be done :-)
One way is like that:
const elemToCopy = document.getElementById("test--1").parentNode; // I assume you know id
const copiedElem = elemToCopy.cloneNode(true);
const newInput = copiedElem.querySelector("#test--1");
newInput.id = "test--2";
newInput.value = "";
elemToCopy.parentNode.append(copiedElem);
Let me know in a comment if something is not clear :-)
Yes, use jQuery's .clone().
Here is an example that might be relevant to your situation:
let newElement = $('.element').clone();
newElement.find('input').attr('id', 'test--2').val('');
$('.wrapper').append(newElement);
Explanation
In the first line, we created a new cloned element by using jQuery clone().
Then, we found it's child input, changed it's ID and reset the val().
Finally, we found the .wrapper element and appended the new cloned element to it.