click function not working on class - javascript

I wanted to take input from user in a text area and then parse those sentences in an array and then make each sentence clikcable so that clicked sentence should get copied to another text box. So to achieve this I tried creating span elements in the text area and each span would have class sentence so that on click it would copy that sentence to another text area. But the innerHTML wont produce the spans. Instead it plainly writes it in the textarea as a string.
document.getElementById("go").onclick = function() {
var lines = $('#input').val().split(".");
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var para = document.getElementById("output");
var htmlButton = ' <span class="sentence">' + line + "</span>";
para.innerHTML = para.innerHTML + htmlButton;
}
};
$('.sentence').click(function(e) {
console.log("%00");
var sentence = $(this).text();
$('#textplace').html(sentence);
});
#input {
height: 150px;
font-family: "Courier New", Courier, monospace;
}
.sentence {
font-family: "Courier New", Courier, monospace;
}
body {
margin: 25px;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="alert alert-info" role="alert">Enter multiple lines of things here and it will be converted to a Javascript array format.</div>
<textarea id="input" class="u-full-width" placeholder=""></textarea>
<div id="output"></div>
<input id="go" class="button-primary" type="submit" value="Go!">
<textarea id="textplace"></textarea>
</body>
</html>
After changing the textarea to division, the innerHTML works but the click function on class sentence does not work.

In line number 7 you have done a mistake change
//para.innerHTMl
para.value
Why because you are trying to access the textarea element which is having a attribute value not innerHTML to get the data. You can use innerHTML for 'div','p' tags etc.

Related

How to replace nested span to div element in JQuery?

I'm trying to check whether the given htmlData has nested(parent,child not siblings) span elements with attribute name data-fact or not.
if it does then replace it with span to div with class='inline-span' pass all the attributes with it.
else just return the htmlData
var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
`
replaceTags(htmlData)
function replaceTags (htmlData) {
var $elm = $(htmlData).find("span[data-fact]");
var $nestedElm = $elm.children().length > 1;
if($nestedElm){
htmlData = htmlData.replace(/<span/g, '<div class="inline-span" ');
htmlData = htmlData.replace(/<\/span>/g, '<\/div>');
}else{
return htmlData;
}
},
The output htmlData i want is something like this
<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<div class='inline-span' xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<div class='inline-span' xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</div>
</div>
</p>
Here i'm not able to find is the span element is nested or not and then the conversion of how can i pass the class='inline-span' with all the previous attributes to the div.
PS: answer i want is in JQuery
It is typically a bad idea to do string replacement to change HTML. You should instead use the tools of jquery to manipulate the DOM. Which is safer and less error prone.
const replaceTags = ($tagToReplace) => {
// create a copy of the htmlData
const $cloned = $tagToReplace.clone();
// While there are still more span's in the p
while ($cloned.find('span[data-fact]').length > 0) {
// get the next span to replace with a div
const $span = $($cloned.find('span[data-fact]')[0]);
// create the new div
const $newDiv = $('<div>');
// copy the span's html into the div
$newDiv.html($span.html());
// For each attribute in the span ...
$.each($span[0].attributes, (_ , attr) => {
// ... set the new div to have the span's attribute.
$newDiv.attr(attr.name, attr.value);
});
// new div needs 'inline-span' property.
$newDiv.addClass('inline-span');
// finally replace the span with the new div
$span.replaceWith($newDiv);
}
return $cloned;
}
// select tag to replace
const $tagToReplace = $('p');
// get the new cloned tag
const $newHtmlData = replaceTags($tagToReplace);
// add the cloned to the body
$('body').append($newHtmlData);
// print that new elements html
console.log($newHtmlData[0].outerHTML);
p {
padding: 8px;
border: 1px dashed green;
}
span[data-fact] {
border: 1px solid red;
padding: 3px;
}
div[data-fact] {
border: 1px solid blue;
padding: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
NOTE: it is invalid HTML to have div tag inside p so one should probably replace the p tag too.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script> var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
`
console.log(replaceTags(htmlData, "span span[data-fact]","div"));
//a very handy function from Matt Basta to rplace tag names cannot be done on the fly without such functions
function replaceElement(source, newType) {
// Create the document fragment
const frag = document.createDocumentFragment();
// Fill it with what's in the source element
while (source.firstChild) {
frag.appendChild(source.firstChild);
}
// Create the new element
const newElem = document.createElement(newType);
// Empty the document fragment into it
newElem.appendChild(frag);
// Replace the source element with the new element on the page
source.parentNode.replaceChild(newElem, source);
}
//we now use our function as warper on above function.
function replaceTags (htmlData,whatToChange,withWhat) {
var fragment = document.createElement('just');
fragment.innerHTML=htmlData;
var found = fragment.querySelector(whatToChange);
if(found){
replaceElement(fragment.querySelector(whatToChange), withWhat);}
return fragment.innerHTML;
}
</script>
Getting as to what you want here is more logical solution that mixes bunch of search logics to do the job. Not perfect but its close
I did some changes related to Find in HTML element and in replace jquery code here is a working demo hope it will be helpful for you.
you can direcatly replace all html with like
htmlData = htmlData.replace($factElem[0].outerHTML, 'div html');
using $factElem[0].outerHTML you can find element containing [data-fact] html.
yes you can check only using data-fact and replace it with div there is no span needed
I updated Code Please check now.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("button").click(function () {
var htmlData = '<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f"><span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span></span></p>'
replaceTags(htmlData);
});
});
function replaceTags(htmlData) {
var $factElem = $(htmlData).find('[data-fact]');
if ($factElem) {
htmlData = htmlData.replace($factElem[0].outerHTML, '<div class="inline-span" xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><div class="inline-span" xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</div></div>');
$("#append").empty().append(htmlData);
alert(htmlData);
} else {
$("#append").empty().append(htmlData);
}
}
</script>
</head>
<body>
<div id="append"></div>
<button>Click me to Replace!!</button>
</body>
</html>

