I can't get the subtotal, tax or total of the food items - subtotal

`<li class="menu-item">
<img src="images/fruitypebblesfrenchtoastwvanillaglaze.jpg"
alt="Fruity Pebbles French toast" class="menu-image">
<div class="menu-item-dets">
<p class="menu-item-heading">Fruity Pebbles French Toast w
vanilla glaze
</p>
<p class="g-price">$17.00</p>
</div>
<button class = "add-button"
data-title = "Fruity Pebbles French Toast w vanilla glaze"
data-price="17.00">Add to Cart</button>
<div class="total"></div>
</li>
<!-- Menu Item 2 -->
<li class="menu-item">
<img src="images/4hawaiianrollsfrenchtoast.jpg" alt="4 Hawaiin
rolls French Toast" class="menu-image">
<div class="menu-item-dets">
<p class="menu-item-heading">4 Hawaiin rolls French Toast
topped w strawberries, bananas, vanilla glaze, whip cream &
powered sugar</p>
<p class="g-price">$16.00</p>
</div>
<button class = "add-button"
data-title = "4 Hawaiin rolls French Toast topped w strawberries,
bananas, vanilla glaze, whip cream & powered sugar"
data-price = "16.00">Add to Cart</button>
<div class = "total"></div>
</li>
<!-- this is the js I created to get subtotal, tax total -->
let subtotal = 0;
price = g-price;
const calculateTax = subtotal => {
const tax = subtotal * 0.13;
const formattedTax = tax.toFixed(2);
return formattedTax;
};
const calculateTotal = subtotal => {
const tax = calculateTax(subtotal);
const total = parseFloat(subtotal) + parseFloat(tax);
const formattedTotal = total.toFixed(2);
return formattedTotal;
};
const getImgLink = title => {
let imgLink;
switch (title) {
case 'Fruity Pebbles French Toast w vanilla glaze':
imgLink =
'https://i.pinimg.com/736x/e9/d2/f9/e9d2f9265ff4c147e2d65d3e90c785ba.jpg';
break;
case '4 Hawaiin rolls French Toast topped w strawberries, bananas,
vanilla glaze, whip cream & powered sugar':
imgLink = 'https://www.bing.com/th?
id=AMMS_854126eb291d301819362a6b9ec7246a&w=164&h=123&rs=2&qlt=80&o=6&cdv=1&dpr=1.45&pid=16.1';
break;
case 'Cinnamon Toast Crunch French Toast w whip cream':
imgLink = 'https://www.foxvalleyfoodie.com/wp-content/uploads/2015/08/capn-crunch-french-toast-with-cinnamon-whipped-cream-recipe.jpg';
break;
case 'Stuffed French Toast caramel & banana cream filling topped w
banana chips, maple syrup & french vanilla ice cream':
imgLink = 'https://www.bing.com/th?id=AMMS_09646475f02c69421e88d828d3fd708a&w=164&h=164&rs=2&qlt=80&o=6&cdv=1&dpr=1.45&pid=16.1';
break;
case 'Stuffed French Toast w strawberries creme filling topped w
` strawberries, bluberries & whip cream':
imgLink = 'https://i2.wp.com/wellplated.com/wp-
content/uploads/2019/04/Best-Overnight-French-Toast-Bake.jpg';
break;
default:
imgLink ='https://i2.wp.com/wellplated.com/wp-
content/uploads/2019/04/Best-Overnight-French-Toast-Bake.jpg';}
return imgLink;
};
$('.add-button').on('click', function () {
const title = $(this).data('title');
const price = $(this).data('price');
const imgLink = getImgLink(title);
const element = `
<li class="cart-item">
<img src="${imgLink}" alt="${title}">
<div class="cart-item-dets">
<p class="cart-item-heading">${title}</p>
<p class="g-price">$${price}</p>
</div>
</li>
`
$('.cart-items').append(element);
subtotal = subtotal + price;
const formattedSubtotal = subtotal.toFixed(2);
const tax = calculateTax(subtotal);
const total = calculateTotal(subtotal);
$('.cart-math').html(`
<p class="cart-math-item">
<span class="cart-math-header">Subtotal:</span>
<span class="g-price subtotal">$${formattedSubtotal}</span>
</p>
<p class="cart-math-item">
<span class="cart-math-header">Tax:</span>
`<span class="g-price tax">$${tax}</span>
`</p>
`<p class="cart-math-item">
<span class="cart-math-header">Total:</span>
<span class="g-price total">$${total}</span>
`</p>
);
});

Related

How to exclude a nested class that is wrapped in the class being retrieved with querySelector

Using Node and Puppeteer to scrape a website.
I'm wanting to return the innerText of a class but there is another span element nested which is returning both.
<div class="inner_sm">
<h1 class="pdp_address ">79 Etwell Street
<span>East Victoria Park, WA 6101</span>
</h1>
<span class="pdp_price">$670,000
<span class="price_feature">Under Offer</span>
</span>
</div>
Target is .pdp_price wanting the result to be '$670,000' but getting '$670,000Under Offer'
const data = await page.evaluate(() => {
const address = document.querySelector('#app > div > div > article > div.pdp_header > div > div > h1').innerText.replaceAll('\n',',')
const bed = document.querySelector('.bed')?.innerText || ""
const bath = document.querySelector('.bath')?.innerText || ""
const car = document.querySelector('.car')?.innerText || ""
const price = document.querySelector('.pdp_price').innerText
return `${address}, ${price}, ${bed}, ${bath}, ${car} \n`
})
I've tried a few things but haven't been able to make it work.
const price = document.querySelector('.pdp_price:not(.price_feature)').innerText
const price = document.querySelector('.pdp_price')?.innerText.replaceAll(',','*') || ""
const cleanPrice = price.remove('.price_feature').innerText

Make a read more Card with reactstrap

So I'm almost wrapping up my personal project, but one thing i'm stuck on is this:
I have a following system, where the user can see all other user's he is following (it's working).
I want to implement it in a way, that he has a reactstrap Card on the left, with a small number of users, and a show more button, which open's up the rest of the users.
This is what I got so far:
The screen :
[![enter image description here][1]][1]
And this is the code which is rendering the users (I got it earlier from a get method):
<div className="following">
<Card body outline color="secondary" >
<CardTitle className = "following-list"><following-list>Following list:</following-list></CardTitle>
<CardBody>
{following.length > 0 &&
following.map(usr => {
// return <p>{usr} </p>
return <div>
<Button className = "button-follow" outline color="primary" onClick = {() =>seachUserHandler(usr)}>{usr}</Button>
</div>
})
}
</CardBody>
</Card>
</div>
CSS code:
.following {
position: absolute;
background: whitesmoke; /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
top:87px;
left:2%;
width:15%;
}
.button-follow{
max-width: 100%;
max-height: 100%;
display: block;
}
.following-list {
color:#3a7bd5;
font-size: large;
}
The onClick on which Button just refers me to the followed usr profile page.
How can I implement the card in such a way that the user would see 3-5 users at the start, and then if he clicks "see more.." button he will see the total list? is it even possible with cards?
UPDATED:
For anyone who wanna use the trick that was suggested in the solution by the great guy below, here is the full working code:
import '../App.css';
import { useHistory } from "react-router-dom";
import React , {useState, useEffect} from 'react';
import {Navbar, NavbarBrand, Button, Input, Card,CardTitle, Col, CardBody} from 'reactstrap'
import { getUserPosts,search,getFollowingUsers,getFollowingUsersPosts } from '../fucntions/user_functions'
function Follow(){
let history = useHistory();
var email;
const [length, setLength] = useState(0)
const [following,setFollowing] = useState([])
const [userSearch, setUserSearch] = useState('')
const [followingPosts, setFollowingPosts] = useState([]);
const [showLess, setShowLess] = useState(false)
const [followingData, setFollowingData] = useState({
isInitial: true,
filteredList: following.slice(0,2),
completeList: following,
});
const showMoreUsers = (_evt /*: SyntheticEvent<Event> */) => {
setFollowingData({
...followingData,
filteredList: following,
isInitial: false
});
setShowLess(true)
}
const showLessUsers = (_evt /*: SyntheticEvent<Event> */) => {
setFollowingData({
...followingData,
filteredList: following.slice(0,2),
isInitial: true
});
setShowLess(false)
}
const moreUsersStyle = {
color: 'rgba(0,0,0,0.5)',
textDecoration: 'underline',
marginTop: '10px'
}
const handleSearchUser = e =>{setUserSearch(e.target.value);};
function handleBack(){
history.goBack()
}
function seachUserHandler(usr) {
var tempPosts;
let toSearch = null
if (typeof(usr) == 'undefined'){
toSearch = {
email: userSearch
}
} else {
toSearch = {
email: usr
}
}
search(toSearch).then(res =>{
if (res.data.code.code !== 0){
window.confirm(res.data.code.message)
} else {
const postsOfUser = {
email: toSearch.email
}
tempPosts = postsOfUser
getUserPosts(tempPosts).then(response =>{
localStorage.setItem('searchedUserPosts', JSON.stringify(response.data))
localStorage.setItem('searchedUser', toSearch.email)
localStorage.setItem('searchedUserName', res.data.user.first_name)
var lengthOfPosts = res.data.user.posts.length
localStorage.setItem('numPosts',lengthOfPosts)
history.push('/profile')
})
}
})
}
function getFollowing(){
const container ={
email: email
}
getFollowingUsers(container).then(res =>{
var data = res.data;
setFollowing(data)
setLength(data.length)
getFollowingPosts(data)
setFollowingData({
...followingData,
filteredList: data.slice(0,2),
completeList: following
})
})
}
function getFollowingPosts(data){
const container ={
data: data
}
getFollowingUsersPosts(container).then(res =>{
var data = res.data;
setFollowingPosts(data)
console.log(data)
})
}
useEffect(() =>{
if (localStorage.getItem("usertoken") === null) {
history.push('/errorPage')
} else {
const _email = localStorage.getItem('useremail')
email = _email
localStorage.removeItem('searchedUser') //used to delete the last profile searched
localStorage.removeItem('searchedUserPosts') // used to delete the last profile searched post from cache
getFollowing()
};
},[]);
return (
<div className="box">
<div>
<Navbar color="light" light expand="lg" className="justify-content-flex" style={{ padding: "5" }}>
<div className="header-home">
<NavbarBrand type="text">inTouch</NavbarBrand>
</div>
<div>
<Col>
<Input id="usr" name="user1" type="text" value={userSearch} placeholder="Enter user's email..." onChange={handleSearchUser}></Input>
</Col>
</div>
<div>
<Col>
<Button outline color="primary" onClick={() => seachUserHandler()}>Search</Button>
</Col>
</div>
<div>
<Col>
<NavbarBrand type="button" onClick={handleBack}>Back</NavbarBrand>
</Col>
</div>
</Navbar>
<div className="feed">
<Card body outline color="secondary" >
<CardTitle className = "following-list text-center"><following-list>Feed</following-list></CardTitle>
<CardBody className = "text-center">
Welcome to your feed! Catch up with the people you follow.
</CardBody>
</Card>
</div>
<div className="following">
<Card body outline color="secondary" >
<CardTitle className = "following-list text-center"><following-list>Following list:</following-list></CardTitle>
<CardBody className = "text-center">
{followingData.filteredList.length > 0 &&
followingData.filteredList.map(usr =>
<div>
<Button className = "button-follow"
outline
color="primary"
onClick = {() => seachUserHandler(usr)}>{usr}</Button>
</div>
)
}
{followingData.isInitial ?
<p onClick={showMoreUsers} style={moreUsersStyle}>Show all users...</p>
: null
}
{showLess ?
<p onClick={showLessUsers} style={moreUsersStyle}>Show less...</p>
: null
}
</CardBody>
</Card>
</div>
<div className="wrapper-all-posts">
{length > 0 &&
followingPosts.map(post => {
return <Card body outline color="secondary" className="card-home " >
<CardTitle>Posted at : {post.createdAt} By : {post.email}</CardTitle>
<CardBody>{post.post}</CardBody>
</Card>
})
}
</div>
</div>
</div>
)
}
export default Follow;
Stackblitz demo
The overall idea is using a filtered list in the component. Take a look at the code below.
const {followings} = props;
...
const [followingData, setFollowingData] = useState({
isInigial: true,
filteredList: followings.slice(0,6),
completeList: followings,
});
const _showMoreUsers = (_evt /*: SyntheticEvent<Event> */) => {
setFollowgingData({
...followingData,
filteredList: followingData.completeList,
isInitial: false
});
}
const moreUsersStyle = {
color: 'rgba(0,0,0,0.5)',
textDecoration: 'underline',
marginTop: '10px'
}
...
<div className="following">
<Card body outline color="secondary" >
<CardTitle className="following-list">
<following-list>Following list:</following-list>
</CardTitle>
<CardBody>
{followingData.filteredList.length > 0 &&
followingData.filteredListfollowing.map(usr =>
<div>
<Button className = "button-follow"
outline
color="primary"
onClick = {() => seachUserHandler(usr)}>{usr}</Button>
</div>
)
}
{followingData.isInitial ?
<p onClick={_showMoreUsers} style={moreUsersStyle}>Show More...</p>
: null
}
</CardBody>
</Card>
</div>

State is not upating in renderer() component

I'm very new to react JS, and I am using it to build a app now. I have a question.
In of of the Button Click event i have a code logic like this:
handlestartbutton(event) {
const accesskey = localStorage.getItem(localStorageKeys.accessTokenKey);
const decodedAccessKey = jwt_decode(accesskey);
const date = dateConverter.epochToReadableDate(decodedAccessKey.exp);
if (date.currentTime < date.expiryDate) {
this.setState({
accesstokenexpirydate: true
}, () => {
if(this.state.accesstokenexpirydate === false) {
//rest of the code
}
})
In renderer() i have a a pop up UI like this:
renderer()
{
{this.state.accesstokenexpirydate === true ? (
<Popup
open ={this.state.open}
closeOnDocumentClick={false}
closeOnEscape={false}
onClose={this.closeModal}className
>
<div className={popstyles.popupBody}>
<div className={popstyles.modalClose}>
<a className="close" onClick={this.closeModal}>
×
</a>
{""}
<div className ={popstyles.unAutherizedUser}>
<label >{homeConstantMessages.accessTokenExpire}</label>
<div className ={popstyles.unAutherizedUserMsg}>
<label>{homeConstantMessages.accessTokenExpireMsg}</label>
<button className ={styles.refreshaccessbtn} onClick = {this.navigateToHomePage.bind(this)} label = {homeConstantMessages.refreshbtn}>
</button>
</div>
</div>
</div>
</div>
</Popup>
) : (
''
)}
}
The problem is when the first time start button is clicked this pop up UI is not getting popped even though the state variable accesstokenexpirydate is set to true. when second time the button is cicked UI is popping up. can anyone please help me out here
1) I think you have to apply arrow function like follows and then you can use this
handlestartbutton=(event)=> {...}
2) I'm quite confused about the name, don't you think it should be render(...) instead of renderer()

Why does my array return no data when creating a customer with the Stripe API in PHP?

I am trying to create both a customer and charge in Stripe.
However, when I try to print_r the array data in my $customer array variable, I get a blank page.
I also tried echoing a string to the charge.php page to make sure the charge page works (echo "page working");, and it does. So I know that's not part of the problem.
The permissions seem to be okay.
These are the permissions for the files in question
-rw-rw-r-- 1 sandbox admin 682 Apr 7 15:55 charge.php
-rw-rw-r-- 1 sandbox admin 1612 Apr 7 17:01 index.php
I have checked my code several times, and no luck.
Can someone help me understand what I might be doing wrong?
Note: The code shown below are all in separate files in the appropriate file types, i.e., all PHP code is in different .php files, and JS in a .js file.
The comment tags are not in the actual code. They are just indicators of where each file starts for the sake of this conversation.
<!-- index.php code below -->
<html>
<body>
<div class="container">
<h2 class="my-4 text-center">Title of Product Page Here</h2>
<form action="./charge.php" method="post" id="payment-form">
<div class="form-row">
<input type="text" class="form-control mb-3 StripeElement StripeElement--empty" name="first_name" placeholder="First Name">
<input type="text" class="form-control mb-3 StripeElement StripeElement--empty" name="last_name" placeholder="Last Name">
<input type="email" class="form-control mb-3 StripeElement StripeElement--empty" name="email" placeholder="Email Address">
<div id="card-element" class="form-control">
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<button>Submit Payment</button>
</form>
</div>
<script src="https://js.stripe.com/v3/"></script>
<script src="js/charge.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
<!-- charge.php code below -->
<!-- Note: Both the Stripe test Key and Stripe PW were masked per Stripe recommendation. Actual test key and password used in real code -->
<?php
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey('sk_test_################');
// Sanitize
$POST = filter_var_array($_POST, FILTER_SANITIZE_STRING);
$first_name = $POST['first_name'];
$last_name = $POST['last_name'];
$email = $POST['email'];
$token = $POST['stripeToken'];
// Create customer
$customer = \Stripe\Customer::create(array(
"email" => $email,
"source" => $token
));
// Charge customer
$charge = \Stripe\Charge::create(array(
"amount" => 5000,
"currency" => "usd",
"description" => "Audio Loops Pack 2019",
"customer" => $customer->id
));
print_r($customer);
<!-- charge.js code below -->
// Create a Stripe client.
var stripe = Stripe('pk_test_################');
// Create an instance of Elements.
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
//Style button
document.querySelector('#payment-form button').classList ='btn btn-primary btn-block mt-4';
// Create an instance of the card Element.
var card = elements.create('card', {style: style});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
// Submit the form with the token ID.
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
I expected the customer and charge arrays to return data, but I get nothing on the screen, not even an empty array.

Search a paragraph

I was assigned homework in which I had to take the given HTML file and create a Javascript file which would search for words within a div class. If the word were to be found, it would highlight it in yellow and return the number of times it was found.
So actually Regex is pretty necessary since it needs to be case insensitive, I would do it like this:
function Search()
{
var elements = document.querySelectorAll(".main");
let search = document.getElementById('searchtext').value;
for (var i = 0; i < elements.length; i++)
{
if(elements[i].innerHTML.toLowerCase().indexOf(search.toLowerCase()) > - 1)
{
alert("found");
}
}
}
document.getElementById('searchbutton').addEventListener('click', Search);
function highlight()
{
var text = document.getElementById('searchtext').value;
if(text)
{
let elements = document.querySelectorAll(".main");
for (var i = 0; i < elements.length; i++)
{
if (elements[i].getAttribute('data-originalText')) {
elements[i].innerHTML = elements[i].getAttribute('data-originalText');
} else {
elements[i].setAttribute('data-originalText', elements[i].innerHTML);
}
var main = elements[i].innerHTML;
var new_text = main.replace(new RegExp('(' + text + ')', 'gi'), '<span class="highlight">$1</span>');
elements[i].innerHTML = new_text;
alert(elements[i].querySelectorAll('.highlight').length + ' occurences found');
}
}
}
document.getElementById('searchbutton').addEventListener('click', highlight);
.highlight {
background-color: yellow;
}
<body>
<div class="main">
<p>The Phoenix Suns are a professional basketball team based in Phoenix, Arizona. They are members of the ...</p>
<p>The Suns have been generally successful since they began play as an expansion team in 1968. In forty years of play they have posted ...</p>
<p>On January 22, 1968, the NBA awarded expansion franchises to an ownership group from Phoenix and one from Milwaukee. ...</p>
<ul>
<li>Richard L. Bloch, investment broker/real estate developer...</li>
<li>Karl Eller, outdoor advertising company owner and former...</li>
<li>Donald Pitt, Tucson-based attorney;</li>
<li>Don Diamond, Tucson-based real estate investor.</li>
</ul>
<p>Page by New Person. <br /> Some (all) information taken from Wikipedia.</p>
</div>
<hr />
<div>
Search for text:
<input id="searchtext" type="text" />
<button id="searchbutton">Search</button>
</div>
</body>
Add a div with a class and some text, a search bar, and a button:
<div class='my_text'>
Homework, or a homework assignment, is a set of tasks assigned to students by their teachers to be completed outside the class. Common homework assignments may include a quantity or period of reading to be performed, writing or typing to be completed, math problems to be solved, material to be reviewed before a test, or other skills to be practiced.
</div>
<br>
Search Word
<input id='search' type='text'>
<br><br>
<button>SEARCH</button>
A highlight function:
function highlight_word(selector, word) {
html = $(selector).html();
replace = word;
re = new RegExp(replace,"gi");
$(selector).html(html.replace(re, "<span class='word'>" + word + "</span>"))
$('.word').css('color', 'blue');
num_highlights = $('.word').css('color', 'blue').length;
return(num_highlights)
}
Reporting function:
function search_and_number() {
$('.show_num').remove();
val = $('#search').val();
num = highlight_word('.my_text', val);
$('body').append("<a class='show_num'>" + num + " highlighted word/s</a>");
}
Handle button click:
$('button').click(function() { search_and_number() })
Result:

Resources