Broken Javascript Code - javascript

I'm trying to create a website where three things happen, but I am stuck.
(1) When the button “ADD” button is clicked it will create a new paragraph
and add it to the output. The contents of the paragraph should come from the text area that is below the [ADD] button.
(2) If the “delete” button is pressed I need to delete the first paragraph in the div.
(3) If the user tries to delete when there are no paragraphs, create an “alert" that says:"No Paragraphs to delete".
I got my JS to put each paragraph into the div, but I'm not really sure how to delete it... Any help would be much appreciated.
window.onload = function() {
var button = document.getElementById("add");
button.onclick = insertItem;
}
function insertItem() {
var added = document.getElementById("output");
var textToAdd = document.getElementById("input");
if (textToAdd.value != "") {
var newp = document.createElement("p");
newp.innerHTML = textToAdd.value;
added.appendChild(newp);
}
}
var deletebutton = document.getElementsByTagName("delete");
deletebutton.onclick = deleteItem;
function deleteItem() {
var output = document.getElementById("output");
var pars = output.getElementsByTagName("p");
if (pars.length > 0) {
output.removeChild(pars[0]);
}
}
#output {
border: blue 5px solid;
padding: 10px;
margin-bottom: 10px;
margin-top: 10px;
width: 50%;
}
#output p {
padding: 10px;
border: black 1px dashed;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" type="text/javascript"></script>
<script src="task3.js"></script>
</head>
<body>
<h2> TASK 3 - Creating, Appending and Deleting Nodes in the DOM Tree </h2>
<p> Type in text below, click add to add as paragraph. <button id="add"> Add </button> </p>
<textarea id="input" rows="10" cols="60">
</textarea><br>
<button id="delete">Delete Last Paragraph</button>
<br><br>
<h2> Added Paragraphs </h2>
<div id="output">
</div>
</body>
</html>

You're fetching the delete button wrong. You're using getElementsByTagName instead of by id.
When deleting, you will probably delete the first <p> you have in your markup that doesnt belong to your output. To fix this you could simply fetch all children of your output div and remove the first one:
function deleteItem() {
let output = document.getElementById('output')
if (output.hasChildNodes()) {
let outputs = output.childNodes
outputs[0].remove()
}
}

Related

How can i get HTML Formated text in this popup box Like: <li> _ _ _ _</li> <br> <h1> _ _ _ _</h1>etc

at this time When text select, The popup show all selected text as in simple format, Like one paragraph. But i want that, the popup should use complete html tag when showing selected text. Like
<li> _ _ _ _</li> <br> <h1> _ _ _ _</h1>etc...
see my code:
const container = document.querySelector('.storypara');
const popupContainer = document.querySelector('.popupContainer');
container.addEventListener('mouseup', (e) => {
const selectedText = window.getSelection().toString();
if (selectedText) {
showPopup(selectedText);
}
});
popupContainer.addEventListener('click', (event) => {
if (event.target.matches('.popupContainer')) {
popupContainer.classList.remove('show');
}
});
function showPopup(selectedText) {
// set the selected text as html inside popup element
document.querySelector('.popup').innerHTML = selectedText;
popupContainer.classList.add('show');
}
body {
margin: 0;
}
.popupContainer {
position: fixed;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.7);
top: 0;
display: none;
align-items: center;
justify-content: center;
color: red;
}
.show {
display: flex;
}
.popup {
background: #fff;
padding: 10px;
border-radius: 3px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
width: 80%;
}
<div class="storypara">
<p><strong>A Bold example Line</strong><br>
Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. </p>
<h2>An Unordered HTML List</h2>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
<h2>An Ordered HTML List</h2>
<ol>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ol>
<p>Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. </p>
</div>
<div class="popupContainer">
<div class="popup"></div>
</div>
How can i get this plz help me. my main purpose
at this time When text select, The popup show all selected text as in simple format, Like one paragraph. But i want that, the popup should use complete html tag when showing selected text. Like
<li> _ _ _ _</li> <br> <h1> _ _ _ _</h1>etc...
Thanks in advance.
Well, not quite what you want, but a lot closer to what you are asking for. Here it goes:
Update your script to be as follows:
<script>
const container = document.querySelector('.storypara');
const popupContainer = document.querySelector('.popupContainer');
// this method is added
// It gives the text of HTML of selected text :)
function getHTMLOfSelection () {
var range;
if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
return range.htmlText;
}
else if (window.getSelection) {
var selection = window.getSelection();
if (selection.rangeCount > 0) {
range = selection.getRangeAt(0);
var clonedSelection = range.cloneContents();
var div = document.createElement('div');
div.appendChild(clonedSelection);
return div.innerHTML;
}
else {
return '';
}
}
else {
return '';
}
}
container.addEventListener('mouseup', (e) => {
const selectedText = getHTMLOfSelection(); // First get the raw HTML text
if (selectedText) {
//selectedText.split("<").join("&lt"); // Now replacing the < so that browser don't render it
//selectedText.split(">").join("&gt"); // Also replacing the > so that browser don't render it
//console.log(selectedText);
showPopup(selectedText); // using the 'xmp' tags around the text, to show the html as it is
}
});
popupContainer.addEventListener('click', (event) => {
if (event.target.matches('.popupContainer')) {
popupContainer.classList.remove('show');
}
});
function showPopup(selectedText) {
// set the selected text as html inside popup element
document.querySelector('.popup').innerHTML = selectedText;
popupContainer.classList.add('show');
}
</script>
I've added a function, which gives you the HTML of the selected text.
This is all you can do to show the HTML to the user. Hope it helps.
Let me know please if it don't work at your end :) Will be happy to help

