I'm developing a food order system. I want show my order list in a textarea. Right now I can make list in a div's content. I also want my result price to be rounded at two decimal place like if you enter 2, it'll be formatted to 2.00.
My full code is a bit long.
This is a sample of the JavaScript I use :
function addNewItem() {
price = 4.50;
result += price;
appendElement("container", "element" + price, "Cappucino Ice Blended " + price + "[Remove]");
document.getElementById('sumOrder').value = result;
}
The full code in a fiddle
To create new lines in the textarea, so that it looks like a list, you can delimit your orders with "\n".
Example: http://jsfiddle.net/U58gT/
<textarea id="orders" rows="10"></textarea>
<br /><br /><br />
<input id="new-order" type="text"><button>add order</button>
$('button').click(function() {
var new_order = $('#new-order').val();
$('#orders').append(new_order + "\n");
});
Thanks for reply but I using other method. I already can make list in text area. Now i got the problem to remove it when i click remove link. In DIV's i can remove properly but the textarea not remove. i using this code for make list in textarea.
This is a sample of the JavaScript I use :
var result =0.00;
function addtxt(input) {
price = 4.50;
result += price;
var obj=document.getElementById(input)
var txt=document.createTextNode("Cappucino Ice Blended "+ price+"\n")
obj.appendChild(txt)
addNewItem();}
function addNewItem()
{
appendElement("container", "element" + price, "Cappucino Ice Blended " + price + "[Remove]");
document.getElementById('sumOrder').value = result;
}
function removeItem(price)
{
result -= price;
removeElement("container", "element" + price);
document.getElementById('sumOrder').value = result;
}
function removeElement(parentId, elementId)
{
var parentElement = document.getElementById(parentId);
var childElement = document.getElementById(elementId);
parentElement.removeChild(childElement);
}
function appendElement(containerId, newElementId, newElementContent)
{
var newElement=document.createElement("div");
newElement.setAttribute("id", newElementId);
newElement.innerHTML=newElementContent;
var container = document.getElementById(containerId);
container.appendChild(newElement, container);
}
The full code in a fiddle
Related
I'm trying to change the text of a button to that of a value stored in a variable. The button is currently blank and not even using a fixed value like .value = "test"; is working.
HTML:
<div id="addContainer">
<textarea id="listTitleInput" class="textarea" placeholder="Add the title of your list here, then click 'Add List'." rows="10" cols="50"></textarea>
<button id="addListBtn" data-role="button">Add List</button>
</div>
<div id="listDisplayContainer">
</div>
JS:
$(document).ready(function () {
//LISTS
var listTitleInput = document.getElementById("listTitleInput");
var addListBtn = document.getElementById("addListBtn");
var listCount = localStorage.getItem("listCount");
if (listCount === null) {
noteCount = 0;
}
//ADD LISTS
function addList() {
if ($("#listTitleInput").val() == "") {
alert("Please give your list a title, then click 'Add List'.");
} else {
listCount++;
var list = $("#listTitleInput").val();
console.log("List Count: " + listCount);
console.log(list);
var display = document.createElement("button");
document.getElementById("listDisplayContainer").appendChild(display);
display.className = "ui-btn";
display.id = "list" + listCount;
$("#list" + listCount).value = list;
}
}
//Lists
addListBtn.addEventListener("click", addList);
});
Looks like you need to change $("#list" + listCount).value = list; to $("#list" + listCount).text(list);
value is not a property and val() doesn't work for a button.
The problem is that you are confusing native DOM attributes with jQuery ones.
$("#list" + listCount).value = list;
$("#list" + listCount) is a jQuery object so it doesn't use the native javascript properties that you may be used to. (value=)
What you are looking for is:
$("#list" + listCount).html(list);
Or
$("#list" + listCount).text(list);
Since list is a string value, it will be best to use .text
In class, our assignment was to create a grocery list of fruit and their prices by placing objects into an array. Now that I did that part, i'm supposed to Extend the shopping cart program from the last lab. Set up a basic HTML page
Append the items and their prices from the shopping list to the page."
This is where I got lost. We can only use vanilla JavaScript. ** I was able to get the webpage to display the total button, and it works(it calculated the items), but where is my list of groceries and their prices?!
my code:
var fruita = {
name: 'apple',
price: 5
};
var fruitb = {
name: 'pear',
price:3
};
var fruitc = {
name: 'orange',
price: 4
};
var grocery = [];
grocery.push(fruita, fruitb, fruitc);
var total = (fruita.price + fruitb.price +fruitc.price);
for (i=0; i<grocery.length; i++){
console.log(grocery[i].name);
console.log(grocery[i].price);
}
var total = (fruita.price + fruitb.price +fruitc.price);
console.log("total price= " + total);
function calcTotal() {
document.getElementById("total").innerHTML = total;
}
function displayList() {
document.write(grocery).innerHTML = grocery;
In my html:
<head>
<script src="monday2assn2.js"></script>
</head>
<body>
<h1> Shopping List </h1>
<p>Click "Total" to add up your shopping list.</p>
<button onclick="calcTotal()">Total</button>
<p id="total"> </p>
One good way to start is to create a global function that standardizes your method for adding elements to the page. Here are functions that can be used to add an element to a parent element:
function addElement(type,content,parent) {
var newElement = document.createElement(type);
var newContent = document.createTextNode(content);
newElement.appendChild(newContent);
get(parent,'id');
current.insertBefore(newElement,current.childNodes[0]);
}
function get(reference, type) {
switch(type) {
case 'id':
current = document.getElementById(reference);
break;
case 'class':
current = document.getElementsByClassName(reference);
break;
case 'tag':
current = document.getElementsByTagName(reference);
break;
}
}
I copied and pasted this from my own files, as I use these frequently. The get function is used to select elements. The addElement function is used to create a new element. The "type" parameter specifies the tag - so p, div, span, etc. "Content" and "parent" are pretty straightforward. The "parent" parameter is represented by the id of the parent. Once done, you can do something as so:
for(var i=0;i<grocery.length;i++) {
var concat = 'Item: ' + grocery[i].name + ' Price: ' + grocery[i].price;
addElement('p',concat,'body'); //assign the body tag an id of "body"
}
An alternate method is to simply set the innerHTML of the body to add everything to it.
get('body','id');
var joined = current.innerHTML; //all elements in a string
for(var i=0;i<grocery.length;i++) {
var concat = 'Item: ' + grocery[i].name + ' Price: ' + grocery[i].price;
joined += concat;
}
current.innerHTML = joined;
Of course, it would help if you'd specify more specifically how exactly you want your data to be formatted in the HTML. But don't fear Vanilla Javascript - I find it to be much easier than using libraries for things like this, and people often become too reliant on libraries that they forget the roots of JS.
I want to run my function when the page first loads, and again when certain elements are clicked. Each time this function is ran I need it to update the variables, but as it sits right now it is keeping the values that it found the first time the function ran.
I tried searching for this issue and found people saying to just set it to null, or undefined. So I tried doing this by adding var price = null;, var x = null;, etc. at the end of the function. That didn't do anything. So I tried adding an if statement at the top to see if price has a value greater than 0, and then changing every variable to null if it is. This didn't change anything. Now I'm not sure if I need to just re-write the entire thing, or maybe there is some other detail that I am missing?
Thanks in advance for your help.
jQuery(document).ready(function(){
var bessie = function(){
//remove or reset value of variables for next time function runs
if(price > 0){
var qtyCode = null;
var qty = null;
var price = null;
var total = null;
var newContent = null;
};
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html that will be inserted into the page
var newContent = '<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">' + qtyCode + '</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>';
//New html being inserted
jQuery(".qtyswitcher-qty").replaceWith(newContent);
};
bessie();
jQuery('.switcher-label').click(bessie);
jQuery('#qtyswitcher-oneless').click(bessie);
jQuery('#qtyswitcher-onemore').click(bessie);
});
Moved some things around and added some new code based on Data's comments. I'm not sure I did this correctly. I had also tried it with and without the parenthesis as was mentioned below. It's still staying as $9.00 even though you can see that the .price element is changing on the page when the items are clicked.
Link to page with the html I am messing with
<script type="text/javascript">
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html that will be inserted into the page
var newContent = '<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">' + qtyCode + '</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>';
//New html being inserted
jQuery(".qtyswitcher-qty").replaceWith(newContent);
};
bessie();
$('.switcher-label, #qtyswitcher-oneless, #qtyswitcher-onemore' ).on('dblclick click', function(e) {
bessie(e);
e.stopImmediatePropagation();
});
</script>
Found the problem now, but still working on a complete solution. The .replaceWith(); was replacing the html in a way that made it not able to display updated info. The code below is working, but the problem now is that I need to find a way replace the html each time without breaking it. The way it sits now it is adding more html to the page when an element is clicked. My code is still a bit messy.
<script type="text/javascript">
jQuery(document).ready(function() {
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html being inserted
jQuery(".qtyswitcher-add-to-cart-box").append('<p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '<div id="qty">');
jQuery(".qtyswitcher-qty").append('</div>' + '<p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p>');
};
bessie();
jQuery('.switcher-label').click(bessie);
jQuery('.input-box').click(bessie);
jQuery('#qtyswitcher-oneless').click(bessie);
jQuery('#qtyswitcher-onemore').click(bessie);
});
</script>
It's easier to separate html from javascript, so I recommend using handlebars. You pass an object and it returns html you can then use in jQuery. Notice the html string uses back-ticks to concatenate multi-line strings.
<script>
var html = `<p class="multiply">${{price}}/ea</p>
<p class="multiply2">x</p><div id="qty">{{qtyCode}}</div>
<p class="multiply3">=</p><p class="multiply">'$'{{total}}</p>`;
function bessie(){
var obj = { 'qtyCode' : $('.qtyswitcher-qty').html(),
'qty' : $('#qtyswitcher-qty').val(),
'price' : $('.price').first().text().replace(/[^0-9\.]+/g,"") };
obj.total = obj.price * obj.qty;
var template = handlebars.compile(html),
compiled = template(obj);
$(".qtyswitcher-qty").replaceWith(compiled);
};
function addListeners(){
$('.switcher-label').click(bessie());
$('#qtyswitcher-oneless').click(bessie());
$('#qtyswitcher-onemore').click(bessie());
}
$(document).ready( addListeners(); bessie(); );
</script>
Fixed it! Used insertBefore() and insertAfter() to add the html content where I wanted it. Also added a div with the class remove me that will have .remove(); used on it each time an element is clicked.
<script type="text/javascript">
jQuery(document).ready(function() {
var bessie = function(){
//Pull html code for plus/minus qty selector
var qtyCode = jQuery('.qtyswitcher-qty').html();
//Get value of qty that is currently selected
var qty = jQuery('#qtyswitcher-qty').val();
//Pull the current price and change the string to a number
var price = jQuery('.price').first().text().replace(/[^0-9\.]+/g,"");
//multiply price by qty to get the total for the users current selection
var total = price * qty;
//New html being inserted
jQuery( '<div class="removeMe"><p class="multiply">' + '$' + price + '/ea</p>' + '<p class="multiply2">x</p>' + '</div><div id="qty">' ).insertBefore( '.qtyswitcher-qty');
jQuery( '</div>' + '<div class="removeMe"><p class="multiply3">=</p> <p class="multiply">' + '$' + total.toFixed(2) + '</p></div>' ).insertAfter( '.qtyswitcher-qty' );
};
bessie();
jQuery('.switcher-label, .input-box, #qtyswitcher-oneless, #qtyswitcher-onemore' ).click(function() {
jQuery( '.removeMe' ).remove();
bessie();
});
});
</script>
I have a list of divs created server-side, each with a price, quantity (entered by the user) and name. I've managed to use jQuery to calculate the total of each and add those up.
What I'd like to do now is to list the name, quantity and total of each item that has a value in my textarea, on a per-row basis.
So far I've got the following (the append part of which doesn't currently work):
$(document).ready(function () {
$(".product-row input").change(multInputs);
function multInputs() {
var mult = 0;
// for each row:
$("div.product-row").each(function () {
// get the values from this row:
var $price = $('.price', this).html();
var $quantity = $('.quantity', this).val();
var $total = ($price * 1) * ($quantity * 1);
// set total for the row
$('.multTotal',this).text($total);
mult += $total;
$('#textarea',this).append($name).append($total);
});
$("#total").html(mult);
}
});
If I can get this worked out, I'm pretty sure I can work out how to add the grand total and clear the textarea each time something is changed (I'm not looking for someone to do all the work).
Any feedback as to why my textarea isn't populating would be very much appreciated.
Edit: The solution, really well explained below by braks has resulted in the following (working!) code:
$(document).ready(function () {
$(".product-row input").change(multInputs);
function multInputs() {
var mult = 0;
// for each row:
$("div.product-row").each(function () {
// get the values from this row:
var price = $('.price', this).html();
var quantity = $('.quantity', this).val();
var name = $('.name', this).html();
var total = (price * 1) * (quantity * 1);
// set total for the row
$('.multTotal',this).text(total);
mult += total;
$('#textarea').val($('#textarea').val() + ' ' + name + ' ' + total);
});
$("#total").html(mult);
}
});
$(textarea).append(txt) doesn't work like you think. When a page is loaded the text nodes inside the textarea are set the value of that form field. After that, the text nodes and the value can be disconnected. As you type in the field, the value changes, but the text nodes inside it on the DOM do not. Then you change the text nodes with the append() and the browser erases the value because it knows the text nodes inside the tag have changed.
So you want to set the value, you don't want to append. Use jQuery's val() method for this.
You have to use something like $('#textarea').val($('#textarea').val() + ' ' + $name + ' ' + $total);
Except I'm not sure why you put $ in your variables, mix up with PHP ?
I am trying to solve a problem in javascript and I want to do it in javascript not in jQuery.
I create objects in javascript, display them as elements and I bind an eventListener. For simplicity I create objects with a name, description and a price. What I basically want to do is when people click the name the corresponding price is alerted. Is there any way to do this with javascript? In my actual project I want a hover event so that people get a tooltip-like description of the product, but the idea is the same.
Thanks in advance.
Here a fiddle:
fiddle
And some code:
function makeProduct (name, description, price) {
this.name = "<p class='name'>" + name + "</p>";
this.description = "<p class='description'>" + description + "<p>";
this.price = "<p class='price'>" + price + "</p>";
document.getElementById('productlist').innerHTML+=this.name;
document.getElementById('productlist').innerHTML+=this.description;
document.getElementById('productlist').innerHTML+=this.price;
}
var product1=new makeProduct("Pizza", "very Tasty", 5.00);
var product2=new makeProduct("Choclate milk", "warm for the cold winter", 3.00);
var productnames = document.getElementsByClassName('name');
for (i=0; i<productnames.length; i++){
(function(){
productnames[i].addEventListener('click', showPrice, false);
})();
}
function showPrice () {
alert("product price");
}
The quick fix is to write a function that returns the next matching p elem:
function getNextElement(elem, className) {
var next = elem.nextElementSibling; // set next element to "nextElementSibling" relative to passed element.
while (next && !next.classList.contains(className)) { // check for existence and class
next = next.nextElementSibling; // if it exists, but the class does not, move to the next element and repeat.
}
return next; // return whatever was found, or null
}
function showPrice () {
var elem = getNextElement(this, 'price'),
price = elem ? elem.innerHTML : 'Price not found.';
alert(price);
}
See updated fiddle: http://jsfiddle.net/zkbdy0rt/5/
A better way to do this would be to change how you are building your product list. For instance, I would put each product in a containing div (with class="product") for easier styling or finding.
In JavaScript, you can also add arbitrary properties to DOM elements which can be useful. For instance, you could store the price on the DOM element and then retrieve it in your click event handler.
div.price = product.price;
and then later...
showPrice = function (e) {
var price = this.parentElement.price;
alert(price.toFixed(2));
}
See this fiddle for a working example: http://jsfiddle.net/zkbdy0rt/6/
First I fix your current code:
function makeProduct (name, description, price) {
this.name = "<p class='name'>" + name + "</p>";
this.description = "<p class='description'>" + description + "<p>"; //this line
...
}
//this line shoud be:
this.description = "<p class='description'>" + description + "</p>"; //</p> should be closing tag
Secondly:
function makeProduct (name, description, price) {
//...
document.getElementById('productlist').innerHTML+=this.price;
}
as makeProduct(..) returns nothing, there shoulding be assigment to new object to product1
var product1=new makeProduct("Pizza", "very Tasty", 5.00);
Finally your function that returs relevant price should look line:
function showPrice(evt)
{
var p1 = evt.target.nextSibling.nextSibling;
alert(p1.innerHTML);
}
DEMO