I am obviously missing something. I need this addmore button to add textarea into the div for the particular question, not only the first one. I can make it complicate, but I hope there is an easy solution.
Fiddle
index.html
1.Question:<br/>
<textarea name="odg1" rows="1" cols="50" ></textarea><br/><div id="inner"></div><button type="button" name="addmore" onClick="addmore();">Add more</button>
<br/><br/>
2.Question:<br/>
<textarea name="odg2" rows="1" cols="50" ></textarea><br/><div id="inner"><button type="button" name="addmore" onClick="addmore();">Add more</button>
<br/><br/>
addmore.js
am = 1;
function addmore() {
var textarea = document.createElement("textarea");
textarea.name = "odg" + am;
textarea.rows = 1;
textarea.cols = 50;
var div = document.createElement("div");
div.innerHTML = textarea.outerHTML;
document.getElementById("inner").appendChild(div);
am++;
}
This function demonstrates how to generate more element using jQuery:
var am = 1;
function addmore() {
var newText = $('<textarea />').attr('name','odg'+am).attr('rows',1).attr('cols',50);
var newBtn = $('<button />').attr('onclick','addmore()').html('add more');
$('body').append(newText);
$('body').append('<br />');
$('body').append(newBtn);
am++;
}
Related
I want to attach more than one field to a div along with a remove button. Something similar to Gmail file attaching methods if the user presses the remove button it should remove the specified p along with the button. But if I press the remove button it is not working properly I know the javascript array method is the problem but I am not able to understand where I am going wrong
<form name="create" action ="">
<input type="text" id="text">
<button name="submit" onclick="attach()" type="button">Submit</button>
</form>
<div id="attach">
</div>
<script>
function attach(){
var value =document.getElementById('text').value;
var content = document.createElement('p'); // is a node
content.className = 'element';
// Insert text
var btn = document.createElement("BUTTON");
btn.innerHTML = "Delete This element";
var i =0;
btn.onclick = function(){
console.log(i);
remove(i);
i++;
};
content.innerHTML = value;
document.getElementById("attach").appendChild(content);
document.getElementById("attach").appendChild(btn);
}
function remove(i){
var elem = document.getElementsByClassName('element');
elem[i].remove();
return false;
}
</script>
The working plunker is here.
http://plnkr.co/edit/eYhfN85FH4XabzE4rO4M?p=preview
What is going wrong here? How can I fix this?
A slightly different approach that simplifies your original example, is to take advantage of the function/closure you create for the button you create. In there, you can literally just reference the content and btn elements, and remove them directly
function attach(){
var value =document.getElementById('text').value;
var content = document.createElement('p'); // is a node
content.className = 'element';
// Insert text
var btn = document.createElement("BUTTON");
btn.className = 'element';
btn.innerHTML = "Delete This element";
btn.onclick = function(){
content.remove();
btn.remove();
};
content.innerHTML = value;
var attach = document.getElementById("attach");
attach.appendChild(content);
attach.appendChild(btn);
}
<form name="create" action ="">
<input type="text" id="text">
<button name="submit" onclick="attach()" type="button">Submit</button>
</form>
<div id="attach">
</div>
That way, you don't have to worry about what index you're removing or anything
Here you go!
function attach() {
const attachEl = document.getElementById("attach");
const value = document.getElementById("text").value;
const contentEl = document.createElement("p"); // is a node
contentEl.className = "element";
// Insert text
const btnEl = document.createElement("button");
btnEl.innerHTML = "Delete This element";
const wrapperEl = document.createElement("div");
btnEl.onclick = function() {
attachEl.removeChild(wrapperEl);
};
attachEl.appendChild(wrapperEl);
wrapperEl.appendChild(contentEl);
wrapperEl.appendChild(btnEl);
contentEl.innerHTML = value;
}
#attach{
background-color: teal;
}
.element {
background-color: wheat;
}
<form name="create" action="">
<input type="text" id="text">
<button name="submit" onclick="attach()" type="button">Submit</button>
</form>
<div id="attach">
</div>
We should use a wrapper to wrap a p & button together so that when we initiate delete it deletes the complete wrapper
function attach(){
var value =document.getElementById('text').value;
var content = document.createElement('p'); // is a node
var wrapper = document.createElement('div');
wrapper.className="wrapper";
content.className = 'element';
// Insert text
var btn = document.createElement("BUTTON");
btn.innerHTML = "Delete This element";
var i =0;
btn.onclick = function(){
console.log(i);
remove(i);
i++;
};
content.innerHTML = value;
wrapper.appendChild(content);
wrapper.appendChild(btn);
document.getElementById("attach").appendChild(wrapper);
}
function remove(i){
var elem = document.getElementsByClassName('wrapper');
elem[i].remove();
return false;
}
<form name="create" action ="">
<input type="text" id="text">
<button name="submit" onclick="attach()" type="button">Submit</button>
</form>
<div id="attach">
</div>
I am creating a simple note editor that has two divs a heading and a body. I'm trying to add a new note by creating the two divs with a button. Such that when you click the button the new divs will be created with texts appended to it through localStorage. When I click the button none of the divs is added. here is the html
<div id ="heading" contenteditable="true">
</div>
<div id="content" contenteditable="true">
</div>
<button type="button" onclick="addNote()" name="button">Add new Note</button>
here is the js
document.getElementById("heading").innerHTML = localStorage['title'] || 'Heading goes here';
document.getElementById('content').innerHTML = localStorage['text'] || 'Body of text editor';
setInterval(function () {
localStorage['title'] = document.getElementById('heading').innerHTML;
localStorage['text'] = document.getElementById('content').innerHTML;
}, 1000);
function addNote() {
const heading = document.createElement('div');
const content = document.createElement('div');
heading.id = "heading";
content.id = "content";
localStorage['title'] = document.getElementById('heading').innerHTML;
localStorage['text'] = document.getElementById('content').innerHTML;
}
your are missing to append the created elements to the dom (https://www.w3schools.com/jsref/met_node_appendchild.asp) :
function addNote() {
var heading = document.createElement('div');
var content = document.createElement('div');
heading.id = "heading";
content.id = "content";
document.getElementById("myDivs").appendChild(heading);
document.getElementById("myDivs").appendChild(content);
}
and you will need to have an div with id myDivs
<div id="myDivs"></div>
<button type="button" onclick="addNote()" name="button">Add new Note</button>
greetings
There are many problems in your code.
Proper way to set localStorage is via localStorage.setItem(key, val)
You need to append your DIVs somewhere on your HTML page.
Also you need to handle your setTimeout properly.
Please find solution below
HTML
<button type="button" onclick="addNote()" name="button">Add new Note</button>
JavaScript
var intervalObj = null;
function addNote() {
if(intervalObj) {
clearInterval(intervalObj)
}
const heading = document.createElement('div');
heading.setAttribute('contenteditable', true)
heading.id = "heading";
const content = document.createElement('div');
content.setAttribute('contenteditable', true)
content.id = "content";
heading.innerHTML = window.localStorage.getItem('title') || 'Heading goes here';
content.innerHTML = window.localStorage.getItem('text') || 'Body of text editor';
document.getElementsByTagName("body")[0].append(heading);
document.getElementsByTagName("body")[0].append(content);
intervalObj = setInterval(function () {
localStorage.setItem('title', document.getElementById('heading').innerHTML);
localStorage.setItem('text', document.getElementById('content').innerHTML);
}, 1000);
}
Instead of using the setInterval function you can load the data using an onload function and update to local storage whenever the AddNote button is clicked.
Modify the html as follows:
<body onload="load()">
<div id ="heading" contenteditable="true">
</div>
<div id="content" contenteditable="true">
</div>
<button type="button" onclick="addNote()" name="button">Add new Note</button>
</body>
And also you can modify your JS file as follows
function load() {
var headingText = localStorage['title'] || 'Heading goes here';
var bodyText = localStorage['text'] || 'Body of text editor';
document.getElementById("heading").innerHTML = headingText;
document.getElementById('content').innerHTML = bodyText;
}
function addNote() {
localStorage['title'] = document.getElementById('heading').innerHTML;
localStorage['text'] = document.getElementById('content').innerHTML;
}
I'm making an app that submits posts, but I originally designed it with a textarea in mind, I've since put in an iframe to create a rich text field, set the display style to hidden for the textarea and wanted to know how I could modify it to use the iframe value.
HTML
<div id="textWrap">
<div class="border">
<h1>Start Writing</h1><br />
<input id="title" placeholder="Title (Optional)">
<div id="editBtns">
<button onClick="iBold()">B</button>
<button onClick="iUnderline()">U</button>
<button onClick="iItalic()">I</button>
<button onClick="iHorizontalRule()">HR</button>
<button onClick="iLink()">Link</button>
<button onClick="iUnLink()">Unlink</button>
<button onClick="iImage()">Image</button>
</div>
<textarea id="entry" name="entry" rows="4" cols="50" type="text" maxlength="500" placeholder="Add stuff..."></textarea>
<iframe name="richTextField" id="richTextField"></iframe><br />
<button id="add">Submit</button>
<button id="removeAll" onclick="checkRemoval()">Delete All Entries</button>
<ul id="list"></ul>
<ul id="titleHead"></ul>
</div><!--end of border div-->
</div><!--end of textWrap-->
Here is the JS to submit the posts.
//target all necessary HTML elements
var ul = document.getElementById('list'),
removeAll = document.getElementById('removeAll'),
add = document.getElementById('add');
//richText = document.getElementById('richTextField').value;
//make something happen when clicking on 'submit'
add.onclick = function(){
addLi(ul)
};
//function for adding items
function addLi(targetUl){
var inputText = document.getElementById('entry').value, //grab input text (the new entry)
header = document.getElementById('title').value, //grab title text
li = document.createElement('li'), //create new entry/li inside ul
content = document.createElement('div'),
title = document.createElement('div'),
//textNode = document.createTextNode(inputText + ''), //create new text node and give it the 'entry' text
removeButton = document.createElement('button'); //create button to remove entries
content.setAttribute('class','content')
title.setAttribute('class','title')
content.innerHTML = inputText;
title.innerHTML = header;
if (inputText.split(' ').join(' ').length === 0) {
//check for empty inputs
alert ('No input');
return false;
}
removeButton.className = 'removeMe'; //add class to button for CSS
removeButton.innerHTML = 'Delete'; //add text to the remove button
removeButton.setAttribute('onclick', 'removeMe(this);'); //creates onclick event that triggers when entry is clicked
li.appendChild(title); //add title textnode to created li
li.appendChild(content); //add content textnode to created li
li.appendChild(removeButton); //add Remove button to created li
targetUl.appendChild(li); //add constructed li to the ul
}
//function to remove entries
function removeMe(item){
var deleteConfirm = confirm('Are you sure you want to delete this entry?');
if (deleteConfirm){var parent = item.parentElement;
parent.parentElement.removeChild(parent)}
};
function checkRemoval(){
var entryConfirm = confirm('Are you sure you want to delete all entries?');
if (entryConfirm){
ul.innerHTML = '';
}
};
demo I'm working on for reference.. http://codepen.io/Zancrash/pen/VemMxz
you can use either local storage for passing iframe values to the parent DOM.
or ( use this to pass value from iframe to parent container )
var iFrameValue = $('#iframe').get(0).contentWindow.myLocalFunction();
var iFrameValue = $('#iframe').get(0).contentWindow.myLocalVariable;
From IFrame html
<script type="text/javascript">
var myLocalVariable = "text";
function myLocalFunction () {
return "text";
}
</script>
I'm attempting to create a page where the user is able to customize the form to their needs by adding in extra divs or nested divs (as many layers deep as they'd like). Within each div I'd like to have text input and a button which adds another div on the same level and a button that nests a div within it. Both divs should again have a text input and a button which does the same thing.
However I've gotten a bit stuck. When I attempt to create a nested div I always end up adding it at the very bottom instead of inside its parent.
<html>
<script type="text/javascript">
var counter = 1;
function addNode() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs'>";
document.getElementById("dynamicInput").appendChild(newDiv);
var newButton = document.createElement('button');
newButton.type = "button";
newButton.onclick = addSub;
document.getElementById("dynamicInput").appendChild(newButton);
}
function addSub() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs' style='margin:10px'>";
document.getElementById("subInput").appendChild(newDiv);
}
</script>
<form class="form" method="POST">
<div id="dynamicInput" name="dynamicInput" multiple="multiple">
Entry 1<br><input type="text" name="myInputs">
<div id="subInput" name="subInput" multiple="multiple">
<input type="button" value="add nested" onClick="addSub();">
</div>
</div>
<input type="button" value="Add another text input" onClick="addNode();" >
<input type="submit" value = "answer" multiple="multiple"/>
</form>
</html>
Here is a complete solution for you keep in mind that if you need to bind extra events on your produced inputs and buttons you ll have to do it inside the functions addNode or addSub as i did for the click event on the buttons.
Working example : https://jsfiddle.net/r70wqav7/
var counter = 1;
function addNode(element) {
counter++;
var new_entry="Entry "+counter+"<br><input type='text' name='myInputs'><br>";
element.insertAdjacentHTML("beforebegin",new_entry);
}
function addSub(element) {
counter++;
var new_sub_entry="<div class='block'>"
+"Entry "+counter+"<br><input type='text' name='myInputs'><br>"
+"<div class='buttons'>"
+"<input class='add_sub_button' type='button' value='add nested'>"
+"<input class='add_button' type='button' value='Add another text input' >"
+"</div>"
+"</div><br />"
+"</div>";
element.insertAdjacentHTML("beforebegin",new_sub_entry);
var blocks=element.parentNode.getElementsByClassName("block");
blocks[blocks.length-1].getElementsByClassName("add_sub_button")[0].addEventListener("click",function(){
addSub(this.parentNode);
});
blocks[blocks.length-1].getElementsByClassName("add_button")[0].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var buttons=document.getElementsByClassName("add_button");
for(i=0;i<buttons.length;i++){
buttons[i].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var nested_buttons=document.getElementsByClassName("add_sub_button");
for(i=0;i<buttons.length;i++){
nested_buttons[i].addEventListener("click",function(){
addSub(this.parentNode);
});
}
div.block{
padding:5px;
border:2px solid #000;
}
<form class="form" method="POST">
<div class="block">
Entry 1<br><input type="text" name="myInputs"><br>
<div class="buttons">
<input class="add_sub_button" type="button" value="add nested">
<input class="add_button" type="button" value="Add another text input" >
</div>
</div><br />
<input type="submit" value = "answer" multiple="multiple"/>
</form>
EDITED : There was an error binding the click event on nested items updated to work properly
Here's another worked example which makes use of the concepts I mentioned in an earlier comment. I've moved the Add-Item button outside the form and altered the method used to determine the text for each new item added. Rather than keep a counter, I count the number of existing items in the document and increment it, using this as as the n in the string "Entry n"
I should have added(appended) the sub-item before the button that creates new ones, but was lazy and just called appendChild on the button after the other new element was added - the end result is the same, but it's less efficient and will cause slower performance/shorter battery life.
I was going to use the .cloneNode method of the .dynamicInput div, when clicking "Add new item", however this will copy all subitems of the chosen target and we still need to call addEventListener for the button anyway, so I've opted to simply create each input-item added with the "Add new item" button instead.
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('addNewInputBtn').addEventListener('click', myAddNewItem, false);
var subItemBtn = document.querySelectorAll('.dynamicInput button')[0];
subItemBtn.addEventListener('click', myAddSubItem, false);
}
function makeNewItem(titleStr)
{
var div = newEl('div');
div.className = 'dynamicInput';
var heading = newEl('h3');
heading.innerText = titleStr;
div.appendChild(heading);
var input = newEl('input');
div.appendChild(input);
var btn = newEl('button');
btn.innerText = 'Add sub-items';
btn.addEventListener('click', myAddSubItem, false);
div.appendChild(btn);
return div;
}
function myAddNewItem(evt)
{
var numAlreadyExisting = allByClass('dynamicInput').length; // count number of divs with className = dynamicInput
var newNum = numAlreadyExisting + 1;
var newInputPanel = makeNewItem('Entry ' + newNum);
byId('myForm').appendChild(newInputPanel);
return false;
}
function myAddSubItem(evt)
{
evt.preventDefault(); // stops this button causing the form to be submitted
var clickedBtn = this;
var inputDiv = clickedBtn.parentNode;
var newInput = newEl('input');
inputDiv.appendChild(newInput);
inputDiv.appendChild(clickedBtn);
}
</script>
</head>
<body>
<form id='myForm'>
<div class='dynamicInput'>
<h3>Entry 1</h3>
<input type='text'/><button>Add sub-item</button>
</div>
</form>
<button id='addNewInputBtn'>Add new item</button>
</body>
</html>
I am trying to spawn different div's and remove them after they do their job. A simple version of my code is:
function eraseDiv(){
var c = document.getElementById("cn1");
c.parentNode.removeChild(child);
}
function spawnDiv(){
var x = document.getElementById("test");
var d = document.createElement("div");
d.id = "child";
d.style.width = "500px";
d.style.height = "30px";
var content = "Some text for testing!" + "<a href=\"?\" onclick=eraseDiv(); return false; > Delete</a>";
d.innerHTML = content;
if (document.getElementById("cn1").innerHTML.trim() == "")
document.getElementById("cn1").appendChild(d);
else
document.getElementById("cn2").appendChild(d);
}
<input type="submit" name="Submit" value="Spawn" onclick="spawnDiv(); return false;" />
<div id= "test">
<div id= "cn1"></div>
<div id= "cn2"></div>
</div>'
The problem is that when the first spawned div is deleted, all div's are deleted. Any help is appreciated on how to fix this.
How about something like this:
function eraseDiv(target){
var div = target.parentNode;
var container = div.parentNode;
container.removeChild(div);
}
function spawnDiv(){
var x = document.getElementById("test");
var d = document.createElement("div");
d.style.width = "500px";
d.style.height = "30px";
var content = "Some text for testing!" + "<button onclick=eraseDiv(this);> Delete</button>";
d.innerHTML = content;
if (document.getElementById("cn1").innerHTML.trim() == "")
document.getElementById("cn1").appendChild(d);
else
document.getElementById("cn2").appendChild(d);
}
<button type="button" name="submit" onclick="spawnDiv();">Spawn</button>
<div id= "test">
<div id= "cn1"></div>
<div id= "cn2"></div>
</div>
First thing, since you're returning false every time you obviously don't want to use the submit functionality of your submit input, so change it to a button instead.
Second thing, remove the ID from the spawned div since you should never have two divs with the same ID.
Third thing (like the first thing) since you're not using the link functionality of the anchor element, you should change it to a button instead (using CSS you can style this like an anchor if you want to).
Fourth thing, inside the delete button, add this as a parameter to the eraseDiv function. You can now access the button that was clicked using the function parameter rather than trying to find it by an ID.
The simplest fix to your code without modifying the functionality (and view of the page) of what you did is to replace the href="?" with href="#".
In your original code, when you do something like link with the "?" as the hyperlink, this actually performs a GET request which will reload the page. This is tricky because it makes it seem like your delete code is removing all the spawned divs from both cn1 and cn2 divs.
Changing the href=? to href=# prevents a GET request from happening. Below is a snippet that directly makes this change that results in the correct behavior of your original code (by deleting the spawned element in cn1). You will have to further modify your code to make it do what you want.
function eraseDiv(){
var c = document.getElementById("cn1");
c.parentNode.removeChild(c);
}
function spawnDiv(){
var x = document.getElementById("test");
var d = document.createElement("div");
d.id = "child";
d.style.width = "500px";
d.style.height = "30px";
var content = "Some text for testing!" + "<a href=\"#\" onclick=eraseDiv(); return false; > Delete</a>";
d.innerHTML = content;
if (document.getElementById("cn1").innerHTML.trim() == "")
document.getElementById("cn1").appendChild(d);
else
document.getElementById("cn2").appendChild(d);
}
<input type="submit" name="Submit" value="Spawn" onclick="spawnDiv(); return false;" />
<div id= "test">
<div id= "cn1"></div>
<div id= "cn2"></div>
</div>
Another way of doing it would be to create a id for div like this
<html>
<body>
<input type="submit" name="Submit" value="Spawn" onclick="spawnDiv(); return false;" />
<div id= "test">
<div id= "cn1"></div>
<div id= "cn2"></div>
</div>
<script>
function eraseDiv(j){
var c = document.getElementById('child'+j);
c.parentNode.removeChild(c);
}
var i=1;
function spawnDiv(){
var x = document.getElementById("test");
var d = document.createElement("div");
d.id = "child"+i;
d.style.width = "500px";
d.style.height = "30px";
var content = "Some text for testing!" + "<u ><a onclick=eraseDiv("+i+++"); > Delete</a></u>";
d.innerHTML = content;
if (document.getElementById("cn1").innerHTML.trim() == "")
document.getElementById("cn1").appendChild(d);
else
document.getElementById("cn2").appendChild(d);
}
</script>
</body>
</html>