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>
Related
I want to add html elements to the body of my page as an unordered list. I have used DocumentFragment method to create a fragment of the reply button and comment span. Now I need to add a textbox and a add reply to that ul whenever a user clicks on the reply button and add all the replies as a list next to respective comment. Here is what I've tried:
function comment() {
var my_comment = document.getElementById('comments');
my_comment.innerHTML = "<textarea id='user_comment'> </textarea> <button onclick='addNewItem()'>Post Comment</button>";
}
function addNewItem() {
var thediv = document.getElementById("comments_and_replies");
var listItem = document.createElement("ul");
var replyBox = document.createElement("textbox");
var commentSpan = document.createElement("span");
var user_comment = document.getElementById('user_comment');
var replyButton = document.createElement("button");
listItem.className = "comments-list";
replyButton.innerText = "Reply";
replyButton.className = "reply";
replyButton.addEventListener("click", function() {
var g = document.getElementById('comments_and_replies');
for (var i = 0, len = g.children.length; i < len; i++) {
(function(index) {
g.children[i].onclick = function() {
listItem.insertBefore(replyBox, listItem.children[index]);
}
})(i);
}
})
commentSpan.textContent = user_comment.value;
var documentFragment = document.createDocumentFragment();
documentFragment.appendChild(listItem);
listItem.appendChild(commentSpan);
listItem.appendChild(replyButton);
thediv.appendChild(documentFragment);
}
<section><button onclick="comment()">Leave a comment</button></section>
<div id="comments"></div>
<div id="comments_and_replies"></div>
Event delegation on a single <form> can accommodate an unlimited amount of <button>s even if they are added after the page has loaded.
The example below uses the following:
document.forms
.elements
event.currentTarget
event.target
.matches()
.insertAdjacentHTML()
.previousElementSibling
.parentElement
.remove()
Note: Unless you are submitting data to a server, add type="button" to each <button>
Details are commented in code below
// Refernce <form>
const form = document.forms.commentsReplies;
// Any click on <form> invokes post()
form.onclick = post;
// Pass the event
function post(event) {
/* Reference all <fieldset>
(also <button>, <textarea>, etc) */
const field = event.currentTarget.elements;
// Reference the actual element clicked
const clicked = event.target;
// if element clicked has class postCom
if (clicked.matches('.postCom')) {
/* find <fieldset name="post"> and
insert HTML into it */
field.post.insertAdjacentHTML('beforeEnd', `<fieldset name='commentPost'><textarea></textarea><button class='comTxt' type='button'>Done</button></fieldset>`);
// Otherwise if clicked element has class comTxt
} else if (clicked.matches('.comTxt')) {
/* find the clicked element's element
that is right before it and get it's text */
const text = clicked.previousElementSibling.value;
/* find <fieldset name='comments'> and insert HTML */
field.comments.insertAdjacentHTML('afterBegin', `<fieldset>${text}<button class='postRep' type='button'>Reply</button><ul></ul></fieldset>`);
// Remove <fieldset name='commentPost'>
field.commentPost.remove();
} else if (clicked.matches('.postRep')) {
clicked.insertAdjacentHTML('afterEnd', `<ul><textarea></textarea><button class='repTxt' type='button'>Done</button></ul>`);
} else if (clicked.matches('.repTxt')) {
const text = clicked.previousElementSibling.value;
const list = clicked.parentElement;
list.insertAdjacentHTML('afterBegin', `<li>${text}<button class='postRep' type='button'>Reply</button></li>`);
clicked.previousElementSibling.remove();
clicked.remove();
} else {
return false;
}
}
button {
display: block;
margin-left: 25%;
}
<form id='commentsReplies'>
<fieldset name='post'><button class='postCom' type='button'>Leave a comment</button>
</fieldset>
<fieldset name="comments">
<legend>Comments</legend>
</fieldset>
</form>
I intended to make a todo list but I'm getting a problem that i wanna make a button that come inline in list item like so <li>my task</li><button>Delete</button>
but my delete button isn't deleting items correctly it only deletes one items and then start giving error
this is my code, please look here and also tell me what kind of mistakes I'm doing I'm very beginner in web development
<!DOCTYPE html>
<html>
<body>
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="myFunction()">Try it</button>
<button onclick="deleteTask()">del it</button>
<ol id="myList">
</ol>
<script>
function myFunction() {
var node = document.createElement("LI");
var myTask = document.getElementById("myTask").value;
var textnode = document.createTextNode(myTask);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
var btn = document.createElement("input");
var abcElements = document.querySelectorAll('LI');
for (var i = 0; i < abcElements.length; i++){
abcElements[i].id = 'abc-' + i;
}
// node.setAttribute("id", "li1");
btn.setAttribute("type", "submit");
btn.setAttribute("value", "delete");
btn.setAttribute("id", "delete");
node.appendChild(btn);
btn.addEventListener('click', ()=>{
// console.log("OK");
document.getElementById("abc-0").parentNode.removeChild(document.getElementById("abc-0"))
})
}
function deleteTask() {
var i = 0;
var item = document.getElementsByTagName("LI")[i];
i++;
item.parentNode.removeChild(item);
}
</script>
</body>
</html>
So I just want to make a delete button with every list item as I click on Try it button
Some points to address:
Don't call a function myFuntion. Give it a descriptive name, like addTask
Don't create id-attributes with sequential numbers. That is almost never needed.
The initial HTML should not have a delete button, since it should associate with a list item.
Don't make the type of the delete button "submit". That only makes sense when you have a form element, and need to submit the form.
Don't give the created button the same id over and over again: that is invalid in HTML. id-attributes should have unique values. But again, it is rarely needed to assign an id to dynamically generated elements.
In an event listener you can use the event object to get the element on which the event was fired. Or you can use the this object in a function. But you can also reference the node variable that exists in the so-called closure.
function addTask() {
var node = document.createElement("LI");
node.textContent = document.getElementById("myTask").value;
var btn = document.createElement("button");
btn.textContent = "delete";
btn.addEventListener('click', () => node.remove());
node.appendChild(btn);
document.getElementById("myList").appendChild(node);
}
li > button { margin-left: 5px }
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="addTask()">Add task</button>
<ol id="myList"></ol>
try something like this:
function myFunction() {
const li = document.createElement("li");
li.innerHTML = document.getElementById("myTask").value;
const button = document.createElement("button");
button.innerHTML = "delete";
li.appendChild(button);
button.addEventListener("click", () => li.parentNode.removeChild(li));
document.getElementById("myList").appendChild(li);
}
basically i need to get in real time the quantity of numbers added, depending on whether I add or remove these numbers, but the way i did it has a very annoying delay, assigns the function to the add button and it only updates when it is pressed, so if i add a number by pressing it, it does not update until i add another one and if i remove a number by pressing x nothing happens
// add dozens
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
function childCount() {
var x = document.getElementById("items").childElementCount;
var x = eval(x);
document.getElementById("Result").innerHTML = " " + x + " selected";
}
// Form submit event
form.addEventListener('submit', addItem);
// Delete event
itemList.addEventListener('click', removeItem);
// Add item
function addItem(e) {
e.preventDefault();
// Get input value
var newItem = document.getElementById('item').value;
// Create new li element
var li = document.createElement('li');
// Add class
li.className = 'list-group-item';
// Add text node with input value
li.appendChild(document.createTextNode(newItem));
// Create del button element
var deleteBtn = document.createElement('button');
// Add classes to del button
deleteBtn.className = 'btn btn-danger btn-sm float-right delete';
// Append text node
deleteBtn.appendChild(document.createTextNode('X'));
// Append button to li
li.appendChild(deleteBtn);
// Append li to list
itemList.appendChild(li);
}
// Remove item
function removeItem(e) {
if (e.target.classList.contains('delete')) {
if (confirm('confirme para remover a aposta')) {
var li = e.target.parentElement;
itemList.removeChild(li);
}
}
}
<div id="main">
<form id="addForm">
<div class="sel">select
<input type="number" class="adds" id="item" min="0" max="99" value="0"> </input>
<button onclick="childCount()">add</button>
</div>
</form>
<ul id="items"> </ul>
<div id="Result" value="0">selected</div>
</div>
i make some changes in your code and now its working like you want :
// add dozens
var itemList = document.getElementById('items');
var result = document.getElementById('Result');
var input = document.getElementById('item');
function childCount() {
result.innerHTML = itemList.childElementCount + " selected"
}
// Add item
function addItem(e) {
// Get input value
var newItem = input.value;
// Create new li element
var li = document.createElement('li');
// Add class
li.className = 'list-group-item';
// Add text node with input value
li.appendChild(document.createTextNode(newItem));
// Create del button element
var deleteBtn = document.createElement('button');
// Add classes to del button
deleteBtn.className = 'btn btn-danger btn-sm float-right delete';
deleteBtn.onclick = (e)=>{
removeItem(e);
}
// Append text node
deleteBtn.appendChild(document.createTextNode('X'));
// Append button to li
li.appendChild(deleteBtn);
// Append li to list
itemList.appendChild(li);
childCount();
}
// Remove item
function removeItem(e) {
if (e.target.classList.contains('delete')) {
if (confirm('confirme para remover a aposta')) {
var li = e.target.parentElement;
itemList.removeChild(li);
childCount();
}
}
}
<body onload="childCount()">
<div id="main">
<div class="sel">select
<input type="number" class="adds" id="item" min="0" max="99" value="0"> </input>
<button onclick="addItem()">add</button>
</div>
<ul id="items"> </ul>
<div id="Result" value="0"></div>
</div>
<script src="test.js"></script>
</body>
The exercise says that my button (like a submit) must use the information set by user in input tag and create an li tag with the text as content. It was my first JavaScript class, so I'm still not familiarised with the syntax.
This is my actual code. I used a querySelector with the id of my existing ul tag, and addEventListener to create an event for the click action. I can't remember how to properly create the new li tag, and don't know how to use the content as info for it.
let myElement = document.querySelector('#add-book');
myElement.addEventListener("click", (e) => {
if (e.target.classList == 'button-add') {
let liElement = document.createElement('li');
let content = document.appendChild(liElement);
content.textContent();
}
});
I hope the button works properly, and show the element in the page by clicking the button (with the typed information).
Oversimplified, but hey, it works:
function AddLi(str)
{
var li = document.createElement('li');
li.appendChild(document.createTextNode(str))
li.innerHTML += ' <button onclick="this.parentNode.remove()">-</button>';
document.getElementById("out").appendChild(li);
}
<form>
<input type="text" name="userinput">
<input type="button" value="Add LI" onclick="AddLi(userinput.value)">
</form>
<span id="out"/>
I guess this is what you want:
(function () {
document.querySelector('#add').addEventListener('click', function () {
let input = document.querySelector('#text');
let list = document.querySelector('#list');
let item = document.createElement('li'); // create li node
let itemText = document.createTextNode(input.value); // create text node
item.appendChild(itemText); // append text node to li node
list.appendChild(item); // append li node to list
input.value = ""; // clear input
});
})();
<div>
<input id="text" type="text" />
<button id="add">Add</button>
</div>
<ul id="list">
<li>example item</li>
</ul>
But please, in the future, ask more specific questions. I don't even know what your problem is, because you don't provide all your code. Also the last sentence of your question is telling me nothing useful at all (.. "I hope the button works properly, and show the element in the page by clicking the button (with the typed information) " ..).
Try
function addBook(book) {
list.innerHTML +=
`<li>${esc(book.value)} <button onclick="del(this)">Del</button></li>`;
book.value = '';
}
function del(item) {
item.parentNode.remove();
}
function esc(s) {
return s.replace(/[&"<>]/g,c =>
({'&':"&",'"':""",'<': "<",'>':">"}[c]));
}
<ul id="list"></ul>
<input id="data" type="text" />
<button onclick="addBook(data)">Add</button>
I am new to JavaScript and struck at the point where I am getting errors while inserting two elements, one is-page element and second is Button in the span tag, into one div elements.
document.getElementById('buttonForAddingItemToTheList').addEventListener('click', function() {
var getElementFromTheInput = document.getElementById('inputItemOfHtml').value;
//list item for page
var toCreateTheElementOfList = document.createElement('p');
//button tag
var toCreateTheButton = document.createElement('button');
toCreateTheButton.innerText = "Remove";
//span tag
var toCreateTheSpanForButton = document.createElement('span');
toCreateTheSpanForButton.setAttribute('class', 'classForTheButtonCreateByJavaScript');
//div tag
var toCreateTheElementOfDivContainer = document.createElement('div');
toCreateTheElementOfDivContainer.setAttribute('class', 'divContainerCreatedInJavaScript');
toCreateTheElementOfList.innerText = getElementFromTheInput;
toCreateTheSpanForButton.appendChild(toCreateTheButton);
toCreateTheElementOfDivContainer.appendChild(toCreateTheElementOfLists);
toCreateTheElementOfDivContainer.appendChild(toCreateTheSpanForButton);
document.getElementById('containerToStoreListItem').appendChild(toCreateTheElementOfDivContainer);
});
<input type="text" placeholder="Enter List Item Here..." id="inputItemOfHtml"><br><br>
<button id="buttonForAddingItemToTheList">Add</button><br><br><br>
<div id="containerToStoreListItem">
</div>
There is typo error in your code
toCreateTheElementOfDivContainer.appendChild(toCreateTheElementOfLists);
it should be
toCreateTheElementOfDivContainer.appendChild(toCreateTheElementOfList);
document.getElementById('buttonForAddingItemToTheList').addEventListener('click', function() {
var getElementFromTheInput = document.getElementById('inputItemOfHtml').value;
//list item for page
var toCreateTheElementOfList = document.createElement('p');
//button tag
var toCreateTheButton = document.createElement('button');
toCreateTheButton.innerText = "Remove";
//span tag
var toCreateTheSpanForButton = document.createElement('span');
toCreateTheSpanForButton.setAttribute('class', 'classForTheButtonCreateByJavaScript');
//div tag
var toCreateTheElementOfDivContainer = document.createElement('div');
toCreateTheElementOfDivContainer.setAttribute('class', 'divContainerCreatedInJavaScript');
toCreateTheElementOfList.innerText = getElementFromTheInput;
toCreateTheSpanForButton.appendChild(toCreateTheButton);
toCreateTheElementOfDivContainer.appendChild(toCreateTheElementOfList);
toCreateTheElementOfDivContainer.appendChild(toCreateTheSpanForButton);
document.getElementById('containerToStoreListItem').appendChild(toCreateTheElementOfDivContainer);
});
<input type="text" placeholder="Enter List Item Here..." id="inputItemOfHtml"><br><br>
<button id="buttonForAddingItemToTheList">Add</button><br><br><br>
<div id="containerToStoreListItem">
</div>
You have a typo mistake in third last line
toCreateTheElementOfLists should be toCreateTheElementOfList
toCreateTheElementOfDivContainer.appendChild(toCreateTheElementOfList);
https://jsfiddle.net/2wsuj0fr/