I want to create multiple paragraphs with each two inputfield with Javascript.
I wanted to know, if there is a way to have a shorter code but the same result?
It should have the same result like this but with a shorter code:
var para1 = document.createElement("p");
var i1 = document.createElement("input");
var i2 = document.createElement("input");
para1.appendChild(i1);
para1.appendChild(i2);
var element = document.getElementById("div1");
element.appendChild(para1);
var para2 = document.createElement("p");
var i3 = document.createElement("input");
var i4 = document.createElement("input");
para2.appendChild(i3);
para2.appendChild(i4);
var element = document.getElementById("div1");
element.appendChild(para2);
var para3 = document.createElement("p");
//etc.
<div id="div1"></div>
I could not think of any other solution than using a for loop 😁
This definitely reduces the code by half length though.
numberOfParagraphs = 3
for(let i = 0; i< numberOfParagraphs;i++){
var para= document.createElement("p");
var i1 = document.createElement("input");
var i2 = document.createElement("input");
para.appendChild(i1);
para.appendChild(i2);
document.getElementById("div1").appendChild(para);
}
<div id="div1"></div>
Wrap your code into a function
function createPara() {
var para1 = document.createElement("p");
var i1 = document.createElement("input");
var i2 = document.createElement("input");
para1.appendChild(i1);
para1.appendChild(i2);
var element = document.getElementById("div1");
element.appendChild(para1);
}
Call the function n times
createPara()
createPara()
Additionally you can pass params such as class, id etc.
well the way you have it written, you are executing the exact same code multiple times. why not put it in a function?
createPara();
createPara();
createPara();
//etc.
function createPara() {
var para2 = document.createElement("p");
var i3 = document.createElement("input");
var i4 = document.createElement("input");
para2.appendChild(i3);
para2.appendChild(i4);
var element = document.getElementById("div1");
element.appendChild(para2);
}
Create a document fragment and append it to DIV instead of creating individual elements.
In the current setup, HTML elements will reflow each time you append any element.
With DocumentFragment you can save multiple reflows as it reflows only once when attached.
Please refer https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment for information.
wrap your code into a function and give it number of para :
function createPara(n) {
let parentDiv = document.getElementById("div1")
for(let i =0; i<n; i++){
let para = document.createElement("p");
let i1 = document.createElement("input");
let i2 = document.createElement("input");
para1.appendChild(i1);
para1.appendChild(i2);
parentDiv.appendChild(para);
}
}
}
Call the function and give it the number u want to repeat for exemple 5 time :
createPara(5)
you can also give it the number of inputs
I thought I would do something for a more general case, but might have gotten a bit carried away; anyway:
const new_children = [
{ tag: 'p', children: [
{ tag: 'input' },
{ tag: 'input' },
] },
];
const element_for_def = (def) => {
const element = document.createElement(def.tag);
if(def.children && def.children.length > 0)
append_children_to_ele(element, def.children);
return element;
};
const append_to_element = (parent) => (child) => parent.appendChild(child);
const append_children_to_ele = (parent, children) =>
children
.map(element_for_def)
.forEach(append_to_element(parent));
const three_new_children = [1,2,3].reduce(acc => acc.concat(new_children), []);
append_children_to_ele(document.getElementById("div1"), three_new_children);
<div id="div1"></div>
ma is a reference to an element object which you want to create multiple paragraphs.
I use 10 for multiple paragraphs line. You can use your required number.
let ma = document.getElementById("multiple-para").innerHTML;
for(var i =0; i<10; i++){
document.write(ma + "<br>");
}
Related
I need to exit from mine.onclick = function so can anyone help me??
I'm new in js!
I tried to write the word game and I need to write the function, when I'm clicking on the button I need to move the button, but its not working 3th time
//creating div
var div = document.createElement('div');
div.innerHtml = '';
document.body.appendChild(div);
div.classList.add('main');
//creating divsec
var divsec = document.createElement('div');
divsec.innerHtml = '';
document.body.appendChild(divsec);
divsec.classList.add('submain');
//creating array for words
var arr = prompt("Write your word or sentance here and don't accept your apponent to see that!");
array = arr.split('');
array = array.sort();
console.log(array);
alert("Let's construct the word!");
var main = document.getElementsByClassName('main');
var divsec = document.getElementsByClassName('submain');
for(var i = 0; i < arr.length; i++){
var button = document.createElement('button');
divsec[0].appendChild(button);
button.innerHTML = array[i];
button.onclick = function(){
mainp = main[0].appendChild(this);
mainp.onclick = function (){
divsec[0].appendChild(this);
}
}
}
Is this the answer you're looking for?
//creating div
var div = document.createElement('div');
div.innerHtml = '';
document.body.appendChild(div);
div.classList.add('main');
//creating divsec
var divsec = document.createElement('div');
divsec.innerHtml = '';
document.body.appendChild(divsec);
divsec.classList.add('submain');
//creating array for words
var arr = prompt("Write your word or sentance here and don't accept your apponent to see that!");
array = arr.split('');
array = array.sort();
console.log(array);
alert("Let's construct the word!");
var main = document.getElementsByClassName('main');
var divsec = document.getElementsByClassName('submain');
for(var i = 0; i < arr.length; i++){
var button = document.createElement('button');
divsec[0].appendChild(button);
button.innerHTML = array[i];
button.onclick = function(){
if (this.parentNode.className === 'main') divsec[0].appendChild(this)
else main[0].appendChild(this);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
If it's not, please clarify your question and give an example of what is the desired effect on clicking a single button. I'm also not sure what you mean by exit the function. It seemed fine to me.
You stated that you need a button to move, but you didn't state how does it need to move.
I'm probably missing/doing something silly, but I can't seem to work this out:
Here's a fiddle showing the problem:
https://jsfiddle.net/jhqjmcn4/1/
Note that you will need to open your console to see what is happening.
Basically, in this example, I have two functions containing a for loop that are identical to each other except the second one contains a JQuery append.
The goal of the function is to get the html elements from within a string, which works fine in the first function, but not the second.
As can be seen in the console, this causes anything that is not a text node to be ignored and not added to the list. In this case, the b and p tags are not being included.
Here is the code again:
JS:
function parse_text(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = div.childNodes;
var container = jQuery("#container");
var list = [];
for (var i = 0; i < elements.length; i++){
var element = elements[i];
list.push(element);
console.log("First", list);
}
}
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = div.childNodes;
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++){
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
var text = "Here is <b>some</b> text with <p>html</p> in it";
parse_text(text);
parse_text_two(text);
html (irrelevant):
<div id="container">
</div>
<div id="container2">
</div>
Thanks in advance.
I suppose you need to have a Array.prototype.filter() method to get the html elements:
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = [].filter.call(div.childNodes, function(el) {
return el.nodeType !== 3;
});
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++) {
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
var text = "Here is <b>some</b> text with <p>html</p> in it";
parse_text_two(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
<div id="container2">
</div>
You can check updated fiddle here jsfiddle.net/bharatsing/jhqjmcn4/3/
Its return same result for both methods in console as per you want.
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elementsOrg = div.childNodes;
var elements = Array.prototype.slice.call(elementsOrg);;
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++){
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
The issue I saw by putting a debug point inside the loop was this:
The container.append(element); statement was actually modifying the elements array and was removing the appended element from the array. Which meant that in the loop for various values of 'p' the elements array looked like this:
p = 0 -> elements : [ text, b, text, p, text ] // text node at 0 picked
p = 1 -> elements : [ b, text, p, text ] // text node at 1 picked
p = 2 -> elements : [ text, p, text ] // text node at 2 picked
That is why the loop only ran 3 times instead of the original length of the elements array , i.e. 5.
This probably happens because jQuery 'moves' the node from its original place to the container div.
You can either clone the element node and then append into the container:
function parse_text_two(text) {
var div = document.createElement("DIV"),
p,
element,
elements,
container = jQuery("#container2"),
list = [];
div.innerHTML = text;
elements = div.childNodes;
for (p = 0; p < elements.length; p++){
element = elements[p];
list.push(element);
console.log("Second", list);
container.append($(element).clone());
}
}
Or use a while loop as suggested in Venkatesh's answer. Anyway, it is always better to know the root cause. :)
Hope this helps.
In second function in each loop comment this line container.append(element);
I created an object on js with 4 buttons, but it's not showing,
this is my code:
function Keyboard() {
this.plus = document.createElement("input");
this.plus.type = "submit";
this.plus.value = "A";
this.minus = document.createElement("input");
this.minus.type = "submit";
this.minus.value = "B";
this.multi = document.createElement("input");
this.multi.type = "submit";
this.multi.value = "C";
this.divide = document.createElement("input");
this.divide.type = "submit";
this.divide.value = "D";
}
var k = new Keyboard();
document.body.appendChild(k);
I will add the onClick later, but why is this not showing?
Thanks!
Your Keyboard constructs a simple JavaScript object with 4 properties, but not a DOM object. Later, you try to append a simple JavaScript object to your document.
First, you need to create DOM element using document.createElement.
Second, you don't need new keyword here at all.
Third, you don't need to set subitems as properties. You append them to a parent object, and it is enough.
Try the following code:
function CreateKeyboard() {
var t = document.createElement("div");
var plus = document.createElement("input");
plus.type = "submit";
plus.value = "A";
t.appendChild(plus);
var minus = document.createElement("input");
minus.type = "submit";
minus.value = "B";
t.appendChild(minus);
var multi = document.createElement("input");
multi.type = "submit";
multi.value = "C";
t.appendChild(multi);
var divide = document.createElement("input");
divide.type = "submit";
divide.value = "D";
t.appendChild(divide);
return t;
}
document.body.appendChild(CreateKeyboard());
By the way, you can avoid code repetition. For example, by utilizing Array.prototype.forEach:
function CreateKeyboard() {
var t = document.createElement("div");
['A', 'B', 'C', 'D'].forEach(function(l) {
var elem = document.createElement("input");
elem.type = "submit";
elem.value = l;
t.appendChild(elem);
});
return t;
}
document.body.appendChild(CreateKeyboard());
This should work:
<script type="text/javascript">
function createSubmitButton(val) {
var el = document.createElement("input");
el.type = "submit";
el.value = val;
document.body.appendChild(el);
}
createSubmitButton("A");
createSubmitButton("B");
createSubmitButton("C");
createSubmitButton("D");
</script>
Make sure you place the script tag at the bottom of the html code, right before the ending body tag.
k is not type of Node. Append only Node elements you have created.
var k = new Keyboard();
document.body.appendChild(k.plus);
document.body.appendChild(k.minus);
document.body.appendChild(k.multi);
document.body.appendChild(k.divide);
I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the class of "original" to text inputs with a class of "new". When I run the loop, it only replaces every-other div with an input, but if I run the loop to just replace the class of the div and not change the tag to input, it does every single div, and doesn't only do every-other.
Here is my loop code, and a link to the live version: live version here
function divChange() {
var divs = document.getElementsByTagName("div");
for (var i=0; i<divs.length; i++) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
var parent = divs[i].parentNode;
parent.replaceChild(textInput, divs[i]);
}
}
}
Because the divs collection is updated when one of its div elements is removed from the DOM, you end up skipping over divs because your i isn't updated with the reindexing of the collection.
A common solution is to iterate in reverse instead.
function divChange() {
var divs = document.getElementsByTagName("div");
for (var i=divs.length - 1; i > -1; i--) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
divs[i].parentNode.replaceChild(textInput, divs[i]);
}
}
}
Another solution you could use is to copy the live HTMLCollection to an inert array, and use your original logic:
function divChange() {
var divs = document.getElementsByTagName("div");
divs = Array.prototype.slice.call( divs ); //convert to array
for (var i = 0; i < divs.length; i++) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
var parent = divs[i].parentNode;
parent.replaceChild(textInput, divs[i]);
}
}
}
divChange();
http://jsfiddle.net/2UCZa/1/
Yet another solution is to create an Array from an array-like object, and iterate over this. For example:
var divs = document.getElementsByTagName("div");
Array.from(divs).forEach(function(el) {
if (el.className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = el.innerHTML;
var parent = el.parentNode;
parent.replaceChild(textInput, el);
}
});
I like this one the best, as it produces the least amount of code, and is very clear!
I don't know why, but this one seemed to work in the end:
ModalBody.insertAdjacentHTML('afterbegin', loader.outerHTML);
my loader is basically just a new div, but inside of the div there is this loading symbol, which appears when the content is loaded.
var loader = document.createElement('div');
loader.classList.add('loader');
loader.classList.add('is-loading');
loader.classList.add('mt-5');
So with just this line
ModalBody.insertAdjacentHTML('afterbegin', loader);
...while the content was loaded a got [object HTMLDivElement] shown shortly, after 3 sec more or less the right content appeared. As soon as I added this ".outerHTML" things got right. I am still a super beginner. So, maybe someone could also explaine why this worked?
for(var i=0; i<myJSONObject.model.length; i++){
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
create_div.innerHTML = myJSONObject.model[i].model_name;
var assign_innerHTML = create_div.innerHTML;
var create_anchor = document.createElement('a');
document.getElementById('models').appendChild(create_div);
document.getElementById(create_div.id).appendChild(create_anchor);
}
for ex the myJSONObject.model.length is 2
the output is like this
<div id = 'model_id0'>XXXXX<a> </a></div>
<div id = 'model_id1'>XXXXX<a> </a></div> */
but instead of above the output sholud be like this
<div id = model_id0> <a> xxxxxx</a></div>
<div id = model_id1> <a> xxxxxx</a></div>
how to append it inside of the innerhtml
any one plz reply !!!!
two suggestions:
1.) instead of assigning innerHTML to model_idx div assign the model name to its child a. and 2nd instead of appending it to DOM in every loop do it after completing the loop as to minimize frequent the DOM Update ie by:
objContainer = document.createElement('div');
for(....)
{
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
var create_anchor = document.createElement('a');
create_anchor.innerHTML = myJSONObject.model[i].model_name;
create_div.appendChild(create_anchor);
objContainer.appendChild(create_div);
}
document.getElementById('models').appendChild(objContainer);
I would go along the lines of:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
create_div.id = "model_id" + i;
create_div.innerHTML = "<a>" + model.model_name + "</a>";
models.appendChild(create_div);
}
Unless you specifically need to do something to the anchor itself (other than set its innerHTML), there's no need to create a reference to an element for it. If you do need to do something specific to that anchor, then in that case have this, instead:
EDIT: As per your comment, you DO want to do something to the anchor, so go with this (now updated) option - assuming the anchor will always be a child of the div that has the ID you require. The reason "model_id" + i is being put in as a string is because that is exactly what is being passed into the HTML - the document has no clue what "i" is outside of javascript:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
var create_anchor = document.createElement("a");
create_div.id = "model_id" + i;
create_anchor.innerHTML = model.model_name;
if(window.addEventListener) {
create_anchor.addEventListener("click", function() {
getModelData(1, this.parentNode.id);
}, false);
} else {
create_anchor.attachEvent("onclick", function() {
getModelData(1, this.parentNode.id);
});
}
create_div.appendChild(create_anchor);
models.appendChild(create_div);
}