How can I use method on object which name I have as a string?

I'm coming back with another problem.
I have such code:
HTML
<button>first</button>
<button>second</button>
<div class="first"></div>
<div class="second"></div>
CSS
div{
margin-top: 10px;
width: 100px;
height: 100px;
border:1px solid black;
background-color: #ddd;
}
JS
const btns = document.querySelectorAll("button");
const first = document.querySelector(".first");
const second = document.querySelector(".second");
btns.forEach(btn => btn.addEventListener("click", function(){
this.classList.toggle("pressed");
let selection = this.textContent;
// selection.style.transform = "translate(100px)";
}))
https://codepen.io/ptr11dev/pen/oREymM
I'd like to create one function that'll be responsible for moving respective div to the right side by 100px - I stuck with such problem. Under "selection" I have respective name of div (stored under the same name), but simple code like
selection.style.transform = "translate(100px);"
doesn't work. I know that workaround like creating two functions and using
first.style.transform = "translate(100px);"
and
second.style.transform = "translate(100px);"
would work, but in my main code it's a bit more complicated.
I'll really appreciate any input from your side. Thanks
P.S. I'd like to use Vanilla JS.
You can find them by the class name, assuming that the button text and their class are the same.
const btns = document.querySelectorAll("button");
const first = document.querySelector(".first");
const second = document.querySelector(".second");
btns.forEach(btn => btn.addEventListener("click", function(){
this.classList.toggle("pressed");
let selection = this.textContent;
document.querySelector(`.${selection}`).style.transform = "translate(100px)";
}))
div{
margin-top: 10px;
width: 100px;
height: 100px;
border:1px solid black;
background-color: #ddd;
}
<button>first</button>
<button>second</button>
<div class="first"></div>
<div class="second"></div>
Your problem is textContext is just that TEXT not an object. This sets selection as the first element that matches the class name pulled as this.textContent;
let selection = document.getElementsByClassName(this.textContent)[0];
selection.style.transform = "translate(100px)";

How do you make a button that marks the same word in two div in JS?

illustration of the execution of the button:
You can add mark tag in your Html code with JS. But mark tag works only in HTML5. It will be okay in new Browsers.
Forexample this is your html code:
<div>
Word1 Word2 Word3 Word1
</div>
<div>
Word1
</div>
<input type="button" id="button" value="Click" onclick="" />
This is css code:
div { width:200px;height:200px;border:1px solid black;float:left; }
And this is our javascript code:
var commonWord = 'Word1';
var button = document.getElementById('button');
button.addEventListener('click', function () {
var divs = document.getElementsByTagName('div');
divs[0].innerHTML = divs[0].innerHTML.replace(commonWord, '<mark>' + commonWord + '</mark>');
divs[1].innerHTML = divs[1].innerHTML.replace(commonWord, '<mark>' + commonWord + '</mark>');
});
But this javascript code marks only first words in divs
If you want to mark all words, you can use this:
var commonWord = 'Word1';
var button = document.getElementById('button');
button.addEventListener('click', function () {
var divs = document.getElementsByTagName('div');
divs[0].innerHTML = divs[0].innerHTML.replace(/Word1/g, '<mark>' + commonWord + '</mark>');
divs[1].innerHTML = divs[1].innerHTML.replace(/Word1/g, '<mark>' + commonWord + '</mark>');
});
Welcome to Stack Overflow!, This will work for you -
function myFunction() {
var div = document.getElementsByTagName("span");
div[0].innerHTML += 'Hello';
div[1].innerHTML += 'Hello';
}
div {
display: inline-block;
width: 48%;
float: left;
border: 1px solid;
text-align: center;
height:50px;
}
button {
border: 1px solid;
text-align: center;
margin-top: 30px;
}
<div>
<span></span> world
</div>
<div>
<span></span>
</div>
<button class="button" onclick="myFunction()">Button </button>
Note: Do read How to Ask for tips on asking questions. This is your first time so that's why am answering this question if there is any doubt do ask me in the comments. Hope this is helpful to you.

