Since I have couple of entries that needs to be divided with the number i provide (num1 variable), I find the difficulties to complete the task.
I want the loop to divide me and store value from each variable called listX with 34. There are 9 lists (each has different number) and i want each list to be divided with the number i provide, but to be divided first with 2, then with 3, then with 4, 5 ... up to the number i provide.
I figured out that it could be done best with objects, but I can't find the solution, since I'm not so experienced with this stuff. The ideal would be to get the objects like:
List1: 1st division: xxx
List1: 2nd division: xxx
List1: 34th division: xxx
...
List 8: 22nd division: xxx
...
List 9: 33rd divison: xxx
List 9: 34th division: xxx
"xth division" should be linked with the number i provided in the num1 variable
What I'm trying to get is something like this:
It asks me how many times i want my values to be divided, i type in 5. Then it asks me what are the values of my 9 inputs.
I declare to the first input 100. The result what I want should be:
100/1 = 1
100/2 = 50
100/3 = 33,33
100/4 = 25
100/5 = 20
Then I declare to the second input number 200. The result should be:
200/1 = 200
200/2 = 100
200/3 = 66,66
200/4 = 50
200/5 = 40
It goes all the way up until my last input...
What I'm trying to develop is D'Hondt method for seat allocations in the parliament that is being used for some countries.
Here is what I've got so far, but ofc, it is not working.
var array1 = [];
var list = "list";
function someFunction() {
var num1 = 34;
for (var i = 1; i <= num1; ++i) {
for (var j = 1; j <= 9; j++) {
array1[j] += document.getElementById(list + j).value / i;
array1[j] += "<br/>";
}
}
document.getElementById("demo1").innerHTML = list + j;
}
<tr>
<td><input type="text" id="list1" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list2" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list3" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list4" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list5" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list6" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list7" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list8" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list9" style="width:50px" onkeyup="someFunction()"></input></td>
</tr>
I think this is what you are looking for, but a couple of notes.
A couple of notes:
The input element does not have a closing tag.
type="text is the default for input elements, so you don't need
to write it.
Don't Repeat Yourself (DRY). Since all of your input elements need
the same styling, just set up a single CSS rule to style them all the
same way.
Don't use inline HTML event handlers. Separate your JavaScript from
your HTML and follow modern standards.
See the comments below for details.
// Get the number to divide by (You can get this anyway you want. A prompt is show here.):
var num = +prompt("How many calculations per input would you like?");
// Get all the table inputs into an array
var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input[id^='input']"));
// Loop over the input array...
inputs.forEach(function(input){
// Set up an event handler for the input
input.addEventListener("input", someFunction);
});
function someFunction(){
var resultString = "";
for(var i = 0; i < num; i++){
// Do the math and build up the string
resultString += (this.value / (i + 1)) + "<br>";
}
// Update the output cell that corresponds to the input element with the results
document.querySelector("#" + this.id.replace("input", "output")).innerHTML = resultString;
}
td > input { width:50%; }
<table id="inout">
<tr>
<td><input id="input1"></td>
<td><input id="input2"></td>
<td><input id="input3"></td>
<td><input id="input4"></td>
<td><input id="input5"></td>
<td><input id="input6"><td>
<td><input id="input7"></td>
<td><input id="input8"></td>
<td><input id="input9"></td>
</tr>
<tr>
<td id="output1"></td>
<td id="output2"></td>
<td id="output3"></td>
<td id="output4"></td>
<td id="output5"></td>
<td id="output6"><td>
<td id="output7"></td>
<td id="output8"></td>
<td id="output9"></td>
</tr>
</table>
<div id="output"></div>
Related
I am trying to get the values from an html table.
I have tried row.cells[j].innerHTML which returns <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5">
I have also tried row.cells[j].innerHTML.text, row.cells[j].innerHTML.value, and row.cells[j].outterHTML which all return undefined. Any ideas?
An overview of what I want happening: user enter values in the dynamic table, adding / deleting rows as needed. Once table is filled, user clicks save which calls GetTableValues() which loops through the table adding each fields value to a string. Each value is separated by % and each row is separated by #. I then assign that string to a hidden field which I can access in my VB.Net code which then parses the data to save to a database.
It is looping through table but (as seen in the logs below), it does not get the values from the table
Here is the javascript and html of the table and looping through the table.
function GetTableValues() {
var s = "";
console.log("enter function");
//Reference the Table.
var table = document.getElementById("dataTable");
//Loop through Table Rows.
for (var i = 1; i < table.rows.length; i++) {
//Reference the Table Row.
var row = table.rows[i];
console.log("outside nest " + s);
for (var j = 1; j < 6; j++) {
console.log("i= " + i + " j= " + j);
//Copy values from Table Cell to JSON object.
console.log("inside nest " + row.cells[j].innerHTML +"%");
s = s + row.cells[j].innerHTML +"%";
}
console.log("outside again " + s);
s = s + "#";
}
document.getElementsByName("drawingsHidden").value = s
console.log(document.getElementsByName("drawingsHidden").value);
}
<table id="dataTable" style="width:100%">
<tr>
<th>Check Box</th>
<th>CAGE</th>
<th>Dwg #</th>
<th>Dwg Rev</th>
<th>Prop Rev</th>
<th>Issued Rev</th>
<th>Status</th>
</tr>
<tr>
<td><input type="checkbox" id="chkbox" /></td>
<td><input type="text" id="Text2" maxlength="5" runat="server" text=""/></td>
<td><input type="text" id="DRAWINGNUM" maxlength="20" runat="server" text=""/></td>
<td><input type="text" id="DRAWINGREV" maxlength="2" runat="server" text=""/></td>
<td><input type="text" id="PROPREV" maxlength="2" runat="server" text=""/></td>
<!--tie these fields to the drawing tracking form-->
<td><input type="text" id="ISSUEDREV" maxlength="2" runat="server" text=""/></td>
<td><input type="text" id="Text3" maxlength="20" runat="server" text=""></td>
</tr>
</table>
enter function
outside nest
i= 1 j= 1
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5" text="">%
i= 1 j= 2
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGNUM" type="text" id="MainContent_Nav_SiteContent_DRAWINGNUM" maxlength="20" text="">%
i= 1 j= 3
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGREV" type="text" id="MainContent_Nav_SiteContent_DRAWINGREV" maxlength="2" text="">%
i= 1 j= 4
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$PROPREV" type="text" id="MainContent_Nav_SiteContent_PROPREV" maxlength="2" text="">%
i= 1 j= 5
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$ISSUEDREV" type="text" id="MainContent_Nav_SiteContent_ISSUEDREV" maxlength="2" text="">%
outside again <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGNUM" type="text" id="MainContent_Nav_SiteContent_DRAWINGNUM" maxlength="20" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGREV" type="text" id="MainContent_Nav_SiteContent_DRAWINGREV" maxlength="2" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$PROPREV" type="text" id="MainContent_Nav_SiteContent_PROPREV" maxlength="2" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$ISSUEDREV" type="text" id="MainContent_Nav_SiteContent_ISSUEDREV" maxlength="2" text="">%
Picture of the table
row.cells[j] is a TD Element, not an Input element.
By doing console.log(row.cells[j]) it's the easiest way to detect what is actually hold by some property. Then, having that element all it takes is to query for a child element Input. const EL_input = row.cells[j].querySelector("input"). Now that you have your input Element: const value = EL_input.value
Don't overuse ID selectors. Specially not in a table. It makes no sense for columns to contain elements with IDs, you might either run into a duplicated IDs issue or actually you don't necessarily need a Table.
Use NodeList.prototype.forEach(). It's simpler and easier than using daunting for loops.
You could also create some nifty DOM helpers to ease on your self Querying the DOM for elements
Use .console.log() or debugger to test your code.
// DOM helpers:
const EL = (sel, par) => (par || document).querySelector(sel);
const ELS = (sel, par) => (par || document).querySelectorAll(sel);
// Task:
const getTableValues = () => {
let str = "";
ELS("#dataTable tbody tr").forEach(EL_tr => {
ELS("td", EL_tr).forEach(EL_td => {
str += EL("input", EL_td).value + "%";
});
str += "#";
});
EL("#drawingsHidden").value = str
};
EL("#test").addEventListener("click", getTableValues);
#dataTable {
width: 100%;
}
<table id=dataTable>
<thead>
<tr>
<th>Check Box</th>
<th>CAGE</th>
<th>Dwg #</th>
<th>Dwg Rev</th>
<th>Prop Rev</th>
<th>Issued Rev</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type=checkbox></td>
<td><input type=text maxlength=5></td>
<td><input type=text maxlength=20></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=20></td>
</tr>
</tbody>
</table>
<button id=test type=button>CLICK TO TEST</button><br>
<input id=drawingsHidden type=text>
var table = document.getElementsByTagName('table')[0]
var td = table.getElementsByTagName('td')[0]
var input = td.getElementsByTagName('input')[0]
console.log(input.value)
<table>
<tr>
<td><input value=7><td>
</tr>
</table>
I was only able to insert a "$" sign in a3. I also need to insert the "$" sign for a1 but when I insert format for a1 field in like this
$('#a3').val(format($('#a1').val(format) * $('#a2').val()));
I get an error. What is the best way to do this?
HTML
<table class="table">
<tbody>
<tr>
<td>You</td>
<td class="light-gray">Example</td>
</tr>
<tr>
<td width="20%">a1
<input type="textbox" class="form-control" id="a1" name="a1" />
</td>
<td width="20%" class="light-gray">$30,000</td>
</tr>
<tr>
<td>a2
<input type="text" class="form-control" id="a2" name="a2" />
</td>
<td class="light-gray">90%</td>
</tr>
<tr>
<td>a3
<input type="text" class="form-control" id="a3" name="a3" data-cell="a3" />
</td>
<td class="light-gray">$27,000</td>
</tr>
<tr class="heading">
<th colspan="2"> </th>
</tr>
</table>
jQuery
$(document).ready(function () {
var format = function (num) {
var str = num.toString().replace("$", ""),
parts = false,
output = [],
i = 1,
formatted = null;
if (str.indexOf(".") > 0) {
parts = str.split(".");
str = parts[0];
}
str = str.split("").reverse();
for (var j = 0, len = str.length; j < len; j++) {
if (str[j] != ",") {
output.push(str[j]);
if (i % 3 == 0 && j < (len - 1)) {
output.push(",");
}
i++;
}
}
formatted = output.reverse().join("");
return ("$" + formatted + ((parts) ? "." + parts[1].substr(0, 2) : ""));
};
$("#a1,#a2").keyup(function (e) {
$('#a3').val(format($('#a1').val() * $('#a2').val()));
});
});
JSFiddle Examples
Your problem is that you assume the values inside the inputs to be numbers. Since you format those with non-digit-characters they are not (and can not be casted to a number).
$('#a1').val() * $('#a2').val()
Since the values you are multiplying are no numbers an error is thrown.
To be able to multiply those strings (or to be exact the value they are representing) you need to unformat your strings before you can cast those to numbers and do your calculation!
You'll find an working example at https://jsfiddle.net/hn669das/18/.
By the way: Better use the change-event for formatting instead of the keyUp-event since the user won't be able to write into the input undisturbed when the input is manipulated while the user intends to write to it. The change-event will trigger when the input looses its focus and so won't disturb the user.
I hope that helps you!
I am having a hard time with this homework.
Trying to keep adding the multiplication of the new 2 fields the user will add.
Example:
first field 5 second field 5 = total is 5*5 = 25
But when the user clicks the add field, he would have:
first field = 5 second field 5
first field = 6 second field 6 total would be 5*5 + 6*6 = 61 and so forth
<script>
function calc(form) {
var box1 = parseFloat (form.leftover.value,10)
var box2 = parseFloat (form.charge.value,10)
var temp = new Array();
var Mbalance = ( box1 * box2 ) ;
temp.push(Mbalance) ;
for ( var i=0; i< temp.length ; i++ ) {
Mbalance = Mbalance+Mbalance ;
}
form.mbalance.value= Mbalance ;
}
// This script is identical to the above JavaScript function.
var ct = 1;
function new_link(form) {
ct++ ;
var div1 = document.createElement('div');
div1.id = ct;
// Link to delete extended form elements
div1.innerHTML = document.getElementById('newlinktpl').innerHTML ;
document.getElementById('newlink').appendChild(div1);
}
</script>
</script>
<form>
<div id="newlink">
<div>
<td width="423">What was the balance left over from last month ?</td>
<td width="19">$</td>
<td width="141"><input name="leftover" value="" maxlength="10" /></td>
</tr>
<tr>
<td>How much did you charge this month ?</td>
<td>$</td>
<td><input name="charge" value="" maxlength="10" /></td>
<br/>
</div></div>
<button type="submit" id="buttoncalculate" onclick="calc(this.form); return false; "></button>
<br />
<td width="462">Monthly Balance</td>
<td width="128"><input name="mbalance" value="" maxlength="10" /></td>
Add new
</form>
<form>
<!-- Template -->
<div id="newlinktpl" style="display:none">
<div>
<td width="423">What was the balance left over from last month ?</td>
<td width="19">$</td>
<td width="141"><input name="leftover" value="" maxlength="10" /></td>
</tr>
<tr>
<td>How much did you charge this month ?</td>
<td>$</td>
<td><input name="charge" value="" maxlength="10" /></td>
</div>
</div>
<form>
Here's one way you can do it. It's not necessarily the best, but it achieves what you want and I don't feel like completely rewriting what you had:
http://jsfiddle.net/HS6dt/2/
I added a class to the parent div of your two inputs as well as your two inputs. That way I can find the parent div, then find the descendant inputs, get their values and multiple them (note: I have no idea why you are multiplying those two values, it really doesn't make much sense, but whatever):
function calc(form) {
var total = 0;
var items = document.getElementsByClassName("item");
for (var i = 0; i < items.length; i++) {
var left = items[i].getElementsByClassName("leftover");
var charge = items[i].getElementsByClassName("charge");
total += parseFloat(left[0].value, 10) * parseFloat(charge[0].value, 10);
}
form.mbalance.value = total;
}
I need to display the percentage each input value contains out of the full dataset.
So if the user inputs 3, 2 and 1. The "percent" inputfield should show "50, 30 and 20"
The thing is, i dont know how many inputs the form will get. It could be from 1 to any number.
The source html code is created by a partial view i created. The output is:
<table>
<tr>
<th>Name</th><th>Distributiob key</th><th>Percent</th>
</tr>
<tr>
<td>
House 1
</td>
<td>
<input type="text" size="5" value="0" id="LightPhysicalEntities_0__DistributionKey" name="LightPhysicalEntities[0].DistributionKey" />
</td>
<td>
<input type="text" size="5" id="LightPhysicalEntities_0__Percent" readonly=readonly />
</td>
</tr>
<tr>
<td>
House 2
</td>
<td>
<input type="text" size="5" value="0" id="LightPhysicalEntities_1__DistributionKey" name="LightPhysicalEntities[1].DistributionKey" />
</td>
<td>
<input type="text" size="5" id="LightPhysicalEntities_1__Percent" readonly=readonly />
</td>
</tr>
<tr>
<td>
House 3
</td>
<td>
<input type="text" size="5" value="0" id="LightPhysicalEntities_2__DistributionKey" name="LightPhysicalEntities[2].DistributionKey" />
</td>
<td>
<input type="text" size="5" id="LightPhysicalEntities_2__Percent" readonly=readonly />
</td>
</tr>
First field in the table is the title or name. Second is where the user punches in distribution number. Third is the readonly field with the calculated percentage.
The calculation should be done in javascript, but i cant quite crack the nut on how to get started, getting the inputs and setting the outputs.
A function like this should help (this will round down the percentages- replace the Math.floor if you want to handle differently):
function calcPcts() {
var distributions = $("[id$=DistributionKey]");
// Get the base first
var base = 0;
distributions.each(function () {
base += window.parseInt($(this).val(), 10);
});
// Now calculate the percentages of the individual ones
distributions.each(function () {
var input = $(this),
val = window.parseInt($(this).val(), 10),
pct = (val === 0) ? val : Math.floor((val / base) * 100);
$("#" + input.attr("id").replace("DistributionKey", "Percent")).val(pct);
});
}
If you add a class to the input fields you can use jQuery to get the number of items with that class. Then you can get the values and perform your calculations.
Here is an example:
var inputCount = $(".inputfield").length;
$("input[type='text']").change(function() {
var total = GetTotal();
for (i = 0; i < inputCount; i++) {
var inputValue = $('#LightPhysicalEntities_' + i + '__DistributionKey').val();
if (total != 0) {
var percent = inputValue / total;
$('#LightPhysicalEntities_' + i + '__Percent').val(percent);
}
}
});
function GetTotal() {
var total = 0;
for (i = 0; i < inputCount; i++) {
var inputValue = $('#LightPhysicalEntities_' + i + '__DistributionKey').val();
total += parseInt(inputValue);
}
return total;
}
Here is an example of the script working: http://jsfiddle.net/ZWuQr/
I have a table including input text fields with the basic structure below. I am having trouble building a function to iterate all rows in the table and sum all the values of input fields beginning with BFObel where the value of the field beginning with BFOkto are the same. So for the basic example below the sum for value 1111 would be 2000 and the sum for value 1112 would be 3000. Each sum would then be written to an inputfield with the id field1111, field1112 etc...
<table>
<tr id="BFOrow1">
<td><input type="text" id="BFOtxt1" value="text"/></td>
<td><input type="text" id="BFOkto1" value="1111" /></td>
<td><input type="text" id="BFObel1" value="1000" /></td>
</tr>
<tr id="BFOrow2">
<td><input type="text" id="BFOtxt2" value="text"/></td>
<td><input type="text" id="BFOkto2" value="1111" /></td>
<td><input type="text" id="BFObel2" value="1000" /></td>
</tr>
<tr id="BFOrow3">
<td><input type="text" id="BFOtxt3" value="text"/></td>
<td><input type="text" id="BFOkto3" value="1112" /></td>
<td><input type="text" id="BFObel3" value="1000" /></td>
</tr>
<tr id="BFOrow4">
<td><input type="text" id="BFOtxt4" value="text"/></td>
<td><input type="text" id="BFOkto4" value="1112" /></td>
<td><input type="text" id="BFObel4" value="1000" /></td>
</tr>
<tr id="BFOrow5">
<td><input type="text" id="BFOtxt5" value="text"/></td>
<td><input type="text" id="BFOkto5" value="1112" /></td>
<td><input type="text" id="BFObel5" value="1000" /></td>
</tr>
</table>
You'll want to use an object literal to track your results and an "attribute starts with" selector to find the text inputs:
var accumulator = { };
$('table input[id^=BFOkto]').each(function() {
var sum_id = this.id.replace(/^BFOkto/, 'BFObel');
if(!accumulator[this.value])
accumulator[this.value] = 0;
accumulator[this.value] += parseInt($('#' + sum_id).val(), 10);
});
// accumulator now has your results.
Don't forget the second argument to parseInt() so that you don't get tripped up by values with leading zeros (which look like octal without a specified radix).
For example: http://jsfiddle.net/ambiguous/QAqsQ/ (you'll need to run this in a browser with an open JavaScript console to see the resulting accumulator).
var sum1111 = 0;
$('input[value="1111"]').each(function() {
var ordinal = $(this).attr('id').replace('BFOkto', '');
sum1111 += parseInt($('#BFObel' + ordinal).val());
});
At the end, sum1111 should equal 2000.
For reuse, wrap the logic in a function:
function getSum(BFOkto) {
var sum = 0;
var ordinal = null;
$('input[value="' + BFOkto + '"]').each(function() {
ordinal = $(this).attr('id').replace('BFOkto', '');
sum += parseInt($('#BFObel' + ordinal).val());
});
return sum;
}
And then call:
getSum('1111');
getSum('1112');
A different approach: find all input fields with prefix BFOkto, for each, find the input with prefix BFObel sharing same parent and accumulate its value
ref = $("table td input[id^=BFOkto]");
var sums = new Object();
ref.each(function(){
val = parseInt($(this).closest('tr').find("td input[id^=BFObel]").val(), 10);
property = 'i'+ this.value;
sums[property] = (sums[property] || 0 ) + val;
});
alert(sums['i1111']);
alert(sums['i1112']);
sums will be an object with properties
i1111 = 2000
i1112 = 3000
Despite javascript allows it, it is better not to use pure numeric properties for objects (associative arrays), hence the i prefix
The running example is here:
http://jsfiddle.net/TbSau/1/