I'm simply trying to take inputs from html input fields.
The problem is, my function always evaluate the inputs to 0.
What should I do my code to work as I expected (to take inputs from fields and pass them to my javascript functions). If there is alike answered questions asked before, please refer.
Please do not propose jQuery solutions - I can't follow its full of parantheses syntax.
P.S. Zeros on ternary, are just for avoiding NaNs. Nothing else.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<strong>Data</strong>
<hr>Price:
<input type="text" id="price" value="0">
<br>Prepay:
<input type="text" id="prepay" value="0">
<br>Percent:
<input type="text" id="percent" value="0">
<br>Month:
<input type="text" id="month" value="0" onchange="refactorTable('payment-plan')">
<br>
<hr>
<strong>Table</strong>
<table id="payment-plan" border="1">
<thead>
<tr>
<td>Month</td>
<td>Amount</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
var Sum = parseInt(document.getElementById('price').value);
var PrePayment = parseInt(document.getElementById('prepay').value);
var Percent = parseInt(document.getElementById('percent').value);
var Month = parseInt(document.getElementById('month').value);
//console.log(Sum +" -- "+ PrePayment +" -- "+ Percent +" -- "+ Month);
function monthlyPaymentPlan(Sum, PrePayment, Percent, Month) {
var BigJohn = Sum - PrePayment;
//console.log(BigJohn);
var monthly = Math.ceil((BigJohn + BigJohn * Percent) / Month);
return Month > 0 ? monthly : 0;
}
function lastMonth(Sum, PrePayment, Percent, Month) {
return Month > 0 ? Sum - monthlyPaymentPlan(Sum, PrePayment, Percent, Month) * (Month - 1) : 0;
}
function refactorTable(tbl_id) {
var table = document.getElementById(tbl_id).getElementsByTagName('tbody')[0];
table.innerHTML = "";
var i = 0;
var rows = document.getElementById('month').value;
rows = parseInt(rows);
for (i = 0; i < rows - 1; i++) {
table.insertRow(-1).innerHTML = "<td>" + (i + 1) + "</td><td>" + monthlyPaymentPlan(Sum, PrePayment, Percent, Month) + "</td>";
}
table.insertRow(-1).innerHTML = "<td>" + rows + "</td><td>" + lastMonth(Sum, PrePayment, Percent, Month) + "</td>";
}
</script>
</body>
</html>
You are getting the values when the page renders, instead of when the function is supposed to run. Place your assignments inside a function and call the function.
// Define the variables globally so they can be used in any function
var Sum;
var PrePayment;
var Percent;
var Month;
// Call this function to set the values of the global variables.
function getValues() {
Sum = parseInt(document.getElementById('price').value);
PrePayment = parseInt(document.getElementById('prepay').value);
Percent = parseInt(document.getElementById('percent').value);
Month = parseInt(document.getElementById('month').value);
}
// Call the getValues function first to set the values and then continue on
// with your function calculations.
function refactorTable(tbl_id) {
getValues();
// Do the rest...
}
You need to get the values at the time the function is called. Right now you're getting the values on page load (which is 0).
function refactorTable(tbl_id) {
var Sum = parseInt(document.getElementById('price').value);
var PrePayment = parseInt(document.getElementById('prepay').value);
var Percent = parseInt(document.getElementById('percent').value);
var Month = parseInt(document.getElementById('month').value);
var table = document.getElementById(tbl_id).getElementsByTagName('tbody')[0];
table.innerHTML = "";
var i=0;
var rows = document.getElementById('month').value;
rows = parseInt(rows);
for(i=0; i<rows-1; i++) {
table.insertRow(-1).innerHTML = "<td>" + (i+1) + "</td><td>" + monthlyPaymentPlan(Sum, PrePayment, Percent, Month) + "</td>";
}
table.insertRow(-1).innerHTML = "<td>" + rows + "</td><td>" + lastMonth(Sum, PrePayment, Percent, Month) + "</td>";
}
You have need to update input variable value on change of id="month" so you can get updated value.
var Sum = '';
var PrePayment = '';
var Percent = '';
var Month = '';
function inputsval() {
Sum = parseInt(document.getElementById('price').value);
PrePayment = parseInt(document.getElementById('prepay').value);
Percent = parseInt(document.getElementById('percent').value);
Month = parseInt(document.getElementById('month').value);
}
function refactorTable(tbl_id) {
inputsval();
//Your other code.....
}
var Sum = parseInt(document.getElementById('price').value);
This is not defining a function, or a macro. This is a one-time calculation of a number, and it seems this is going to happen when the page starts up. So, it won't ever change from its first value (0).
You should probably move these declarations inside of refactorTable. Thankfully, you already have them set up to be passed as arguments.
Related
I understand there are questions similar to this issue. And I have taken the time to look through them. But the implementation here is a little different than in some of the cases I looked at. The good news here is my fourth column, the running totals column, is correctly displaying the data I want. Everything is working (correctly calculated and displaying) so why is my app held up on this? I'd appreciate it. Thanks.
calculateRunningTotals(){
var attendantTotalCell = 0;
var total = 0;
var totalCell="";
var totalsCells = document.querySelectorAll("td:nth-child(3)");
totalsCells.forEach(function(cell, index){
console.log("The contents of the totals cell " + cell.innerText);
totalCell = cell.innerText;
attendantTotalCell = totalCell.replace(/[^0-9-.]/g, '');
total = parseInt(attendantTotalCell) + parseInt(total);
console.log("Attendant Total Cell is: " + attendantTotalCell);
console.log("Attendant Total is " + total);
cell.nextElementSibling.innerHTML = total;
})
}
If you add the following check to ensure that cell.nextElementSibling is defined, then this should resolve your problem:
calculateRunningTotals(){
var attendantTotalCell = 0;
var total = 0;
var totalCell="";
var totalsCells = document.querySelectorAll("td:nth-child(3)");
totalsCells.forEach(function(cell, index){
console.log("The contents of the totals cell " + cell.innerText);
totalCell = cell.innerText;
attendantTotalCell = totalCell.replace(/[^0-9-.]/g, '');
total = parseInt(attendantTotalCell) + parseInt(total);
console.log("Attendant Total Cell is: " + attendantTotalCell);
console.log("Attendant Total is " + total);
/* Add the following check to ensure nextElementSibling is defined
before attempting to access it */
if(cell.nextElementSibling) {
cell.nextElementSibling.innerHTML = total;
}
})
}
I'm trying to add all the values from the class "q-total" But I can't get it to work. Here's the code:
$(document).on("change", ".row-inputs", function(){
var total = 0;
var price = 0;
var multi = 0;
$('.q-quantity', this).each(function(){
multi = $(this).val();
})
$(".q-price", this).each(function(){
price += +$(this).val() * multi;
})
$(".q-total", this).val(price);
for (var i = 0; i < $(".q-total").length; i++) {
// total = 0;
// console.log($(".q-total", this).val() )
total += parseInt($(".q-total", this).val());
}
console.log("Total " + total)
})
Below is the class code I use to add new rows to the html. In case this might help to figure out why the above code is not working.
var counter = 1;
var limit = 10;
function addInput(divName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + "
inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.className = "row-inputs";
newdiv.innerHTML = "<input type='text' name=''
placeholder='product name' class='q-product-name'> " +
"<input type='number' name='' placeholder='0' class='q-quantity'
value=1> " +
"<input type='text' name='' placeholder='price' class='q-price'> "
+
"<input type='text' name='' placeholder='price' class='q-total'>";
document.getElementById(divName).appendChild(newdiv);
counter++;
}
}
Thank you
Your loop is incorrect:
Change
for (var i = 0; i < $(".q-total").length; i++) {
// total = 0;
// console.log($(".q-total", this).val() )
total += parseInt($(".q-total", this).val());
}
To
$(".q-total").each(function(){
total += +$(this).val();
})
In the original for loop you never iterate over the values, you always take $(this).val(). Not sure why you varied from your .each() approach you've used everywhere else, but that is your fix.
To explain further, using your example of add rows with prices of 3,4,5. The first time through (1st row), you have one element in the jQuery collection, so total=0 becomes total += 3; Second row added and you have two elements, but only look at the value of the current row, so total=0 becomes total += 4 && total += 4 hence total=8; On third row change, there are three elements, to total = 15 ( 3 * 5);
I have a table that consists of dates across the table headers and fruit down the left hand side. What i'm trying to do is get the date and the fruit eaten from a different object called 'eaten' and plot an X in the table row/column that coincides with the day it was consumed.
HTML
<table class="plan">
<thead>
<tr>
<th><strong>Food</strong></th>
<th>27/01/2017</th>
<th>28/01/2017</th>
<th>29/01/2017</th>
<th>30/01/2017</th>
<th>31/01/2017</th>
<th>01/02/2017</th>
<th>02/02/2017</th>
</tr>
</thead>
<tbody>
<tr><td>Apple</td></tr>
<tr><td>Banana</td></tr>
<tr><td>Carrot</td></tr>
<tr><td>Pear</td></tr>
</tbody>
</table>
The food titles are created via javascript from one object 'food', the dates are generated via momentJS and 'eaten' is the object data I want to plot from.
Javascript
var food = '{"food":[{"Name":"Apple"},{"Name":"Banana"},{"Name":"Carrot"},{"Name":"Pear"}]}';
$.each(JSON.parse(food), function(i, f) {
var tblRow = "";
tblRow += "<tr><td>" + f.Name + "</td></tr>";
$(tblRow).appendTo(".plan tbody");
});
for(i = 7; i > 0; i--) {
var day = moment().subtract('days', i).format('DD/MM/YYYY');
$('<th>' + day + '</th>').appendTo('.plan thead tr');
};
var eaten = '{"eaten":[{"fields":[{"value":"02/02/2017"},{"value":"Carrot"}]},{"fields":[{"value":"31/01/2017"},{"value":"Pear"}]},{"fields":[{"value":"30/01/2017"},{"value":"Banana"}]},{"fields":[{"value":"29/01/2017"},{"value":"Apple"}]},{"fields":[{"value":"27/01/2017"},{"value":"Apple"}]}]}'
What is the best way to go about plotting an X from the eaten object?
Should I get the cellIndex / rowIndex then compare the html text and plot an X?
JSFiddle
My suggestion (without changing your data schema and trying to not change much of your code logic):
parse your JSON once, for further reuse:
var eaten = JSON.parse(eatenJSON);
var food = JSON.parse(foodJSON);
populate a days array with your days.
var days = [];
for(i = 7; i > 0; i--) {
var day = moment().subtract('days', i).format('DD/MM/YYYY');
days.push(day);
}
set data-day and data-food in your td element;
for (var i=0; i<days.length; i++) {
tblRow += "<td data-day='" + days[i] + "' data-food='" + f.Name + "'></td>";
}
iterate over the eaten structure, find the elements with correspondent data-day anddata-food and, set their innerText with X, or whatever you want.
/* fill table */
eaten.eaten.forEach( function(userEaten) {
var fields = userEaten.fields;
var day = fields[0].value;
var food = fields[1].value;
document.querySelectorAll("td[data-day='" + day + "'][data-food='" + food + "']").forEach(function(td) {
td.innerText = "X";
});
});
Working fiddle: https://jsfiddle.net/mrlew/5gj4udf6/1/
EDIT: Updated the fiddle with your new JSON: https://jsfiddle.net/mrlew/5gj4udf6/2/
Just replaced this line
$.each(food, function(i, f) {
with:
food.food.forEach(function(f) {
I'm creating a dropdownlist of year.
How can I automatically populate the dropdownlist?
For example, I will be adding a dropdown value 1980, can I use jQuery to populate it to the current year, so I will not need to type all the year?
You can use a for loop between 1980 and the current year, which you can retrieve through the getFullYear() property of a Date object. Try this:
var html = '';
for (var i = 1980; i <= new Date().getFullYear(); i++) {
html += '<option value="' + i + '">' + i + '</option>';
}
$('#mySelect').html(html);
Working example
If you'd prefer to start with the current year and work down, you can use a negative iteration, like this:
for (var i = new Date().getFullYear(); i >= 1980; i--) {
html += '<option value="' + i + '">' + i + '</option>';
}
It's simple using a for loop and adding to string like:
var nowY = new Date().getFullYear(),
options = "";
for(var Y=nowY; Y>=1980; Y--) {
options += "<option>"+ Y +"</option>";
}
$("#years").append( options );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="years"></select>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear
http://api.jquery.com/append/
You can use a for loop (http://www.w3schools.com/js/js_loop_for.asp)
function fillDates(startDate){
yr = new Date().getFullYear();
options = "";
for(var i=startDate, i<=yr, i++){
options += ("<option value = "+i+">"+i+"</option");
}
$("select").append(options);
}
fillDates(1908);
chong there are lots of answers, i am little bit let to update my answer to jsFiddle.
fiddle : https://jsfiddle.net/eua98tqa/8/
HTML:
<html>
<head>
</head>
<body>
<select>
</select>
</body>
</html>
jQuery:
var fromYear = 1980;
var currentYear = new Date().getFullYear();
for (var i = fromYear; i <= currentYear; i++) {
$("select").append('<option value="' + i + '">' + i + '</option>');
}
I have more than one year dorpdowns, for which I wanted to compute year list from one specific year till current year. Commenting my final solution, may be somebody can find this useful:
function populateYearList(minYear, currentYear, selectElement){
var max = currentYear, min = minYear;
for (var i = min; i<=max; i++) {
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = i;
selectElement.append(opt);
}
//selecting current year by default and adding "selected" attribute to it
$(selectElement).val(max)
.find("option[value=" + max +"]")
.attr("selected","selected");
}
calling on page load
var selectElement = $('.select-class');
populateYearList('2015', currentYear, selectElement);
please refer code below
<input type="text" id="inputyear">
<select id="selectyear">
</select>
<input type="button" value="Generate" onclick="FillYears()">
<script type="text/javascript">
function FillYears(){
for(var i=parseInt($("#inputyear").val());i<=(new Date().getFullYear());i++)
{
$("#selectyear").append($("<option>"+i+"</option>"));
}
}
</script>
I'm having Javascript with this code:
function addRowss(frm) {
var start = new Date(document.myform.bookstart.value);
var ends = new Date(document.myform.bookend.value);
var starts = document.myform.bookstart.value;
var yeara = starts.substring(0, 2);
var montha = starts.substring(3,6);
var datea = starts.substring(7,11);
var num3 = (ends - start)/1000/60/60/24;
var i;
for(i=0;i <= num3; i++)
{
var theday = yeara+'-'+getnumo(montha)+'-'+datea;
var resday = new Date(theday);
rowNum ++;
var row = '<p id="rowNum'+rowNum+'">Date: <input type="text" class="datepick" name="qty[]" id="date'+rowNum+'" value="'+theday+'"> Price: <input type="text" name="name[]" value="'+frm.add_name.value+'"> <input type="button" value="Remove" onclick="removeRow('+rowNum+');"></p>';
jQuery('#itemRows').append(row);
yeara++;
}
}
What I want to do is text name[] will be automatically filled by my start date to my end date. For example, if I fill '06-Aug-2015' at start input and '06-Sep-2015' at end input, it will result about 30 textbox field which it's value will be filled by its date... so it will result:
[2015-08-06][ empty ]
[2015-08-07][ empty ]
[2015-08-08]
...
[2015-09-06][ empty ]
Note: [ ] = textbox
Right now I can add many textbox (attachment pic), but I can't set the value of this textbox as I want. Any idea?
You should write a function to parse that format to a Date object, it's a non–standard format so no guarantee that the Date constructor will parse it correctly in all browsers. Then create a function to create a date string from a Date object in the format you require. Now you can generate the rows and just call the functions to add the formatted strings, incrementing the date by one day as you go along.
Here's how I'd rewrite your code to do that, you can get rid of the rowNum variable, I've modified the remove listener and function so it's not required.
// '06-Sep-2015' to Date
function parseDMY(s) {
var months = {jan:0, feb:1, mar:2, apr:3, may:4, jun:5, jul:6, aug:7, sep:8, oct:9, nov:10, dec:11};
var b = s.split('-');
return new Date(b[2],months[b[1].toLowerCase().substring(0,3)],b[0]);
}
// Date to '06-Sep-2015'
function formatDate(date) {
var months = ['Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'];
function z(n){return (n<10? '0' : '') + n;}
return z(date.getDate()) + '-' + months[date.getMonth()] + '-' + date.getFullYear();
}
function addRows(frm) {
var start = parseDMY(frm.bookstart.value);
var ends = parseDMY(frm.bookend.value);
var markup = '';
var num3 = Math.round((ends - start)/8.64e7);
var rowNum = 0;
for(var i=0; i <= num3; i++) {
var theday = formatDate(start);
++rowNum;
markup += '<p id="rowNum' + rowNum + '">Date: <input type="text" class="datepick" name="qty[]" id="date' +
rowNum + '" value="' + theday + '"> Price: <input type="text" name="name[]" value="' +
frm.add_name.value + '"> <input type="button" value="Remove" onclick="removeRow(this);"></p>';
start.setDate(start.getDate() + 1);
}
document.getElementById('itemRows').innerHTML = markup;
}
function removeRow(el) {
var node = el.parentNode;
node.parentNode.removeChild(node);
}
<form id="bookingForm">
<table>
<tr><td>Start date<td><input name="bookstart" value="05-Aug-2015">
<tr><td>End date<td><input name="bookend" value="08-Aug-2015">
<tr><td><input name="add_name" value="the name">
<tr><td><input type="reset"><td><input type="button" value="Add rows" onclick="addRows(this.form)">
</table>
<div id="itemRows"></div>
</form>