I want to be able to update my JavaScript's object's properties(expense and income) so that it reflects on html when I click on the appropriate button.
My JS methods works as follows:
add income - which adds income found in the input (id = amountAdded)
add expense - which adds expense found in the input (id = amountAdded)
return an object that has balance, income and expense
reset values to 0 - this is done by accessing the JS object
However, when I press the appropriate button -- to add income, add expense or reset - nothing occurs. I added the code pen link below.
Account Balance Code Pen
let myAccount = {
name: 'John Doe',
income: 0,
expense: 0
}
let addIncome = function(){
amount = document.getElementById("amountAdded").value
myAccount.income+=amount
}
let addExpense = function(){
amount = document.getElementById("amountAdded").value
myAccount.expense+=amount
}
let resetAccount = function(){
myAccount.income=0
myAccount.expense=0
}
let getAccountSummary = function(){
//for ui logic
return {
balance: myAccount.income-myAccount.expense,
income: myAccount.income,
expense:myAccount.expense
}
}
let printAccountSummary = function(account){
//for developer
let accountSummary = getAccountSummary(account)
console.log(`
Balance: ${accountSummary.balance}
Income: ${accountSummary.income}
Expense: ${accountSummary.expense}
`)
}
// addExpense(account,100)
// addIncome(account,200)
// printAccountSummary(account)
//find app
var app = document.getElementById("root")
//make elements
var h1 = document.createElement("h1")
var text = document.createTextNode(`${myAccount.name}`)
var balance = document.createElement("p")
var balanceText = document.createTextNode(`Balance $${getAccountSummary(myAccount).balance}`)
var expense = document.createElement("p")
var expenseText = document.createTextNode(`Income $${getAccountSummary(myAccount).expense}`)
var income = document.createElement("p")
var incomeText = document.createTextNode(`Expense $${getAccountSummary(myAccount).income}`)
//assign elements
h1.appendChild(text)
balance.appendChild(balanceText)
income.appendChild(incomeText)
expense.appendChild(expenseText)
//append children
app.appendChild(h1)
app.appendChild(balance)
app.appendChild(income)
app.appendChild(expense)
<div class="container">
<!-- Use JavaScript to Populate Card -->
<div id="root" class="card">
</div>
<!-- Set Form Control to Add new Amounts -->
<div class="update">
<form>
<div class="input-group">
<input class="form-control" type="text" name="amountAdded" id="amountAdded" placeholder="Enter Amount"/>
<input type="button" class="btn btn-outline-secondary" value="Add Income" onclick="addIncome()"/>
<input type="button" class="btn btn-outline-secondary" value="Add Expense" onclick="addExpense()"/>
<input type="button" value="Reset" class="btn btn-outline-secondary" onclick="resetAccount()"/>
</div>
</form>
</div>
</div>
Simply you need to update the UI. Try this.
let myAccount = {
name: 'John Doe',
income: 0,
expense: 0
}
let addIncome = function(){
console.log('add income');
amount = document.getElementById("amountAdded").value
myAccount.income+=amount
updateUI()
}
let addExpense = function(){
amount = document.getElementById("amountAdded").value
myAccount.expense+=amount
}
let resetAccount = function(){
myAccount.income=0
myAccount.expense=0
}
let getAccountSummary = function(){
//for ui logic
return {
balance: myAccount.income-myAccount.expense,
income: myAccount.income,
expense:myAccount.expense
}
}
let printAccountSummary = function(account){
//for developer
let accountSummary = getAccountSummary(account)
console.log(`
Balance: ${accountSummary.balance}
Income: ${accountSummary.income}
Expense: ${accountSummary.expense}
`)
}
// addExpense(account,100)
// addIncome(account,200)
// printAccountSummary(account)
let updateUI = function() {
//find app
var app = document.getElementById("root")
app.innerHTML = '';
//make elements
var h1 = document.createElement("h1")
var text = document.createTextNode(`${myAccount.name}`)
var balance = document.createElement("p")
var balanceText = document.createTextNode(`Balance $${getAccountSummary(myAccount).balance}`)
var expense = document.createElement("p")
var expenseText = document.createTextNode(`Income $${getAccountSummary(myAccount).expense}`)
var income = document.createElement("p")
var incomeText = document.createTextNode(`Expense $${getAccountSummary(myAccount).income}`)
//assign elements
h1.appendChild(text)
balance.appendChild(balanceText)
income.appendChild(incomeText)
expense.appendChild(expenseText)
//append children
app.appendChild(h1)
app.appendChild(balance)
app.appendChild(income)
app.appendChild(expense)
}
updateUI()
Also, note that updating UI directly with JavaScript is not nice. If your project is too big, it will be chaos in the future
you need update the values for the p tags u are using to show the income, balance and expense p tags. u can do this by adding a classname to them and when u click add income or add expense, get the elements by their classname and update their values
Related
I have a modal
<div class="modal-body">
<textarea id="data" class="form-control" oninput="this.style.height = ''; this.style.height = this.scrollHeight + 3 +'px'"></textarea>
</div>
and to save the user entered text from the textarea I have a save button and on click I want to save the text
$('#save').click(function () {
var value = $("#data").val();
}
I would like the text to be stored in an array with each line an item in the array. So
text of the below would be an array of 4 items. Some line items will have a space between them but they need to be kept together as a single item in the array.
ABC123
XYZ 444
12323321
OOOO XXXX
Setting var value to be var value = []; reads each letter into an individual array item so not what I need.
Thank you!
try this
$("#save").click(function () {
const value = $("#data").val();
const splitted = value.split("\n");
console.log(splitted);
});
Try this:
HTML:
<div class="modal-body">
<textarea id="data" class="form-control" oninput="this.style.height = ''; this.style.height = this.scrollHeight + 3 +'px'"></textarea>
</div>
<button id="save-btn">save</button>
js:
const textArea = document.querySelector("#data");
const saveBtn = document.querySelector("#save-btn");
arr = [];
const saveData = function(){
arr = textArea.value.split(/\r?\n/);
console.log(arr);
}
saveBtn.addEventListener('click', saveData);
example:
https://codepen.io/huskyslava/pen/PoORBVN?editors=1111
I'm creating a weather dashboard that updates every 5 seconds. I would like the user to be able to change the target city, and have the dashboard update with the new data.
Problem is every time they input a new city, the previous data stays and it seems to be looping through all the inputs the user has made so far.
I would like the data to be updated after the user inputs a new city, rather than added. This is my code:
window.onload = function() {
const api_key = "c7eedc2fa8594d69aa6122025212904";
const inputCity = document.getElementById("inputCity");
const getCity = document.querySelector("form");
getCity.addEventListener("submit", e => {
// Prevent the form from submission
e.preventDefault();
var inputVal = inputCity.value;
var api_url = "http://api.weatherapi.com/v1/forecast.json?key=" + api_key + "&q=" + inputVal + "&days=3&aqi=no&alerts=no";
// Get the dataset
function refreshData() {
fetch(api_url).then(response => {
response.json().then(json => {
var dataset = json;
var output = formatResponse(dataset);
})
// Catch error - for example, the user doesn't input a valid city / postcode / country
.catch(error => console.log("not ok")); // TO BE IMPROVED
})
}
refreshData(); // Display the dashboard immediately
setInterval(refreshData, 5000); // And then refresh the dashboard every X milliseconds
});
function formatResponse(dataset) {
console.log(dataset);
// Current temp
var currentTemp = [dataset.current.temp_c];
console.log(currentTemp);
document.getElementById("currentTempDsp").innerHTML = currentTemp + "°";
// Current state icon
var currentIcon = [dataset.current.condition.icon];
console.log(currentIcon);
document.getElementById("iconDsp").src = "http://" + currentIcon;
// Current state text
var currentText = [dataset.current.condition.text];
console.log(currentText[0]);
document.getElementById("currentStateDsp").innerHTML = currentText;
}
}
<form id="getCity" class="search">
<label id="labelCity">Search for a city...</label></br>
<input type="text" id="inputCity" class="inputCity" placeholder="Type city name here...">
<button id="submitCity" type="submit" class="submitCity"><i class="fas fa-search"></i>Submit</button>
</form>
<div class="state">
<h2 id="currentTempDsp"></h2>
<img id="iconDsp"/>
<span id="currentStateDsp"></span>
</div>
</div>
</div>
When you create an interval using setInterval() it continues to execute until the page is reloaded, navigated away from, or explicitly cleared using clearInterval(). Simply setting more intervals will not stop any previous ones from firing.
Use a globally-scoped variable to store the return value of setInterval() - check if it's set in the beginning of your submit event handler and clear it if it is.
A simplified example of how you could get this done:
const locations = [{
temp: 73,
conditions: 'Sunny'
}, {
temp: 22,
conditions: 'Mostly Cloudy'
}];
var currentInterval = null;
const updateTemp = locationData => {
document.querySelector(".number").innerText = locationData.temp;
document.querySelector(".conditions").innerText = locationData.conditions;
console.log(`updated interface with temperature (${locationData.temp}) and conditions (${locationData.conditions}) data`);
}
[...document.querySelectorAll('.add-location')].forEach(button => {
button.addEventListener('click', (e) => {
// clear the interval
if (currentInterval) {
clearInterval(currentInterval);
currentInterval = null;
console.log('cleared currentInterval');
}
updateTemp(locations[parseInt(e.srcElement.dataset.loc)]);
currentInterval = setInterval(function () {
updateTemp(locations[parseInt(e.srcElement.dataset.loc)]);
}, 2500);
});
});
* {
font-family: sans-serif;
}
.temp {
font-size: 2em;
}
.conditions {
font-style: italic;
}
<div class="temp">
<span class="number">--</span>
<span class="deg">°</span>
</div>
<div class="conditions">--</div>
<div>
<button class="add-location" data-loc="0">Add location 0</button>
<button class="add-location" data-loc="1">Add location 1</button>
</div>
edited with all the code, sorry for my messy coding, I am begginer
hope you can help with this,
I have just created a button in the dom with a function, I gave the button a class to apply an event listener, for some reason i am not able to activate the listener, does anyone have a clue about what I am doing wrong?
//this is th initial array of items, after I am changing it to an arrayof objects
let shoppingList = ['banana','apples','cherries','oranges', 'peaches'];
const list = document.querySelector('.list');
//this is the last thing I need, create new items and allow the del button
const foo=()=>{
console.log('hi');
}
const adder =(item, index, price,name)=>{
list.innerHTML += `<div class='item${[index+1]}'>${name}, price ${price} </div>`;
item[index]= {name,price};
const delElm = document.createElement('button');//the element to remove items
delElm.className = 'remove';
delElm.innerHTML = 'X';
list.appendChild(delElm);
const btndel = document.querySelector('.remove')
console.log(btndel)
btndel.addEventListener('click', foo)
}
//assign a random price to the original array
for (let i = 0; i < shoppingList.length; i++) {
let prices = i+Math.round((((Math.random()*5)+10))*100)/100;
let name = shoppingList[i];
adder(shoppingList,i,prices,name);
}
const btnElm= document.querySelector('.press');
//function to add new elements
const addItm=()=>{
const nameElm = document.querySelector('#text');
const priceElm = document.querySelector('#price');
let name = nameElm.value;
let prices = Number(priceElm.value);
let i = shoppingList.length-1;
adder(shoppingList, i, prices,name)
console.log(shoppingList)
}
console.log(shoppingList)
btnElm.addEventListener('click', addItm)
edit with the HTML, basically, the user can add new items filling the form, each item should be posible to be removed,
<input type="text" id="text" placeholder="name item">
<input type="text" id="price" placeholder="price">
<button class="press">add</button> -->
thanks you in advance
I've made a start to a to do list. I've got it adding an item when you submit an item.
I want to now add local storage when you refresh the page so the items are saved in the browser.
I obviously need to save all the times when the page is refreshed but because my items only update on click I'm not sure how to grab that function data outside the function and save the items.
Any ideas?
Cheers
JS Fiddle:
https://jsfiddle.net/x1bj8mfp/
// When submit item
var submit = document.getElementById('form');
submit.addEventListener('submit', addItem);
var items = [];
var itemValues = document.getElementById('items');
var listContainer = document.createElement('ul');
itemValues.appendChild(listContainer);
// Add item
function addItem(e) {
e.preventDefault();
var item = this.querySelector('[name=item]');
var itemValue = item.value;
items.push(itemValue);
item.value = '';
// Output items
var listItems = document.createElement('li');
listItems.innerHTML = itemValue;
listContainer.appendChild(listItems);
}
You could write the whole array to local storage whenever you add an item:
localStorage.setItem('items', JSON.stringify(items));
Then on page load you would read from local storage the array and assign it back to your variable, or set it to [] (like now), if nothing is in local storage, and then display these items:
var items = JSON.parse(localStorage.getItem('items')) || [];
items.forEach(function (itemValue) {
var listItems = document.createElement('li');
listItems.textContent = itemValue;
listContainer.appendChild(listItems);
});
This updated JSFiddle has that code included.
Of course, you will need some function to delete items as well, otherwise you can only grow your list.
Here's a full solution for you. Note that the code snippet won't work here, due to the cors and sandbox. Just paste it into your code editor.
var submit = document.getElementById('form');
submit.addEventListener('submit', addItem);
var items = [];
var itemValues = document.getElementById('items');
var listContainer = document.createElement('ul');
itemValues.appendChild(listContainer);
//retrieve data after reload
window.onload = function() {
if (localStorage.userData != undefined) {
var userData = JSON.parse(localStorage.getItem('userData'));
for (var i = 0; i < userData.length; i++) {
var listItems = document.createElement('li');
listItems.innerHTML = userData[i];
listContainer.appendChild(listItems);
items = userData;
}
}
}
// Add item
function addItem(e) {
e.preventDefault();
var item = this.querySelector('[name=item]');
var itemValue = item.value;
items.push(itemValue);
item.value = '';
// Output items
var listItems = document.createElement('li');
listItems.innerHTML = itemValue;
listContainer.appendChild(listItems);
localStorage.setItem('userData', JSON.stringify(items));
}
<main>
<form id="form">
<input class="form-input" type="text" name="item" placeholder="Add item">
<input class="btn btn-block" type="submit" value="Submit">
</form>
<div id="items"></div>
<div id="completed"></div>
</main>
Here some helpful small example for local storage
function save() {
var fieldvalue = document.getElementById('save').value;
localStorage.setItem('text', fieldvalue);
}
function load() {
var storedvalue = localStorage.getItem('textfield');
if (storedvalue) {
document.getElementById('textfield').value = storedvalue;
}
}
function remove() {
document.getElementById('textfield').value = '';
localStorage.removeItem('textarea');
}
<body onload="load()">
<input type="textarea" id="textfield">
<input type="button" value="Save" id="save" onclick="save()">
<input type="button" value="remove" id="remove" onclick="clr()">
</body>
<!--save& run this in local to see local storage-->
I want to update my object with values from text fields.
I think the problem is with the click eventhandler on the button but not sure. I've tried a few things, Your help would be amazing.
HTML
<form>
<label><p>Book Name: </p></label>
<input name="booktitle" id="booktitle" type="text" value="I'm a value">
<label><p>Total Pages: </p></label>
<input type="text">
<label><p>Current Page: </p></label>
<input type="text">
<button id="my-Btn" type="button">Add to List</button>
</form>
JS
(function() {
// Create book object
var book = {
name: 'JavaScript & jQuery',
totalPages: 622,
pages: 162,
pagesLeft: function() {
var total = this.totalPages - this.pages;
return total;
},
percentageLeft: function() {
var totalPercentage = this.pagesLeft() / this.totalPages * 100
return Math.round(totalPercentage);
}
};
// write out book name and pages info
var bookName, totalPages, pagesLeft, percentageLeft; //declares variables
bookName = document.getElementById('bookName'); // gets elements from document
totalPages = document.getElementById('totalPages');
pagesLeft = document.getElementById('pagesLeft');
percentageLeft = document.getElementById('percentageLeft');
bookName.textContent = book.name; // write to document
totalPages.textContent = 'Total Pages: ' + book.totalPages;
pagesLeft.textContent = book.pagesLeft();
percentageLeft.textContent = book.percentageLeft() + '%';
// pull value from text field and set to object
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
});
}());
Code Pen of what I have so far.
http://codepen.io/Middi/pen/pRGOVW
Thanks in advance.
Your code already updates an object's property (book.name) with a value from a text field (#booktitle). You can see this by adding alert(book.name); after the line
book.name = document.getElementById('booktitle').value;
As Jazcash noted, if you wanted to display the updated book name everytime it was changed, you'd need to add
bookName.textContent = book.name;
In your eventlistener, so it'd look something like this:
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
bookName.textContent = book.name;
});
The problem is you're setting your divs textContent based on book here: bookName.textContent = book.name;. But then you need to do it again in your event like so:
book.name = bookName.value;
bookName.textContent = book.name;
You'll need to do this for all your fields