I have a JavaScript file with a function called "AddCenter(e)" that is called on the click of a button but nothing happens. Can anyone help me?
For some more details, I am using a node.js project, an express server and on online IDE called: Replit. Here is the website url: replit.com
EDIT : So I have modified everything like you guys suggested but still nothing happens.
Here is the link to the part of the website : Website Link
So the url is supposed to change from : https://worldsportcenters.xxgamecodingxx.repl.co/api/v1/im to : https://worldsportcenters.xxgamecodingxx.repl.co/
But instead it goes to the same url but adds a ? at the end of it : https://worldsportcenters.xxgamecodingxx.repl.co/api/v1/im?
Does anyone know why ???
Here is my JavaScript file :
const centers = require('../../models/Center');
const centerName = document.getElementById('center-name');
const centerAddress = document.getElementById('center-address');
const centerDescription = document.getElementById('center-description');
const key = document.getElementById('dev-key');
const submitButton = document.getElementById('submit-button');
function CheckForURL(str)
{
let reg = new RegExp('([a-zA-Z\d]+://)?((\w+:\w+#)?([a-zA-Z\d.-]+\.[A-Za-z]{2,4})(:\d+)?(/.*)?)', 'i')
return reg.test(str)
}
async function AddCenter(e)
{
e.preventDefault();
if (centerName.value === '') return alert('Please fill in the "Sport Center Name" field');
else if (centerAddress.value === '') return alert('Please fill in the "Sport Center Address" field');
else if (centerDescription.value === '') return alert('Please fill in the "Sport Center Description" field');
else if (key.value === '') return alert('Please fill in the "Developper Key" field');
else if (CheckForURL(centerDescription.value)) return alert('You can not put a url in the free marker "Sport Center Description" field');
else if (key.value !== process.env['DEVELOPER_KEY'])
{
alert('You filled in the wrong KEY in the "Sport Center Description" field, and this window will self destruct in 10 seconds');
var timer = setInterval(function() {
window.close();
}, 10000);
return;
}
centers.create({
type: 'informative',
name: centerName.value,
address: centerAddress.value,
description: centerDescription.value
});
if (res.status === 400)
{
throw Error('That sport center already exists !');
}
alert('Center added !');
window.location.href = '/';
}
submitButton.addEventListener("click", function ()
{
AddCenter();
});
The HTML file :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
rel="stylesheet",
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css",
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T",
crossorigin="anonymous"
/>
<title>World Sport Center - Add Center</title>
<link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<div class="text-center">
<div class="container my-3">
<h1 class="display-4 text-center disable-select">Add Informative Marker</h1>
<form id="center-form" class="mb-4">
<div class="form-group">
<blockquote class="blockquote">
<p class="mb-0 disable-select">Sport Center Name</p>
</blockquote>
<input type="text" id="center-name" class="form-control" />
</div>
<div class="form-group">
<blockquote class="blockquote">
<p class="mb-0 disable-select">Sport Center Address</p>
</blockquote>
<input type="text" id="center-address" class="form-control" />
</div>
<div class="form-group">
<blockquote class="blockquote">
<p class="mb-0 disable-select">Sport Center Description</p>
</blockquote>
<textarea type="text" rows="2" id="center-description" class="form-control" maxlength="150"></textarea>
</div>
<div class="form-group">
<blockquote class="blockquote">
<p class="mb-0 disable-select">Developper Key</p>
</blockquote>
<input type="text" id="dev-key" class="form-control" />
</div>
<-- Back
<button id="submit-button" class="btn btn-lg btn-primary">Submit --></button>
</form>
</div>
</div>
<script src="/js/informative.js"></script>
</body>
</html>
onclick="AddCenter"
The value of an onclick attribute is the function body for the event handler.
That makes this, roughly, equivalent to:
theElement.addEventListener("click", function () {
AddCenter;
});
If you want to call the function then you need to do so with ( then any arguments you want to pass, then ).
That said, use addEventListener, intrinsic event attributes have some gotchas and don't separate concerns very well.
Related
In this code I can't make the "All" filter button show me the whole menu!
When the product category filters are placed, they display properly, but once the "All" button is clicked, all the products in the DOM disappear.
I tried everything, inserting and removing elements and structures outside some of the functions, in case it was something out of scope, but nothing.
I believe that between line 66 and 84 the error should be but I have not been able to find what it is.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title></title>
</head>
<body>
<h3>Cheeky Chooks</h3>
<hr>
<div id="divFilterButtons" class="row justify-content-between">
</div>
<div class="m-2">
Serch by ingredient
<input id="searchIngredient">
</div>
<hr>
<div id="menu" class="d-flex flex-row flex-wrap justify-content-center">
</div>
<div id="cartSection" class="bg-warning">
<h3 class="text-center m-2 p-3">
THIS IS YOUR CART
</h3>
<form>
<input id="inputName" class="contactInfo" type="text" placeholder="Enter your name">
<input id="inputAddress" class="contactInfo" type="text" placeholder="Enter your address">
<input id="inputPhone" class="contactInfo" type="number" placeholder="Enter your phone number">
<input id="saveContactBtn" class="" type="submit" value="Save contact info">
</form>
<hr>
<div class="d-flex">
<p class="fs-4 col-1">Quantity</p>
<p class="fs-4 col-2">Name</p>
<p class="fs-4 col-2">Price</p>
<p class="fs-4 col-2">Subtotal</p>`
</div>
<div id="divCart">
</div>
<div id="divCartTotal">
<input type="submit" id="btnPayConfirm" value="Pay & confirm">
</div>
</div>
<div>
FOOTER
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="js/main.js"></script>
</body>
</html>
class Dish {
constructor(id,type,name,principal,otherIngredients,price,img,q){
this.id=id
this.type=type
this.name=name
this.principal=principal
this.otherIngredients=otherIngredients
this.price=parseFloat(price)
this.img=img
this.q=parseInt(q)
}
addq(){
this.q++
}
};
const menuType = [`Chicken`,`Burguers`,`Wraps`,`Meals`,`Sides`];
const menuAll = [];
const cart=[];
let contactDetails =[]
userDetails()
menuAll.push(new Dish(`C-W`,menuType[0],`Whole chicken`,`BBQ chicken`,`free garlic sause`,16.90,`img/ChickenWholeChicken.png`,1));
menuAll.push(new Dish(`C-1/2`,menuType[0],`1/2 chicken`,`BBQ chicken`,`free garlic sause`,9.90,`img/Chicken12.png`,1));
menuAll.push(new Dish(`C-1/4`,menuType[0],`1/4 chicken`,`BBQ chicken`,`free garlic sause`,5.90,`img/Chicken14.png`,1));
menuAll.push(new Dish(`B-CHE`,menuType[1],`Cheeky Burguer`,`Flame grilled chicken`,`cheese - lettuce - Cheeky sauce`,10.90,`img/BurguerCheekyChookBurguer.png`,1));
menuAll.push(new Dish(`B-CHI`,menuType[1],`Chilli Chook Burguer`,`Flame grilled chicken`,`cheese - lettuce - Chilli sauce`,10.90,`img/BurguerChilliChookBurguer.png`,1));
menuAll.push(new Dish(`W-CHE`,menuType[2],`Cheeky Wrap`,`Shredded chicken`,`tomatoe - onion - parsley - pickles - turnip - garlic sause`,11.90,`img/WrapsCheekyWrap.png`,1));
menuAll.push(new Dish(`W-FAL`,menuType[2],`Falafel Wrap`,`Falafel`,`tomatoe - onion - parsley - pickles - turnip - hummus`,11.90,`img/WrapsFalafelWrap.png`,1));
menuAll.push(new Dish(`M-BOX`,menuType[3],`Cheeky Box`,`1/4 Chicken`,`chips - salad - garlic - pickles - turnips`,14.90,`img/MealCheekyBox.png`,1));
menuAll.push(new Dish(`M-PLA`,menuType[3],`Cheeky Plate`,`1/2 Chicken`,`chips - salad - garlic - hummus - baba ghannouj - pickles - turnips - bred`,23.90,`img/MealsCheekyPlate.png`,1));
menuAll.push(new Dish(`S-LFR`,menuType[4],`Cheeky Loades Fries`,`Chips`,`cheese - tabouli - chilli & cheeky sause`,10.90,`img/SidesCheekyLoadesFries.png`,1));
menuAll.push(new Dish(`S-SFR`,menuType[4],`Small chips`,`Chips`,`chicken salt`,4.50,`img/SidesSmallChips.png`,1));
let divMenu = document.getElementById(`menu`);
let divFilterButtons= document.getElementById(`divFilterButtons`);
let searchIngredient= document.getElementById(`searchIngredient`);
let divCart= document.getElementById(`divCart`);
let divCartTotal= document.getElementById(`divCartTotal`);
const saveContactBtn = document.getElementById(`saveContactBtn`);
const btnPayConfirm = document.getElementById(`btnPayConfirm`);
let filterButtons= document.getElementsByClassName(`filterButton`)
//UI
function buttonsUI (list){
divFilterButtons.innerHTML += `<div class="col-2 d-flex justify-content-center"> <button id="All" class="filterButton col-6">All</button> </div>`
for (const type of list) {
divFilterButtons.innerHTML += `<div class="col-2 d-flex justify-content-center"> <button id="${type}" class="filterButton col-6">${type}</button> </div>`
}
}
buttonsUI(menuType);
function menuUI(list) {
divMenu.innerHTML=''
for (const dish of list) {
let div=document.createElement(`div`);
div.className="card col-3 m-3"
div.innerHTML= `<img src="${dish.img}" class="card-img-top" alt="${dish.name}">
<h3>${dish.name}</h3>
<h4>${dish.principal}</h2>
<p>WITH: ${dish.otherIngredients}</p>
<h3>$ ${dish.price}-</h3>
<button id="${dish.id}"class="btnBuyDish btn btn-primary col-3">Buy</button>`
divMenu.append(div);
}
buyBtnClick ()
}
menuUI(menuAll);
//Filters
for (const button of filterButtons) {
if (this.id!="All") {
button.addEventListener('click',function(){
const results= menuAll.filter(dish => dish.type == this.id);
menuUI(results);
})
}else {
menuUI(menuAll);
}
}
searchIngredient.addEventListener(`input`,function(){
const results = menuAll.filter(dish=> dish.otherIngredients.includes(this.value)|| dish.name.includes(this.value) || dish.principal.includes(this.value))
if (results.length >0) {
menuUI(results);
}else{
divMenu.innerHTML='We dont have any dish with it'
}
});
//Contact details
saveContactBtn.addEventListener('click', saveContactDetails);
function saveContactDetails() {
contactDetails=[]
localStorage.removeItem('Contact');
let name = document.getElementById(`inputName`).value
let address = document.getElementById(`inputAddress`).value
let phone = document.getElementById(`inputPhone`).value
if (name!="" && address!="" &&phone!="") {
contactDetails.push(name);
contactDetails.push(address);
contactDetails.push(phone);
localStorage.setItem('Contact',contactDetails)
}
}
function userDetails() {
if ('Contact' in localStorage) {
contactDetails = localStorage.getItem('Contact').split(',')
document.getElementById(`inputName`).value=contactDetails[0]
document.getElementById(`inputAddress`).value=contactDetails[1]
document.getElementById(`inputPhone`).value=contactDetails[2]
}
}
//Cart
function buyBtnClick (){
let btnsBuyDish= document.getElementsByClassName(`btnBuyDish`);
for (const button of btnsBuyDish) {
button.addEventListener(`click`,function(){
let dishChoosed=cart.find(dish=>dish.id == this.id);
if (dishChoosed){
dishChoosed.addq();
}else{
dishChoosed=menuAll.find(dish=>dish.id == this.id);
cart.push(dishChoosed);
}
cartUI(cart)
localStorage.setItem('cart',JSON.stringify(cart));
});
}
}
function cartUI(list){
divCart.innerHTML=""
for (const item of list) {
let div= document.createElement(`div`);
div.className="d-flex"
div.innerHTML=` <p class="col-1">${item.q}</p>
<p class="col-2">${item.name}</p>
<p class="col-2">$${item.price}-</p>
<p id="subtotal" class="col-2">${item.price*item.q}</p>`
divCart.append(div);
}
}
if ('cart' in localStorage) {
const cartList=JSON.parse(localStorage.getItem('cart'))
for (const objet of cartList) {
cart.push(new Dish(objet.id,objet.type,objet.name,objet.principal,objet.otherIngredients,objet.price,objet.img,objet.q))
}
cartUI(cart);
}
btnPayConfirm.addEventListener('click', payConfirm);
function payConfirm() {
localStorage.removeItem('cart')
divCart.innerHTML=`<h4 class="text-center m-5">Thanks for your order. It will arrive soon</h4>`
}
Modify your button eventListener code to this.
for (const button of filterButtons) {
button.addEventListener('click',function(){
if(this.id !== "All" ){
const results= menuAll.filter(dish => dish.type == this.id);
menuUI(results);
}
else{
menuUI(menuAll);
}
})
}
I'm working to create not only a space for recent searches in local storage but also to create a new working button on my main project page once functioning. I am receiving an error message that the "addEventListener("click", buttonClickHandler); call I have at the very bottom of my code cannot read property of "null" so I'm wondering where I went wrong in the starting piece. I have tried to rework this piece of JS so many times now and I'm just not sure where to go from here at this point. Any advice?
var cityFormEl = document.querySelector("#city");
var cityNameInputEl = document.querySelector("#location");
var dateFormEl = document.querySelector("#date");
var dateNameInputEl = document.querySelector("#today");
var historyButtonsEl = document.querySelector("#search-item");
var historyCardEl = document.querySelector("#recent-searches");
var trashEl = document.querySelector("#trash");
var searchHistoryArray = []
var formSubmitHandler = function (event) {
event.preventDefault();
// get city name value from input element
var cityBtn = cityNameInputEl.value.trim();
// Set city name in local storage and generate history buttons
if (cityBtn) {
searchHistoryArray.push(cityBtn);
localStorage.setItem("citySearch", JSON.stringify(searchHistoryArray));
localStorage.setItem("dateSearch", JSON.stringify(searchHistoryArray));
var searchHistoryEl = document.createElement('button');
searchHistoryEl.className = "btn";
searchHistoryEl.setAttribute("data-city", "data-date", cityBtn)
searchHistoryEl.innerHTML = cityBtn;
historyButtonsEl.appendChild(searchHistoryEl);
historyCardEl.removeAttribute("style")
cityNameInputEl.value = "";
}
else {
alert("Please enter a Date and a City name");
}
}
// Load any past city searches
var loadHistory = function () {
searchArray = JSON.parse(localStorage.getItem("citySearch"));
if (searchArray) {
searchHistoryArray = JSON.parse(localStorage.getItem("citySearch", "dateSearch"));
for (let i = 0; i < searchArray.length; i++) {
var searchHistoryEl = document.createElement('button');
searchHistoryEl.className = "btn";
searchHistoryEl.setAttribute("data-city", "data-date", searchArray[i])
searchHistoryEl.innerHTML = searchArray[i];
historyButtonsEl.appendChild(searchHistoryEl);
historyCardEl.removeAttribute("style");
}
}
}
// Search using search history buttons
var buttonClickHandler = function (event) {
var cityBtn = event.target.getAttribute("data-city", "data-date",);
if (cityBtn) {
formSubmitHandler(cityBtn);
}
}
// Clear Search History
var clearHistory = function (event) {
localStorage.removeItem("citySearch", "dateSearch");
historyCardEl.setAttribute("style", "display: none");
}
cityFormEl.addEventListener("submit", formSubmitHandler);
historyButtonsEl.addEventListener("click", buttonClickHandler);
trashEl.addEventListener("click", clearHistory);
loadHistory();
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Adventure Time</title>
<link rel="stylesheet" href="../adventure-time/assets/css/styles.css" />
<link rel="stylesheet" href="../adventure-time/build/styles.css" />
</head>
<body>
<header>
<nav class="flex justify-between items-center">
<a href="#"><img class="max-w-xs p-8" src="../adventure-time/assets/img/adventure-time-logo-reverse.png"
alt="Logo of Adventure Time" /></a>
Recent Searches
</nav>
<section class="hero">
<div class="hero-statement">
<h2>
Your <span id="adventure"> Adventure</span> <br />
Starts here
</h2>
<p>Enter a time and place to start your journey</p>
<br />
</div>
<form class="search-input flex justify-between">
<div id="date">
<input type="date" id="today" name="date" value="2021-08-01" min="2021-08-01" max="2022-12-31"
class="date-input cst-btn cst-btn-lft">
</div>
<div class="time-input cst-btn cst-btn-cntr"><input type="time" id="time" name="time" min="07:00"
max="22:00" required></div>
<div class="location-input cst-btn cst-btn-cntr">
<div id="city">
<label>City</label>
<input id="location" type="text" tabindex="3" name="city">
</div>
</div>
<button class="cst-btn cst-btn-rgt" id="search"><a href=adventure.html>Find my Adventure</a></button>
</form>
</section>
<!-- HERO END -->
</header>
<main class="m-auto w-3/4">
<div id="recent-searches">
<h2 class="text-black text-4xl text-center">Recent Searches</h2>
<div class="recent-searches flex justify-around">
<div class="search-item">
<h4>Los Angeles, CA</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>Portland, OR</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>New York, NY</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>Vancouver, BC</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
</div>
</div>
</div>
</main>
<footer class="main-footer">
<h5>Made with ❤️  by Team Awesome</h5>
</footer>
<script src="../adventure-time/assets/js/script.js"></script>
</body>
</html>
I ran your code and got this error (although I am not entirely sure if this is what you are referencing):
Uncaught TypeError: historyButtonsEl is null
The reason this TypeError is being thrown lies in this line of your JS:
var historyButtonsEl = document.querySelector("#search-item");
You are selecting for an element that has an ID equal to 'search-item'; however, the only reference to 'search-item' in your html is a class. To fix this, simply do:
var historyButtonsEl = document.querySelector(".search-item");
Notice the '.' instead of a '#'. '#' select ids whereas '.' select classes. Also, although I am unsure what you are trying to select with this querySelector(), I ought to warn you that selecting classes with querySelector() will return the first found element with that class and not all elements with that class (to do that use querySelectorAll()). Hopefully this helped.
I'm working on a project that requires a PayPal payment gateway. I found a simple tutorial online that works fine, with the exception that the PayPal Response is sent to the console log. Looking online for any instance were the then() function is used for other than logging to console came up empty. The present code:
return actions.order.capture().then(function (details) {
console.log(details);
needs to be changed, to a function other than then() in order to send the JSON object to the PHP processing page. Being a backend developer, I'm not sure what function that will be. Can anyone make a suggestion please? The entire code is as follows:
The HTML & JS Script
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Paypal Payment</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main id="cart-main">
<div class="site-title text-center">
<h3 class="font-title">Shopping Cart</h3>
</div>
<div class="container">
<div class="grid">
<div class="col-1">
<div class="flex item justify-content-between">
<div class="flex">
<div class="img text-center">
<img src="./assets/pro1.png" alt="">
</div>
<div class="title">
<h3>Canon EOS 1500D</h3>
<span>Electronics</span>
<div class="buttons">
<button type="submit"><i class="fas fa-chevron-up"></i> </button>
<input type="text" class="font-title" value="1">
<button type="submit"><i class="fas fa-chevron-down"></i> </button>
</div>
Save for later |
Delete From Cart
</div>
</div>
<div class="price">
<h4 class="text-red">$349</h4>
</div>
</div>
</div>
<div class="col-2">
<div class="subtotal text-center">
<h3>Price Details</h3>
<ul>
<li class="flex justify-content-between">
<label for="price">Products ( 1 item ) : </label>
<span>$399</span>
</li>
<li class="flex justify-content-between">
<label for="price">Delivery Charges : </label>
<span>Free</span>
</li>
<hr>
<li class="flex justify-content-between">
<label for="price">Amout Payble : </label>
<span class="text-red font-title">$399</span>
</li>
</ul>
<div id="paypal-payment-button">
</div>
</div>
</div>
</div>
</div>
</main>
<script src="https://www.paypal.com/sdk/js?client-id=ASbdZ8CH5kN5y98rzOuKMLPYsHl4QHLYcDGJ6lgaRjxiRp97t53sPWr1yG5vyd9mlHbyqw3vGUZaJsok&disable-funding=credit,card"></script>
<script>
// Create a Global var - the HTML charge is dummy stuff
window.charge = 0.27;
paypal.Buttons({
style : {
color: 'blue',
shape: 'pill'
},
createOrder: function (data, actions) {
return actions.order.create({
purchase_units : [{
amount: {
value: window.charge
}
}]
});
},
onApprove: function (data, actions) {
return actions.order.capture().then(function (details) {
console.log(details);
window.location.replace("https://localhost/PayPal_Simple/payPalResponse.php?q=good");
window.alert('This was successful.');
})
},
onCancel: function (data) {
window.location.replace("https://localhost/PayPal_Simple/payPalResponse.php?q=bad");
window.alert('Something went wrong!');
}
}).render('#paypal-payment-button');</script>
</body>
</html>
The PHP
<?php
// Get the Response from PayPal
$status = $_GET['q'];
// Once there is an object that can be tested, that will be used instead of ?q=
if($status = "good") {
echo "The payment was a success.<br />";
} elseif($status = "bad") {
echo "The charge was cancelled.";
} else {
echo "Something else went wrong.";
}
// Of course, this doesn't display anything
echo '<pre>';
print_r($_POST);
echo '<pre>';
// Insert data into the database
// Redirect the client to another page
?>
Thanks so much in advance for your help!
Cheers,
Rick
Do not capture on the client side and then send data to a backend. Instead, change to a proper server-side integration--the backend should be communicating with PayPal itself and sending data to the client on request.
Make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return only JSON data (no HTML or text). The latter one should (on success) store the payment details in your database before it does the return (particularly purchase_units[0].payments.captures[0].id, the PayPal transaction ID)
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
As This link reads , try using
onApprove
''''
const onApprove= new Promise((resolve, reject) => {
{resolve((data,actions) => {actions.order.capture(data,actions)}});
});
''''
buttonPushFunction
''''
async function doYourButtonPush() {
try {
await onApprove;
console.log("The Promise is resolved!", value);
} catch (e) {
console.error("The Promise is rejected!", error);
} finally {
function (details) {
console.log(details);
window.location.replace("https://localhost/PayPal_Simple/payPalResponse.php?q=good");
window.alert('This was successful.');
}
}
}
''''
I am building a web tool for authors that follows a format we need for our backend. I didn't like a number of pre-made solutions for rich text editors as they were having way more features than I would need so I decided to parse my text through a function to detect bold using ** in the text.
I came across a regex solution here and when I used it, it detected the bold text and substituted * for <b> but displayed the tags instead of making the text between <b> and </b> bold.
I am new to HTML, CSS and JS so probably this is a simple error, but I couldn't find out how to deal with it myself...
// Tracks number of current textareas i.e. paragraphs
var element_counter = 0;
// Add Paragraph on button press
document.getElementById("addParagraph").addEventListener("click", function() {
var textarea = document.createElement("textarea");
var text = "Here goes your new paragraph.";
var node = document.createTextNode(text);
textarea.setAttribute("id", element_counter);
//textarea.setAttribute("class", "flow-text");
//textarea.setAttribute("oninput", "this.style.height = '';this.style.height = this.scrollHeight + 'px'");
textarea.append(node);
var section = document.getElementById("editor");
section.appendChild(textarea);
element_counter++;
reloadPreview();
});
// Add Image on button press
document.getElementById("addImage").addEventListener("click", function() {
var image = document.createElement("input");
image.setAttribute("type", "file");
image.setAttribute("id", element_counter);
image.setAttribute("accept", "image/*");
image.setAttribute("class", "file-field input-field");
var section = document.getElementById("editor");
section.appendChild(image);
element_counter++;
});
// Remove paragraph with confirmation step on button press
var confirm = false;
document.getElementById("removeLastItem").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirm === false) {
confirm = true;
document.getElementById("removeLastItem").innerHTML = "Confirm";
} else {
document.getElementById("removeLastItem").innerHTML = "Remove last item";
var element = document.getElementById(element_counter-1);
element.parentNode.removeChild(element);
confirm = false;
element_counter--;
reloadPreview();
}
}
});
// Remove all with confirmation step on button press
var confirmRemoveAll = false;
document.getElementById("removeAll").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirmRemoveAll === false) {
confirmRemoveAll = true;
document.getElementById("removeAll").innerHTML = "Confirm";
} else {
document.getElementById("removeAll").innerHTML = "Remove all";
var element = document.getElementById("editor").innerHTML = ""
confirmRemoveAll = false;
element_counter = 0;
reloadPreview();
}
}
});
// Preview on button press
document.getElementById("previewButton").addEventListener("click", reloadPreview);
// Preview current document status
function reloadPreview() {
// Clear previous preview
document.getElementById("preview").innerHTML = "";
// Add elements iteratively
var section = document.getElementById("preview");
const id = "preview";
for (var counter = 0; counter < element_counter; counter++) {
var type = document.getElementById(counter).nodeName;
// If text element
if (type === "TEXTAREA") {
var paragraph = document.createElement("p");
var text = document.getElementById(counter).value;
var richtext = boldText(text);
paragraph.setAttribute("id", id + counter);
paragraph.setAttribute("class", "flow-text");
paragraph.innerHTML = richtext;
section.appendChild(paragraph);
}
// If image element
if (type === "INPUT") {
// This weird structure allows to render item by item into preview and not mix up the order as onload is otherwise too slow
(function() {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
reader.onload = function(e) {
image.setAttribute("src", e.target.result);
}
reader.readAsDataURL(file);
}())
}
}
}
function boldText(text){
var bold = /\*\*(\S(.*?\S)?)\*\*/gm;
var richtext = text.replace(bold, '<b>$1</b>');
return richtext;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Climate Science</title>
<!--Used to unify web page appearance and this preview appearance-->
<link type="text/css" href="/css/materialize.css" rel="stylesheet">
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<link type="text/css" href="/css/mystyles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap" rel="stylesheet">
<script href="text/javascript" src="/js/materialize.js"></script>
<link rel="manifest" href="/manifest.json">
<!-- IOS Support -->
<link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
<link rel="apple-touch-icon" href="/img/icons/icon-152x152.png">
<meta name="apple-mobile-web-app-status-bar" content="#5368ff">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="#5368ff">
</head>
<body class="grey lighten-5">
<header>
<!-- top nav -->
<div class="navbar-fixed">
<nav class="z-depth-2">
<div class="nav-wrapper">
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Log out</li> <!--TODO needed?-->
</ul>
</div>
</nav>
</div>
</header>
<div class="container">
<h3>Editor Area</h3>
<p><b>Linebreaks</b> within paragraphs are currently <b>ignored</b> to follow our internal database format.</p> <!--TODO check if accurate, \n possible integratable?-->
<!--
<h6>Safety switch</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>You can only remove paragraphs while the switch is deactivated!</p>
<h6>Auto-preview</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>The preview will load automatically while you edit your text</p>
<br>
-->
<button id="addParagraph" class="waves-effect waves-light btn">Add new paragraph</button>
<button id="addImage" class="waves-effect waves-light btn">Add new image</button>
<button id="removeLastItem" class="waves-effect waves-light btn">Remove last item</button>
<button id="removeAll" class="waves-effect waves-light btn">Remove all</button>
<div id="editor">
<!-- Here go all the content the author creates-->
</div>
<button id="previewButton" class="waves-effect waves-light btn">Update Preview</button>
<h3>Preview</h3>
<div id="preview">
<!-- Here will be the preview elements when clicking the button -->
<!--
<form action="#">
<p class="flow-text">What changes do you think we're already experiencing? Tap as many that apply</p>
<p>
<label>
<input type="checkbox" />
<span>Raising Sea Levels</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Fewer Heat Waves</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Worse Droughts</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Hotter heat waves</span>
</label>
</p>
<button class="btn waves-effect waves-light btn-large" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</form>
-->
</div>
</div>
<script href="text/javascript" src="js/preview.js"></script>
<script href="text/javascript" src="js/ui.js"></script>
</body>
</html>
Hi so perhaps use innerHTML to insert HTML into the tag body? So instead of paragraph.append:
paragraph.innerHTML = richtext;
Trying to make it so that when I refresh the page the previous comments remain on the page. Not quite sure how to do it. Also was wondering how you would go about making it so that when you click on the namebox you don't have to highlight "name" and then write your name, you can just click and what you write simply replaces the "name".
//Functions for Homepage
function imgUpdate() {
var img = document.getElementById("navImg").alt;
if (img === "Cat Selfie") {
document.getElementById("navImg").src = "foo.jpg";
document.getElementById("navImg").alt = "foo"
}
else {
document.getElementById("navImg").src = "cat-selfie.jpg";
document.getElementById("navImg").alt = "Cat Selfie"
}
}
//Functions for Comments
function clearComment(){
$('#txt1').val(''); //short for getElement when using j query
};
function clearName(){
$('#namebox').val('');
};
function saveComment() {
var ctext = $('#txt1').val();
var cname = $('#namebox').val();
if (cname === 'Name') {cname = 'Anon';}
alert('saveComment cname=' + cname + ' ctext=' +ctext);
var d = Date();
var prevComments = $('#cmtlist').html();
var curComment='<p><span class="cmtname">'+cname+ ':' + '</span>'
+ctext +d+' </p>'; //span = add things to something inline
curComment += prevComments;
$('#cmtlist').empty();
$('#cmtlist').append(curComment);
clearComment();
clearName();
setObject('totCmts', curComment);
}
function fetchComments(){
var inlist=getObject('totCmts');
if(inlist === null){
inlist='';
}
//display the comments
$('#cmtlist').empty();
$('#cmtlist').append(inlist);
}
My Html file
<html>
<head>
<meta charset="utf-8" />
<title>Dubya comments</title>
<link rel="stylesheet" href="homepage.css" type="text/css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="homepage.js"></script>
</head>
<body>
<header id="banner">
</header>
<nav>
<button type="button" onclick="clearComment()">Clear
comment</button>
<button type="button" onclick="saveComment()">Save comment</button>
</nav>
<div id="main">
<div id="dtext">
<h4>Your comment</h4>
<input id="namebox" type="text" maxlength="32" size="20"
value="Name" />
<br />
<textarea id="txt1" class="textbox" rows="6"></textarea>
</div>
<h4>Comments</h4>
<div id="cmtlist"></div>
</div>
</body>
</html>
Jack, you can easily store data in localStorage using global object like this:
// your array with comments
var comments = ["First comment", "Second comment"];
// saving your comments in JSON format
window.localStorage.setItem("comments", JSON.stringify(comments));
// retrieving them
comments = JSON.parse(window.localStorage.getItem("comments"));
You can read more about localStorage on MDN