Method fired multiple times on click event

I'm building a web app in which the user can type in any key word or statement and get in return twenty results from wikipedia using the wikipedia API. AJAX works just fine. When the web app pulls data from wikipedia it should display each result in a DIV created dynamically.
What happens is that, when the click event is fired, the twenty DIVs are created five times, so one hundred in total. I don't know why but, as you can see in the snippet below, the web app creates twenty DIVs for each DOM element that has been hidden (through .hide) when the click event is fired.
Here's is the code:
function main() {
function positive() {
var bar = document.getElementById("sb").childNodes[1];
var value = bar.value;
if (!value) {
window.alert("Type in anything to start the research");
} else {
var ex = /\s+/g;
var space_count = value.match(ex);
if (space_count == null) {
var new_text = value;
} else {
new_text = value.replace(ex, "%20");
//console.log(new_text);
}
url = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=&list=search&continue=-%7C%7C&srsearch=" + new_text + "&srlimit=20&sroffset=20&srprop=snippet&origin=*";
var request = new XMLHttpRequest();
request.open("GET", url);
//request.setRequestHeader("Api-User-Agent", "Example/1.0");
request.onload = function() {
var data = JSON.parse(request.responseText);
render(data);
//console.log(data);
}
request.send();
}
}
function render(data) {
$("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
$("#sb input").css({
"float":"left",
"margin-left":"130px"
});
$("#first_btn").css({
"float":"left"
});
var title = data.query.search[0].title;
var new_text = document.createTextNode(title);
var new_window = document.createElement("div");
new_window.appendChild(new_text);
new_window.setAttribute("class", "window");
var position = document.getElementsByTagName("body")[0];
position.appendChild(new_window);
//}
});
}
var first_btn = document.getElementById("first_btn");
first_btn.addEventListener("click", positive, false);
}
$(document).ready(main);
html {
font-size: 16px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;ù
}
.align {
text-align: center;
}
#first_h1 {
margin-top: 30px;
}
#first_h3 {
margin-bottom: 30px;
}
#sb {
margin-bottom: 10px;
}
#second_h1 {
margin-top: 30px;
}
#second_h3 {
margin-bottom: 30px;
}
.window {
width: 70%;
height: 150px;
border: 3px solid black;
margin: 0 auto;
margin-top: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Wikipedia Viewer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<h1 class="align" id="first_h1">Wikipedia Viewer</h1>
<h3 class="align" id="first_h3">Type in a key word about the topic you are after<br>and see what Wkipedia has for you..</h3>
<p class="align" id="sb">
<input type="text" name="search_box" placeholder="Write here">
<label for="search_box">Your search starts here...</label>
</p>
<p class="align" id="first_btn">
<input type="submit" value="SEND">
</p>
<h1 class="align" id="second_h1">...Or...</h1>
<h3 class="align" id="second_h3">If you just feel eager of random knowledge,<br>punch the button below and see what's next for you...</h3>
<p class="align" id="second_btn">
<input type="submit" value="Enjoy!">
</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery-3.2.1.min.js"><\/script>')
</script>
<script type="text/javascript" src="js/script.js"></script>
</body>
</html>
I made the code easier to read by erasing the for loop. As you can see, even with just one result, it is displayed five times.
Do you know guys why it happens?
thanks
The line:
$("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {})
Says, for every element in this "list", hide the element and run this block of code after hidden.
This code is the culprit:
$("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow",
function() {...});
The callback function is called five times, one for each ID listed, not once for all of them, as you might expect.
A workaround is to create a class (say, "hideme"), apply it to each element you want to hide, and write:
$('.hideme').hide("slow", function() {...});
function render(data) {
$("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
$("#sb input").css({
"float":"left",
"margin-left":"130px"
});
$("#first_btn").css({
"float":"left"
});
}); // Finish it here..
var title = data.query.search[0].title;
var new_text = document.createTextNode(title);
var new_window = document.createElement("div");
new_window.appendChild(new_text);
new_window.setAttribute("class", "window");
var position = document.getElementsByTagName("body")[0];
position.appendChild(new_window);
//}
// }); Move this line..
}
As described in the docs:
complete: A function to call once the animation is complete, called once per matched element.
Which means this line will call the handle function 5 times with 5 matched elements.
$("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
The easiest solution is moving the render codes outside of the hide event handler

Button onclick more than once, different text in javascript

So i made this button, and i made the description text change from
{description}
to "No..." upon clicking. This is what i made:
function changeText(txt){
document.getElementById('name').innerHTML = txt;
}
<p>
<b id='name'>{description}</b>.
</p>
<input type='image'
onclick='changeText("No...")'
src='http://i.imgur.com/4y6bzH9.png'
style="margin-left: 540px; margin-bottom: 20px; position: absolute; outline: none;"/>
If you want, you can view what i did on /http://yosougay.tumblr.com/
I tried to make the description text change another time upon clicking another one time on the same button, so i tried adding another onClick, to make the description text change to "Another text" the next time you click the button.
function changeText(txt){
document.getElementById('name').innerHTML = txt;
}
<p>
<b id='name'>{description}</b>.
</p>
<input type='image'
onclick='changeText("No...")';
onclick='changeText("Another text")';src='http://i.imgur.com/4y6bzH9.png'
style="margin-left: 540px; margin-bottom: 20px; position: absolute; outline: none;" />
I tested it, and it didn't work. Please, is it possible to make a JavaScript button that changes the text to different texts every time it is clicked?
So far, I've only been able two make the text change once.
Try something like this: http://jsfiddle.net/54pp2/2/
<input id="click" type="button" value="click" />
<label id="test">Test</label>
$(document).ready(function () {
var textArray = [];
textArray[0] = 'test 1';
textArray[1] = 'test 2';
textArray[2] = 'test 3';
textArray[3] = 'test 4';
var idx = 0;
$('input#click').on('click', function(){
idx++;
var newidx = idx % textArray.length;
$('label#test').text(textArray[newidx]);
});
});
Sure you can.
You can only bind one click listener that way. Duplicating the attribute onclick will only override the first one, not provide two click listeners.
What you want to do is to handle the "different text every time" in you single onclick listener.
<script>
var txts = ["first", "second", "third"]
var counter = 0;
function changeText() {
document.getElementById('name').innerHTML = txts[counter%3];
counter++;
}
</script>
<p>
<b id='name'>{description}</b>.
</p>
<input type='image'
onclick='changeText()'
src='http://i.imgur.com/4y6bzH9.png'
style="margin-left: 540px;
margin-bottom: 20px;
position: absolute;
outline: none;"/>
I think this what you want
<script>
<!--
$(document).ready(function(){
var textarray ={"No...","Another Text"};
var count = 0;
$('input[type="image"]').click(function(){
$('#name').text(textarray[count]);
count = count==0?1:0;
});
});
// -->
</script>
<p> <b id='name'>{description}</b>. </p>
<input type='image' onclick='changeText("No...")' src='http://i.imgur.com/4y6bzH9.png'
style="margin-left:540px; margin-bottom:20px; position:absolute; outline:none;"/>
<br /><br />
You could keep track of how many times the button has been clicked from inside javascript.
<script>
var clicked = 0;
function changeText(){
if (clicked == 0) {
document.getElementById('name').innerHTML = "No...";
}
else if (clicked == 1) {
document.getElementById('name').innerHTML = "Another text";
}
clicked++;
}
</script>
Notice how I removed the argument from changeText() as well.
Fiddle
My suggestion is to change the onclick to onclick='changeText()'.
Store the texts in an array, and use a count property on the element. This will also move to the first text and repeat, on the third click.
var texts = [
'No',
'Another text'
];
function changeText(){
var elem = document.getElementById('name');
if(typeof elem.count == 'undefined'){
elem.count = 0;
} else {
elem.count++;
}
if(elem.count == texts.length){
elem.count = 0;
}
elem.innerHTML = texts[elem.count];
}

Categories