How to create element within for loop in Javascript

I have one text box and one button in my code. I want to let the user to enter a text and click the button. If so a card will be created with the user entered text, and the background color of the card will be set using a json file.
But in my code if the user clicks the button for the second time, previously created card disappears and a new card is being created leaving the space of previously created card. But I want all the cards to be aligned one below one.
I think this can be done using a loop function by setting different ids to each card. Unfortunately I am not able to do it properly.
I am attaching my code here, please someone help me with this.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Task</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link rel = "stylesheet" href = "css/style.css" type = "text/css">
</head>
<body>
<h2>Creative Handle Task Assignment</h2>
<input type="text" name="text" id="text" placeholder="Enter your text here...">
<button id="btn">Click</button>
<div class="flex-container" id="container">
</div>
<script src="js/custom_script.js" type="text/javascript"></script>
</body>
</html>
style.css
.flex-container {
display: flex;
flex-direction: column-reverse;
justify-content: center;
align-items: center;
}
.flex-container > div {
/*background-color: DodgerBlue;*/
color: white;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
custom_script.js
const subBtn = document.getElementById("btn");
const inptTxt = document.getElementById("text");
const contDiv = document.getElementById("container");
subBtn.disabled = true
inptTxt.addEventListener('input', evt => {
const value = inptTxt.value.trim()
if (value) {
inptTxt.dataset.state = 'valid'
subBtn.disabled = false
} else {
inptTxt.dataset.state = 'invalid'
subBtn.disabled = true
}
})
var xhttp = new XMLHttpRequest();
subBtn.addEventListener("click",function(){
var crd = document.createElement("div");
crd.setAttribute("id", "card");
crd.innerHTML = inptTxt.value;
contDiv .appendChild(crd);
xhttp.onreadystatechange=function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("card").style.background = JSON.parse(this.responseText).color;
}
};
xhttp.open("GET","http://api.creativehandles.com/getRandomColor","" ,true);
xhttp.send();
})
Each time you create a new element you give it the id of card. You can't have multiple html elements with the same id. You should use crd.setAttribute("class", "card");' instead. The external stylesheet you load has styling for the class .card but not for id #card.
You can not give id to more one html tag.
Instead of id use class attribute i.e.
crd.setAttribute("class", "card");

Button Clicked change Colour

