so i was creating a shop/store in my index html file. but i want to make that if i dont have enough gems, it wont let me buy the item
for example:
you can buy 1 coins from 20 gems
[Buy]
Gems: 19
Coins: 0
Error: you do not have enough gems to buy a coin.
html:
<div id="gemplace">
<div id="gems">
Balance: <span id="balance">0</span>
</div>
<div id="coins">
Coins: <span id="coins">0</span>
</div>
<div id="shop" style="background-color: black">
<div id="additem" style="display: inline-block;">
<button height="100" width="100" style="padding: 10px 14px" onclick="jsfAI()">+</button>
</div>
<hr>
<h2 style="color: white">Recommended items</h2>
<div id="items">
<div class="class_built-in-item" name="coinsitem">
<img id="built-in-item-coins" src="icons&images/coins.png" height="90" width='100'>
<div class="cost">
<span class="cost_int">5</span>
<span id="currency"> gems </span>
<button onclick='buycoin()'>Buy</button>
</div>
</div>
</div>
in javascript :
< script >
// Get references to the gems balance and coins
const gems = document.querySelector('#balance');
const coins = document.querySelector('#coins');
// Get reference to the buy button
const buyButton = document.querySelector('button[onclick="buycoin()"]');
// Listen for a click on the buy button
buyButton.addEventListener('click', function() {
// Get the cost of the item
const cost = parseInt(document.querySelector('.cost_int').textContent);
// Check if the user has enough gems to buy the item
if (parseInt(gems.textContent) >= cost) {
// If the user has enough gems, subtract the cost of the item from the gems balance
gems.textContent = parseInt(gems.textContent) - cost;
// Increase the number of coins
coins.textContent = parseInt(coins.textContent) + 1;
} else {
// If the user doesn't have enough gems, show an error message
alert("Error: you do not have enough gems to buy a coin.");
}
}); <
/script>
Related
I have tried using basic JavaScript when data-reviews="2" and it worked, but what I need is when data-reviews is less than 5 or any specific number, the whole <span> section should be hidden. I need assistance on this. I am trying to achieve the same outcome but I want to hide this, when data reviews has < 5.
<div class="collection-list-badge">
<span class="stamped-product-reviews-badge" data-id="5649263493270" style="display:block;">
<span class="stamped-badge" data-rating="5.0" data-lang="en" aria-label="Rated 5.0 out 42reviews"></span>
</span>
<span class="stamped-badge-caption" data-reviews="42" data-rating="5.0" data-label="reviews" aria-label="42 reviews" data-version="2">42</span>
</div>
Loop over the badge elements. For each collection badge select the review element. Parse the data-reviews attribute with parseInt. Check if the review is less than 5. If so, remove the collection badge element.
const collectionListBadges = document.querySelectorAll('.collection-list-badge');
for (const collectionListBadge of collectionListBadges) {
const reviewsElement = collectionListBadge.querySelector('[data-reviews]');
const amountOfReviews = parseInt(reviewsElement.getAttribute('data-reviews'));
if (amountOfReviews < 5) {
collectionListBadge.remove();
}
}
<div class="collection-list-badge">
<span class="stamped-product-reviews-badge" data-id="5649263493270" style="display:block;">
<span class="stamped-badge" data-rating="5.0" data-lang="en" aria-label="Rated 5.0 out 42reviews"></span>
</span>
<span class="stamped-badge-caption" data-reviews="42" data-rating="5.0" data-label="reviews" aria-label="42 reviews" data-version="2">42</span>
</div>
<div class="collection-list-badge">
<span class="stamped-product-reviews-badge" data-id="5649263493270" style="display:block;">
<span class="stamped-badge" data-rating="4.0" data-lang="en" aria-label="Rated 4.0 out 38reviews"></span>
</span>
<span class="stamped-badge-caption" data-reviews="4" data-rating="4.0" data-label="reviews" aria-label="38 reviews" data-version="2">4</span>
</div>
I'm currently developing a project that will be Client on Java and Admin on PHP. For this purpose, I would like to store the API's data in a SQL database, so then I can show it in Java for the user to consume. The problem is, no matter how much I search, I can't find an answer that helps my specific issue. The solution that tends to be the best is to implement AJAX from a PHP form, the problem is I'm not trying to use POST for this.
Example of a function where I want information stored in database
function getMovie() {
let movieId = sessionStorage.getItem('id');
//test id -> 299536
axios.get(`https://api.themoviedb.org/3/movie/${movieId}?api_key=5ec279387e9aa9488ef4d00b22acc451`)
.then((response) => {
// https://api.themoviedb.org/3/movie/299536/reviews?api_key=5ec279387e9aa9488ef4d00b22acc451&language=en-US&page=1
console.log(response);
let movie = response.data;
if (movie.poster_path === null) {
poster = "../image/default-movie.png";
} else {
poster = "https://image.tmdb.org/t/p/w185_and_h278_bestv2" + movie.poster_path;
}
let date = movie.release_date;
let year = date.slice(0, 4);
let Rated;
let revenue = movie.revenue / 1000000;
let budget = movie.budget / 1000000;
revenue = Math.round(revenue);
budget = Math.round(budget);
if (revenue === 0) {
revenue = "Revenue is less than million dollers"
}
if (budget === 0) {
budget = "Budget is less than million dollers"
}
let genre = [];
movie.genres.forEach(element => {
genre.push(element.name);
});
genres = genre.join(' / ');
let output1 = `
<div class="row">
<div class="col-md-4 box1">
<img src="${poster}" class="poster-image">
</div>
<div class="col-md-4 box2">
<h1 class="movie-title">${movie.title}</h1>
<h5 style="color: white; font-weight:bold">${year}</h5>
<h5 style="color: white; font-weight:bold; margin-top: -10px;">${genres}</h5>
<ul class="list-group">
<li class="list-group-item active">
<strong>Rating: </strong> ${movie.vote_average} / 10</li>
<li class="list-group-item active">
<strong>Status: </strong> ${movie.status}</li>
<li class="list-group-item active">
<strong>Duration: </strong> ${movie.runtime} min</li>
<li class="list-group-item active">
<strong>Budget: </strong> $ ${budget} million</li>
<li class="list-group-item active">
<strong>Revenue: </strong> $ ${revenue} million</li>
</ul>
</div>
<div class="col-md-4 box3">
<h1 class="title-second">Synopsis</h1>
<p>${movie.overview}</p>
<hr style="width: 80%;color: #222;">
<div>
View IMDB
<!-- View IMDB -->
Go Back To Search
</div>
</div>
</div>
`
$('#movie').html(output1);
})
.catch((error) => {
console.log(error);
});
}
Thanks in advance!
I have a simple Invoicing & Inventory management application where we display the list of invoices under a particular customer which you can see in the img below. Also, when we click on View/Edit button the bootstrap modal pop-up is displayed with the selected invoice details. The problem I notice here is, the result of Grand Total function is wrong which I being a novice in angular unable to figure out.
I also read about the impact of function calls in angular template here https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496 because I'm calling the functions in my template code below. I tired the pipe soultion shown in the article but that didn't help me.
Looking for someone who can help me figure out the Grand Total issue. Any help is really appreciated. Kindly look at the images & code below for the reference.
1. Invoice lists under customer(Raj Kapoor)
2. Invoice Bootstrap Modal Pop-up (On click of View/Edit Button)
Note: Here, assume that we've edited invoice no 4
3. Template code(admin-invoices.component.html)
Note: I'm providing only the absolute essentials part of code to keep it simple to understand. Focus only on 2 things: 1. View/Edit button function call 2. Invoice amount calculations section
<div class="container">
<div class="row g-0 mb-4">
<!-- Customer Name & Total Balance code goes here -->
</div>
<table class="table table-hover border" datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger">
<thead class="thead-dark">
<tr>
<!-- Table heading goes here like Date, Invoice No.,
Amount, Balance Due, Operation, Action etc.
-->
</tr>
</thead>
<tbody>
<tr *ngFor="let invoice of customerInvoices">
<td class="text-center">{{invoice.invoiceDate | date:'dd/MM/yyyy'}}</td>
<td class="text-center">{{invoice.invoiceNumber}} </td>
<td class="text-center">{{invoice.invoiceTotal | currency:'INR':true}}</td>
<td class="text-center">{{invoice.invoiceTotal - invoice.paymentTotal | currency:'INR':true}}</td>
<td class="text-center">
<button type="button" class="btn btn-success" (click)="setInvoice(invoice)" data-bs-toggle="modal" data-bs-target="#invoiceDetailsModal">
View/Edit Details
</button>
</td>
</tr>
</tbody>
</table>
<!-- View/Edit Details: Bootstrap Modal Starts -->
<div class="modal fade" id="invoiceDetailsModal" tabindex="-1" aria-labelledby="invoiceDetailsLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<!-- Shop Details header goes here. -->
</div>
<div class="modal-body pt-0">
<div class="row">
<!-- To Customer, Date and Invoice No goes here-->
</div>
<!-- Items List Section -->
<div class="row">
<div class="items-table">
<div class="row header">
<!-- Table Heading: Sr. No, Item Details,
Qty, Rate, Amt goes here.. -->
</div>
<ng-container *ngFor="let invItem of invoice.invoiceItem; let i=index;">
<!-- Table data(list of all items) goes here-->
</ng-container>
<!-- Invoice amount calculations section -->
<div class="row">
<div class="col-4">
<!-- sub total row -->
<div class="row" style="border: 1px solid green;">
<div class="col-6 text-end">Sub Total:</div>
<div class="col text-center">{{invoiceSubTotal() | currency:'INR':true}}</div>
</div>
<!-- discount row -->
<div class="row">
<div class="col-6 ps-0 pe-0 text-end">
Discount:
<select class="form-select p-0" style="display: inline; width:60px;" [(ngModel)]="invoice.discountLabel" name="discountLabel" id="discountLabel" aria-label="Select discount option">
<option value="%">%</option>
<option value="Rs">Rs</option>
</select>
</div>
<div class="col text-center">
<input [(ngModel)]="invoice.discountTotal" name="discountTotal" type="number" style="border: 1px solid #ddd; width:100px">
</div>
</div>
<!-- freight row -->
<div class="row">
<div class="col-6 text-end">Freight(Rs.):</div>
<div class="col text-center"><input [(ngModel)]="invoice.freight" name="freight" type="number" style="border: 1px solid #ddd; width:100px"></div>
</div>
<!-- grand total row -->
<div class="row">
<div class="col-6 text-end">Grand Total:</div>
<div class="col text-center">{{calculateGrandTotal() | currency: 'INR':true}}</div>
</div>
<!-- Received row -->
<div class="row">
<div class="col-6 text-end">Received:</div>
<div class="col text-center">
<input [(ngModel)]="invoice.paymentTotal" name="paymentTotal" type="number" style="border: 1px solid #ddd; width:100px">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal" (click)="clearData()">Close</button>
<button type="button" class="btn btn-outline-secondary" (click)="updateInvoice()">
Update & Print
</button>
</div>
</div>
</div>
</div>
<!-- View/Edit Details: Bootstrap Modal Ends -->
4. Component Class(admin-invoices.component.ts)
#Component({
selector: 'app-admin-invoices',
templateUrl: './admin-invoices.component.html',
styleUrls: ['./admin-invoices.component.css']
})
export class AdminInvoicesComponent {
customerInvoices: Invoice[] = []; // to get list of all invoices under this customer
invoice: Invoice = new Invoice();
customerId: number;
customer: Customer = new Customer(); // To avoid initial undefined value of customer field
totalBalance: number = 0.0; // total balace of all invoices under this customer
itemsList: Item[] = [];
constructor(private route: ActivatedRoute,
private customerService: CustomerService,
private invoiceService: InvoiceService,
private itemService: ItemService) {
this.customerId = +(this.route.snapshot.paramMap.get('customerId')); // converting string to number using '+'
this.setCustomer();
this.setItems();
this.invoiceService.getCustomerInvoices(this.customerId)
.subscribe((invoices: Invoice[]) => {
this.customerInvoices = invoices.map(invoice => new Invoice(invoice));
this.calculateTotalBalance(); // get the total balace of all invoices under this customer
});
}
setCustomer() {
this.customerService.get(this.customerId)
.subscribe((customer: Customer) => this.customer = customer);
}
setItems() {
this.itemService.getAll()
.subscribe((items: Item[]) => this.itemsList = items);
}
calculateTotalBalance() {
this.customerInvoices.forEach(invoice => {
this.totalBalance = this.totalBalance + (invoice.invoiceTotal - invoice.paymentTotal);
});
}
setInvoice(invoice: Invoice) {
this.invoice = invoice;
}
addItem() {
this.invoice.addItem();
}
removeItem(item) {
this.invoice.removeItem(item);
}
invoiceSubTotal() {
return this.invoice.invoiceSubTotal();
}
calculateGrandTotal() {
return this.invoice._invoiceTotal;
}
updateInvoice() {
// update code goes here
}
}
5. Invoice Model class(invoice.ts)
export class Invoice {
invoiceId?: number;
invoiceNumber: number;
discountLabel: string = '';
discountTotal: number = 0.0;
freight: number = 0.0;
invoiceTotal: number = 0.0;
paymentTotal: number = 0.0;
invoiceDate: string;
narration: string = '';
customer: Customer;
invoiceItem: InvoiceItem[] = [];
description: string;
constructor(customer?: Customer, invoiceNumber?: number);
constructor(invoice: Invoice);
constructor(customerOrInvoice?: Customer | Invoice, invoiceNumber?: number){
if(!invoiceNumber) {
// Existing invoices
Object.assign(this, customerOrInvoice); // copy everything in current invoice object
} else {
// New invoice creation
this.invoiceDate = new Date().toISOString().substring(0,10);
this.customer = customerOrInvoice as Customer;
this.invoiceNumber = invoiceNumber;
this.invoiceItem.push({itemId: 0, quantity: 0, rate: 0}); // default invoice_item
}
}
addItem() {
this.invoiceItem.push({itemId: 0, quantity: 0, rate: 0}); // default invoice_item
}
invoiceSubTotal(): number {
let subTotal = 0.00;
this.invoiceItem.forEach(item => {
subTotal += (item.quantity * item.rate);
});
return subTotal;
}
get totalDiscount(): number {
if(this.discountLabel === '%') return ((this.discountTotal * this.invoiceSubTotal())/100);
return this.discountTotal; // Considering discountLable to either 'Rs' or not selected
}
get _invoiceTotal(): number {
this.invoiceTotal = (this.invoiceSubTotal() - this.totalDiscount) + this.freight;
return this.invoiceTotal;
}
}
First of all, I would like to thank #GRD or grdtechlab#gmail.com for collaborating with me over an email to help me with this problem. This was basically two way efforts to find out the root cause. But again credit goes to GRD.
Root Cause: So, the backend response object was the main issue and not the UI code. Because, when we query sequelize database to get the Decimal type data, then it converts the decimal values to string values. And, in the resultant object, we end up with the string type values instead of 'number' type(in javascript). This leads to abnormal results in our computation functions like _invoiceTotal( ) getter function above.
Read more here https://github.com/sequelize/sequelize/issues/8019
Solution: As mentioned in the above github issue, I changed the sequelize configuration to dialectOptions : {decimalNumbers: true} and this converted all the decimal values to number in the response object.
See the response object images below to understand this better.
1. Incorrect Response object (string values instead of number type)
2. Correct Response object (after changing sequelize configuration)
I'm trying to develop a Load-More button using Javascript calling an API done with PHP.
So far, so good. I can load the new objects in a range i += i + 4 (I load three new comments everytime I press the button).
This is my load-more button:
$(document).ready(function () {
$(".load-more").on('click', function () {
var tab = $(this).data('tab');
var next_page = $(this).data('next-page');
console.log(next_page);
console.log(tab);
$.get($(this).data('url') + '?tab=' + tab + '&page=' + next_page, function (data) {
addNewQuestions($.parseJSON(data));
});
});
});
And for every object loaded I want to print each of these html blocks.
<div class="question-summary narrow">
<div class="col-md-12">
<div class="votes">
<div class="mini-counts"><span title="7 votes">
{if $question['votes_count']}
{$question['votes_count']}
{else}
0
{/if}
</span></div>
<div>votes</div>
</div>
<div {if $question['solved_date']}
class="status answered-accepted"
{else}
class="status answer-selected"
{/if}
title="one of the answers was accepted as the correct answer">
<div class="mini-counts"><span title="1 answer">{$question['answers_count']}</span></div>
<div>answer</div>
</div>
<div class="views">
<div class="mini-counts"><span title="140 views">{$question['views_counter']}</span></div>
<div>views</div>
</div>
<div class="summary">
<h3>
<a href="{questionUrl($question['publicationid'])}" class="question-title" style="font-size: 15px; line-height: 1.4; margin-bottom: .5em;">
{$question['title']}
</a>
</h3>
</div>
<div class = "statistics col-sm-12 text-right" style="padding-top: 8px">
<span>
<i class = "glyphicon glyphicon-time"></i>
<span class="question-updated-at">{$question['creation_date']}</span>
</span>
<span>
<i class = "glyphicon glyphicon-comment"></i>
<span class="question-answers">{$question['answers_count']}</span>
</span>
</div>
</div>
</div>
The problem is that I have several conditions, as {if$question['votes_count']} and I'm struggling because I don't know how get those variables when rendering the html.
Then I found something but I can't figure out how to adapt to my case
On that addNewQuestions I think that a good approach would be:
function addNewQuestions(objects) {
$.each(objects, function (i, object) {
console.log(object);
var lastItem = $('div.active[role="tabpanel"] .question-line:last');
var newLine = lastItem.clone(true);
var newObject = newLine.find('.question-col:eq(' + i + ')');
newObject.find('.question-info-container').attr('data-id', object.publicationid);
newObject.find('.vote-count').html(object.votes);
updateTitleAndLink(newObject.find('.question-title'), object);
lastItem.after(newLine);
});
}
function updateTitleAndLink(questionTitle, object) {
questionTitle.attr('href', questionTitle.data('base-question-url') + object.publicationid);
questionTitle.html(object.title);
}
But nothing happens and I can't figure out why.
Any idea or suggestion?
Kind regards
(1) I am trying to add a new user to a list of items (userList). The functionality works, but there is an issue. I made the list 'selectable' aka.. when a user clicks on an item on the list the textboxes in my html5 code gets populated w/ values from the selected item in the list. This allows the user to edit the individual properties from the item. Right underneath the group of textboxes is my 'add new user' button..... When the app first runs, the textboxes are empty and I fill them w/ appropriate text and click the add button and the new user is appended to the list. However the issues is, when I have already selected an item, edited it... then the textboxes are still populated w/ the item values... now if I click add new user... a new user is added... but now I have duplicate users in my list.. which is fine because I can always edit one of them... However.... it looks like both the new and the old user are now somehow linked... if I edit one of them, the values in the other also change... (I hope this makes sense). I feel that because the new user was created via the selected record of the old user, somehow their indexes are related....can't seem to figure out how to create a new user without having the old user connected to it.
(2) Deleting a user works fine, but except, the user deleted is always from the bottom of the list. I want to be able to select any item in the list and delete that specific item. I tried using something like:-
$scope.userList.splice($scope.userList.indexOf(currentUser), 1);
but to no avail.
My Javascript:-
<script type="text/javascript">
function UserController($scope) {
$scope.userList = [
{ Name: "John Doe1", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
{ Name: "John Doe2", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
{ Name: "John Doe3", Title: "xxxx", Company: "yyyy", Place: "zzzz" },
{ Name: "John Doe4", Title: "xxxx", Company: "yyyy", Place: "zzzz" }
];
$scope.selectUser = function (user) {
$scope.currentUser = user;
}
$scope.addNew = function (currentUser) {
$scope.userList.push(currentUser);
$scope.currentUser = {}; //clear out Employee object
}
$scope.removeItem = function (currentUser) {
// $scope.userList.pop(currentUser);
$scope.userList.splice($scope.userList.indexOf(currentUser), 1);
$scope.currentUser = {}; //clear out Employee object
}
}
</script>
My HTML:-
<div class="row">
<div style="margin-top: 40px"></div>
<div data-ng-app="" data-ng-controller="UserController">
<b>Employee List</b><br />
<br />
<ul>
<li data-ng-repeat="user in userList">
<a data-ng-click="selectUser(user)">{{user.Name}} | {{user.Title}} | {{user.Company}} | {{user.Place}}. </a>
</li>
</ul>
<hr>
<div style="margin-top: 40px"></div>
<b>Selected Employee</b><br />
<br />
<div style="border:dotted 1px grey; padding:20px 0 20px 0; width:40%;">
<div class="row" style="margin-left: 30px">
<div style="display: inline-block;">
Name:
</div>
<div style="display: inline-block; margin-left: 35px;">
<input type="text" data-ng-model="currentUser.Name">
</div>
</div>
<div style="margin-top: 20px"></div>
<div class="row" style="margin-left: 30px">
<div style="display: inline-block;">
Title:
</div>
<div style="display: inline-block; margin-left: 45px;">
<input type="text" data-ng-model="currentUser.Title">
</div>
</div>
<div style="margin-top: 20px"></div>
<div class="row" style="margin-left: 30px">
<div style="display: inline-block;">
Company:
</div>
<div style="display: inline-block; margin-left: 10px;">
<input type="text" data-ng-model="currentUser.Company">
</div>
</div>
<div style="margin-top: 20px"></div>
<div class="row" style="margin-left: 30px">
<div style="display: inline-block;">
Place:
</div>
<div style="display: inline-block; margin-left: 35px;">
<input type="text" data-ng-model="currentUser.Place">
</div>
</div>
</div>
<div>
<div style="margin: 2% 0 0 8%; display:inline-block">
<button data-ng-click="addNew(currentUser)" class="btn btn-primary" type="button">Add New Employee</button>
</div>
<div style="margin: 2% 0 0 1%; display:inline-block">
<button data-ng-click="removeItem(currentUser)" class="btn btn-primary" type="button">Delete Employee</button>
</div>
</div>
<hr>
<div style="margin-top: 40px"></div>
<b>Employee Details:</b><br />
<br />
{{currentUser.Name}} is a {{currentUser.Title}} at {{currentUser.Company}}. He currently lives in {{currentUser.Place}}.
</div>
</div>
* EDIT * I solved the delete user issue as:-
$scope.removeItem = function (currentUser) {
if ($scope.userList.indexOf(currentUser) >= 0) {
$scope.userList.splice($scope.userList.indexOf(currentUser), 1);
$scope.currentUser = {}; //clear out Employee object
}
}
and thanks to the suggestion, the add new user issue has also been resolved.
You have two issues. In $scope.addNew():
$scope.userList.push(currentUser);
This line pushes a reference to the same object you are currently editing. This is why the users appear linked, because you have the same object in the list twice. You instead need to copy the properties of the object onto a new object, which you can do in this case with angular.extend():
$scope.userList.push(angular.extend({}, currentUser));
You might instead consider having the "add new" button just add a blank user to the list and select it for editing:
$scope.addNew = function () {
$scope.userList.push($scope.currentUser = {});
};
In $scope.removeItem(), you use the pop() method of the array to try to remove a specific item, but pop() removes the last item and doesn't actually accept any arguments:
$scope.userList.pop(currentUser);
You could iterate the list to remove a specific object:
var i;
for (i = 0; i < $scope.userList.length; ++i) {
if ($scope.userList[i] === currentUser) {
$scope.userList.splice(i, 1);
break;
}
}
Or you could use indexOf() but test that the return value is not equal to -1, or the splice() call will remove the last element from the list.