So little bit stuck here, I have several buttons that I want to do separate actions. For example of someone clicks the colour green it changes the paragraph text colour to green, I accomplished the first one but I can't seem to work others, what's the correct way to do it?
//JS:
function myFunction() {
var p = document.getElementById("paragraph"); // get the paragraph
document.getElementById("paragraph").style.color = "green";
var p = document.getElementById("paragraph"); // get the paragraph
document.getElementById("Bluecolour").style.color = "blue";
}
<!doctype html>
<html lang="en">
<head>
<title> Change Paratext </title>
<meta charset="utf-8">
<script src="task2.js"></script>
<style>
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 200px;
overflow: hidden;
margin-top: 10px;
}
</style>
</head>
<body>
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="myFunction()" id="GreenColour">Green</button><!-- Changes text to Green -->
<button type="button" onclick="myFunction()" id="Bluecolour">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="myFunction()" id="Mono">Mono</button> <!-- Changes text to Mono -->
<button type="button" onclick="myFunction()" id="Sans Serif">Sans Serif</button> <!-- Changes text to Sans Serif -->
<button type="button" onclick="myFunction()" id="Serif">Serif</button> <!-- Changes text to Serif -->
<button type="button" onclick="myFunction()" id="SizeAdd">Size++</button> <!-- This button increases size by 1 every time its clicked -->
<button type="button"onclick="myFunction()" id="SizeMinus">Size--</button> <!-- This button decreases size by 1 every time its clicked -->
</p>
</div>
</body>
</html>
Your myFunction() doesn't know what it need to do when it has been called.
Try this entry level code, simply declare few function to change the text color:
function blue() {
var p = document.getElementById("paragraph"); // get the paragraph
p.style.color= 'blue'
}
function green() {
var p = document.getElementById("paragraph"); // get the paragraph
p.style.color= 'green'
}
function mono(){
var p = document.getElementById("paragraph"); // get the paragraph
p.style.fontFamily = "monospace"
}
<!doctype html>
<html lang="en">
<head>
<title> Change Paratext </title>
<meta charset="utf-8">
<script src="task2.js"></script>
<style>
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 100px;
overflow: hidden;
margin-top: 10px;
}
</style>
</head>
<body>
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="green()">Green</button><!-- Changes text to Green -->
<button type="button" onclick="blue()">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="mono()">Mono</button><!-- Changes text to monospace-->
</p>
</div>
</body>
</html>
There are different ways to do that,
name distinct function name for distinct button id and set the background according to that
call the same function but this time inside the function pass a parameter of button ID
button type="button" onclick="myFunction(this.id)" id="GreenColour">Green
and the function is:
function myFunction(id) {
if(id=="GreenColour")
document.getElementById("paragraph").style.color="green"; // get the paragraph
//document.getElementById("paragraph").style.color = "green";
else if(id=="BlueColour")
document.getElementById("paragraph").style.color=blue; // get the paragraph
//document.getElementById("Bluecolour").style.color = "blue";
}
You could separate the logic into different functions and pass values as arguments to them:
const paragraph = document.getElementById("paragraph");
let fontSize = 1;
function setStyle(style, value) {
paragraph.style[style] = value;
}
function incrementSize(value) {
fontSize += value
paragraph.style.fontSize = `${fontSize}em` ;
}
<!doctype html>
<html lang="en">
<head>
<title> Change Paratext </title>
<meta charset="utf-8">
<script src="task2.js"></script>
<style>
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 200px;
overflow: hidden;
margin-top: 10px;
}
</style>
</head>
<body>
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="setStyle('color', 'green')" id="GreenColour">Green</button><!-- Changes text to Green -->
<button type="button" onclick="setStyle('color', 'blue')" id="Bluecolour">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="setStyle('font-family', 'monospace')" id="Mono">Mono</button> <!-- Changes text to Mono -->
<button type="button" onclick="setStyle('font-family', 'sans-serif')" id="Sans Serif">Sans Serif</button> <!-- Changes text to Sans Serif -->
<button type="button" onclick="setStyle('font-family', 'serif')" id="Serif">Serif</button> <!-- Changes text to Serif -->
<button type="button" onclick="incrementSize(+0.1)" id="SizeAdd">Size++</button> <!-- This button increases size by 1 every time its clicked -->
<button type="button"onclick="incrementSize(-0.1)" id="SizeMinus">Size--</button> <!-- This button decreases size by 1 every time its clicked -->
</p>
</div>
</body>
</html>
Updated code using SWITCH case
//JS:
function myFunction(btnColor) {
var p = document.getElementById("paragraph"); // get the paragraph
switch(btnColor){
case 'green':
document.getElementById("paragraph").style.color = "green";
break;
case 'blue':
document.getElementById("paragraph").style.color = "blue";
break;
case 'mono':
document.getElementById("paragraph").style.color = "mono";
break;
case 'sansserif':
document.getElementById("paragraph").style.fontFamily = "Sans Serif";
break;
case 'serif':
document.getElementById("paragraph").style.fontFamily = "serif";
break;
case 'sizeadd':
var el = document.getElementById('paragraph');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = parseFloat(style);
el.style.fontSize = (fontSize + 1) + 'px';
document.getElementById("paragraph").style.fontSize = "serif";
break;
case 'sizeminus':
var el = document.getElementById('paragraph');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = parseFloat(style);
el.style.fontSize = (fontSize - 1) + 'px';
break;
}
}
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 20px;
overflow: hidden;
margin-top: 10px;
}
<!doctype html>
<html lang="en">
<body>
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="myFunction('green')" id="GreenColour">Green</button><!-- Changes text to Green -->
<button type="button" onclick="myFunction('blue')" id="Bluecolour">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="myFunction('mono')" id="Mono">Mono</button> <!-- Changes text to Mono -->
<button type="button" onclick="myFunction('sansserif')" id="Sans Serif">Sans Serif</button> <!-- Changes text to Sans Serif -->
<button type="button" onclick="myFunction('serif')" id="Serif">Serif</button> <!-- Changes text to Serif -->
<button type="button" onclick="myFunction('sizeadd')" id="SizeAdd">Size++</button> <!-- This button increases size by 1 every time its clicked -->
<button type="button"onclick="myFunction('sizeminus')" id="SizeMinus">Size--</button> <!-- This button decreases size by 1 every time its clicked -->
</p>
</div>
</body>
</html>
the easiest way is to create function with parameter like myFunction(name, value)
var fontSize = 12;
function myFunction(name, value) {
var p = document.getElementById("paragraph");
if (value == 'SizeAdd') {
fontSize += 2;
value = fontSize + 'px';
}
if (value == 'SizeMinus') {
fontSize -= 2;
value = fontSize + 'px';
}
p.style[name] = value;
}
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="myFunction('color', 'green')">Green</button>
<button type="button" onclick="myFunction('color', 'blue')">Blue</button>
<button type="button" onclick="myFunction('fontFamily', 'Mono')">Mono</button>
<button type="button" onclick="myFunction('fontFamily', 'Sans-Serif')">Sans Serif</button>
<button type="button" onclick="myFunction('fontFamily', 'Serif')">Serif</button>
<button type="button" onclick="myFunction('fontSize', 'SizeAdd')">Size++</button>
<button type="button" onclick="myFunction('fontSize', 'SizeMinus')">Size--</button>
</p>
First of all, for caching reasons, it's best to use external CSS and JavaScript. Just make sure you change your CSS and JavaScript file names every time you update the code when you go live. Also, it's a best practice to separate your HTML, CSS, and JavaScript.
Here is some code showing you how to change colors. It should be easy to see that you can just change the paraColor argument, following the design pattern below, to get the results you seek.
//<![CDATA[
/* js/external.js */
var doc, bod, htm, M, I, S, Q, paraColor; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body; htm = doc.documentElement;
M = function(tag){
return doc.createElement(tag);
}
I = function(id){
return doc.getElementById(id);
}
S = function(selector, within){
var w = within || doc;
return w.querySelector(selector);
}
Q = function(selector, within){
var w = within || doc;
return w.querySelectorAll(selector);
}
var para = I('paragraph'), pS = para.style;
paraColor = function(color){
pS.color = color;
}
I('greenColor').addEventListener('click', function(){
paraColor('green');
});
I('blueColor').addEventListener('click', function(){
paraColor('blue');
});
}); // load end
//]]>
/* css/external.css */
html,body{
padding:0; margin:0;
}
.main{
width:980px; margin:0 auto;
}
#paragraph{
height:100px; background-color:silver; padding:10px; border:1px dashed black;
margin:10px 0; overflow:hidden;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Paratext</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='main'>
<h1>Ali Rizwan</h1>
<p id='paragraph'>Box changes text based on what color is clicked</p>
<p id='buttons'>
<input type='button' id='greenColor' value='Green' />
<input type='button' id='blueColor' value='Blue' />
</p>
</div>
</body>
</html>
Here is the full version of all buttons working, you can use switch case so you can use the same code for multiple buttons. I have used switch case
function myFunction(actionType,actionValue,currentButton) {
var increaseDecreaseFactor = 5;
switch (actionType) {
case 'color':
document.getElementById("paragraph").style.color = actionValue;
currentButton.style.color = actionValue;
break;
case 'increaseFont':
txt = document.getElementById("paragraph");
style = window.getComputedStyle(txt, null).getPropertyValue('font-size');
currentSize = parseFloat(style);
txt.style.fontSize = (currentSize + increaseDecreaseFactor) + 'px';
break;
case 'decreaseFont':
txt = document.getElementById("paragraph");
style = window.getComputedStyle(txt, null).getPropertyValue('font-size');
currentSize = parseFloat(style);
txt.style.fontSize = (currentSize - increaseDecreaseFactor) + 'px';
break;
case 'changeFont':
document.getElementById("paragraph").style.fontFamily = actionValue;
break;
default:
break;
}
}
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 200px;
overflow: hidden;
margin-top: 10px;
}
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="myFunction('color','green',this)" id="GreenColour">Green</button><!-- Changes text to Green -->
<button type="button" onclick="myFunction('color','blue',this)" id="Bluecolour">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="myFunction('increaseFont','size++',this)" id="SizeAdd">Size++</button> <!-- This button increases size by 1 every time its clicked -->
<button type="button"onclick="myFunction('decreaseFont','size--',this)" id="SizeMinus">Size--</button> <!-- This button decreases size by 1 every time its clicked -->
<button type="button" onclick="myFunction('changeFont','monospace',this)" id="Mono">Mono</button> <!-- Changes text to Mono -->
<button type="button" onclick="myFunction('changeFont','Sans-Serif',this)" id="Sans Serif">Sans Serif</button> <!-- Changes text to Sans Serif -->
<button type="button" onclick="myFunction('changeFont','Serif',this)" id="Serif">Serif</button> <!-- Changes text to Serif -->
</p>
</div>
First add below link in your head section.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can do above things by this way :
$("button").click(function() {
var Id = $(this).attr('id');
if(Id == 'GreenColour'){
$("#"+Id).css('color','green');
}elseif(Id == 'Bluecolour'){
$("#"+Id).css('color','blue');
}elseif(...){
.....
}else(...){
.....
}
});
and so on. You can perform your different operation based on its ids in if else.
You can do it like this
<button type="button" onclick="myFunction()" id="GreenColour" c_name="green">Green</button><!-- Changes text to Green -->
<button type="button" onclick="myFunction()" id="Bluecolour" c_name="blue">Blue</button><!-- Changes text to Blue -->
function myFunction(evn) {
var color = event.currentTarget.getAttribute('c_name');
document.getElementById("paragraph").style.color = color;
event.currentTarget.style.color = color;
}
set the color name in div as attribute and read that attribute in calling function and use it.
So with your help and others that see this I learned this, essentially the button onclick name can be used in JS to change the text colour, define the button id, create a variable and then default JS to change the colour of paragraph.
HTML:
<!doctype html>
<html lang="en">
<head>
<title> Change Paratext </title>
<meta charset="utf-8">
<script src="task2.js"></script>
<style>
#paragraph {
padding: 10px;
margin-bottom: 10px;
background-color: silver;
border: 1px dashed black;
width: 90%; /* you can adjust this on Firefox if needed */
height: 100px;
overflow: hidden;
margin-top: 10px;
}
</style>
</head>
<body>
<h1> Ali Rizwan </h1>
<p id="paragraph"> Box changes text based on what colour is clicked <br>
<!-- add your buttons here. All buttons should be in one paragraph -->
</p>
<p id="buttons">
<button type="button" onclick="green()">Green</button><!-- Changes text to Green -->
<button type="button" onclick="blue()">Blue</button><!-- Changes text to Blue -->
<button type="button" onclick="mono()">Mono</button><!-- Changes text to monospace-->
<button type="button" onclick="sansserif()">Sans Serif</button><!-- Changes text to Sans Serif-->
<button type="button" onclick="serif()">Serif</button><!-- Changes text to Serif-->
</p>
</div>
</body>
</html>
JS:
function blue() {
var p = document.getElementById("paragraph"); // get the paragraph
p.style.color= 'blue'
}
function green() {
var p = document.getElementById("paragraph"); // get the paragraph
p.style.color= 'green'
}
function mono(){
var p = document.getElementById("paragraph"); // get the paragraph
p.style.fontFamily = 'monospace'
}
function sansserif(){
var p = document.getElementById("paragraph"); // get the paragraph
p.style.fontFamily = 'sans-serif'
}
function serif(){
var p = document.getElementById("paragraph"); // get the paragraph
p.style.fontFamily = 'serif'
}

Broken Javascript Code

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()
}
}

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

Categories