I have a situation here, I need to calculate tax on the basis of an input using JavaScript. Here is the code:
PHP CODE:
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Subtotal</td>
<td class="total-value"><div id="subtotal">$0.00</div></td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Tax(%)</td>
<td class="total-value"><textarea id="txp">0.00</textarea></td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Taxes</td>
<td class="total-value"><div id="tax">$0.00</div></td>
</tr>
JavaScript code:
function update_tax() {
var txc = $("txp").val() * $("#subtotal").val() / 100;
$("#tax").html(txc);
}
$("#txp").blur(update_tax);
But the function is not working. Can anyone please help me with why this is not working?
Change
<td class="total-value"><div id="subtotal">$0.00</div></td>
to :
<td class="total-value">$<span id="subtotal">0.00</span></td>
and your code to:
$(document).ready(function(){
function update_tax() {
var txc = parseFloat($("#txp").val()) * parseFloat($("#subtotal").text()) / 100;
$("#tax").html("$"+txc);
}
$("#txp").blur(update_tax);
});
Now the code starts executing when the page has fully loaded. I moved the $-sign from the div and changed the div to a span (inline). So $ and value appear on the same line.
In the multiplying function I used parseFloat to convert any string to a float. The content from the textarea can be retrieved using jQuery val() the content of the span using text(). Also in the function you used txp as a selector, which will refer to a node with the name txp. Updated it to #txp to select the element with id: txp.
Related
I have a table in html that has a ton of data that I don't want to change by hand. I basically have to update every single by a factor of .75. I figured the best way to do that would be to write a javascript function that takes the initial value of , multiplies it by .75, and then replaces it—but I'm stuck.
So, for instance, here's part of my table:
<tr>
<th class="headcol">PT 89</th>
<td id="test">100</td>
<td id="test">99</td>
<td id="test">98</td>
<td id="test">*</td>
<td id="test">97</td>
<td id="test">96</td>
<td id="test">95</td>
<td id="test">94</td>
<td id="test">93</td>
<td id="test">92</td>
</tr>
Here's the javascript I tried running, but it didn't work:
function product() {
let num1 = document.getElementById("test")
let sum1 = num1 * 0.75
document.getElementById("test").innerHTML = sum1
}
Does anyone have any tips?
Thank you very much!
I see you tagged this with jQuery so here is simple solution without changing current HTML markup:
$(document).ready(function() {
$(".headcol").siblings("td").each(function() {
$(this).text(Math.round(parseFloat($(this).text()) * 0.75 || $(this).text())||$(this).text());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th class="headcol"> PT 89</th>
<td id="test">100</td>
<td id="test">99</td>
<td id="test">98</td>
<td id="test">*</td>
<td id="test">97</td>
<td id="test">96</td>
<td id="test">95</td>
<td id="test">94</td>
<td id="test">93</td>
<td id="test">92</td>
</tr>
</table>
EDIT:
to round it as requested, just wrap it into Math.round just like it is wrapped in parseFloat, So first you take text, convert into floating number, do calculation and then round it.
Math.round is like parseFloat is pure JS but you can easily apply it to selected value with jQuery. It would be maybe clearer if its done step by step, but one-liners are also popular ;)
Also to clarify it, || $(this).text() part on Math.round and parseFloat is to return text if its not a number, in your case *
function product() {
const tds = document.querySelectorAll(".test");
tds.forEach(td => {
const value = +td.textContent * 0.75;
if (!isNaN(value)) {
td.textContent = value;
}
});
}
product();
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <!-- Ignore this -->
<table class="table table-bordered">
<tr>
<!-- Never use duplicate id attribute, use class instead -->
<th class="headcol"> PT 89</th>
<td class="test">100</td>
<td class="test">99</td>
<td class="test">98</td>
<td class="test">*</td>
<td class="test">97</td>
<td class="test">96</td>
<td class="test">95</td>
<td class="test">94</td>
<td class="test">93</td>
<td class="test">92</td>
</tr>
</table>
I would like to have keyup function that would show only rows matching the input text by cell that spans on multiple rows.
Consider following table:
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1'> dummy1 </td>
</tr>
<tr>
<td name='Key1'> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2'> dummy3 </td>
</tr>
<tr>
<td name='Key2'> dummy4 </td>
</tr>
</table>
jsfiddle
Here each row has second td tag with name that matches its "parent" column text. So when I type 'Key1' at the input field I would like it to show only dummy1 and dummy2. Is it possible in jquery?
I understand that you want to display the rows that has a matching name. If this is wrong, please elaborate more, then I can update it.
Here is a demo: https://jsfiddle.net/erkaner/gugy7r1o/33/
$('input').keyup(function(){
$('tr').hide();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(keyword) != -1; }).parent().show().next().show();
});
});
Here's my take on your issue, assuming you always want the first column to show. https://jsfiddle.net/gugy7r1o/2/
<input type="text" id="myInput" />
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1' class="data"> dummy1 </td>
</tr>
<tr>
<td name='Key1' class="data"> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2' class="data"> dummy3 </td>
</tr>
<tr>
<td name='Key2' class="data"> dummy4 </td>
</tr>
</table>
.data{
display:none;
}
var theData = $('td.data');
var input = $('#myInput').on('keyup', function(){
theData.hide();
var value = input.val();
var matches = theData.filter('[name="'+value+'"]');
matches.show();
});
Firstly, I would recommend using <ul> to wrap each key in as tables should be used for data structure (Forgive me if that is what it is being used for).
Secondly, just attach an on keyup event to the search box and then find matches based on the id. See example below:
JS Fiddle Demo
It is also worth mentioning that it could be useful attaching a timeout to the keyup event if you end up having large amounts of rows so that only one filter is fired for fast typers!
I am traversing the divs on my page and looking up child elements using find and supplying a classname
select elements and input elements are located, but the 3 TDs I am trying to find are returning nothing
Here is the code snippet
$.each($(".ccypair"), function(index, element) {
var elements = {
selectElement : $(element).find('.selectstyle'),
inputElement : $(element).find('.inputstyle'),
tdElement1 : $(element).find('.decayTime'),
tdElement2 : $(element).find('.price.bidprice'),
tdElement3 : $(element).find('.price.offerprice')
};
});
Now the first two find() lines work fine, but the three tdElement ones below resolve to nothing. Anyone able to tell me where I am going wrong. I suspect for TD I need to have a different selector?
Apologies here is the html
<div class="ccypair" id="ccypairdiv_0">
<form>
<table>
<tr>
<td colspan="2" class="top currency"><select class="ccypairselect"/></td>
<td colspan="2" class="top volume"><input class="ccypairvolume" type="text" value="1m" autocomplete="off"/></td>
<td colspan="2" class="decaytime">00h:00m:00s</td>
</tr>
<tr>
<td colspan="3" class="price bidPrice">---.---</td>
<td colspan="3" class="price offerPrice">---.---</td>
</tr>
</table>
</form>
</div>
<div class="ccypair" id="ccypairdiv_1">
<form>
<table>
<tr>
<td colspan="2" class="top currency"><select class="ccypairselect"/></td>
<td colspan="2" class="top volume"><input class="ccypairvolume" type="text" value="1m" autocomplete="off"/></td>
<td colspan="2" class="top decaytime">00h:00m:00s</td>
</tr>
<tr>
<td colspan="3" class="price bidPrice">---.---</td>
<td colspan="3" class="price offerPrice">---.---</td>
</tr>
</table>
</form>
</div>
Thanks
First check if your jQuery is loading with the $, the try this
//think about structure, it makes your code more legible
$(".ccypair").each(function(index) {
var element = $(this); //each .ccypair found
var elements = {
selectElement : element.find('.selectstyle'),
inputElement : element.find('.inputstyle'),
tdElement1 : element.find('.decayTime'),
tdElement2 : element.find('.price.bidprice'),
tdElement3 : element.find('.price.offerprice')
};
});
cheers
As always a back to basics approach worked. A simple typo was the root cause here. Apologies
On that note. Does jQuery provide a flag so that rather than failing to locate an element and failing silently it will print out an error message. This would be really helpful?
Any ideas why this doesn't work?
http://jsfiddle.net/zk4pc/2/
I'm trying to get it so that everytime there is an element with the class "insert_name", the name is printed from the table.
Could you also help me make the selection more advanced (for instance only using the data from the first tr in the "client-profile" class?
Thanks!
HTML
<body onload="printMsg()">
<div id="api_data" style="display:none;">
<div class="client-profile">
<div class="head icon-5">Customer Details</div>
<table id="client-information">
<tbody>
<tr>
<td class="left">Name:</td>
<td class="color">Matthew Tester
</td>
</tr>
<tr class="dark">
<td class="left">E-mail:</td>
<td class="color">asdfg</td>
</tr>
<tr>
<td class="left">Registration:</td>
<td class="color">2013-11-21</td>
</tr>
<tr class="dark">
<td class="left">Status:</td>
<td class="color"><span class="active">Active</span>
</td>
</tr>
<tr>
<td class="left">Last Login Time:</td>
<td class="color" title="2014-05-28 11:43:46">1 hour ago</td>
</tr>
<tr class="dark">
<td class="left">Last Login From:</td>
<td class="color">123.123.123.123</td>
</tr>
<tr>
<td class="left">Location:</td>
<td class="color">United Kingdom</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="insert_name"></div>
</body>
Javascript
(function printMsg() {
var node = document.getElementsByClassName('insert_name');
node.innerHTML = $('[class*="color"]').eq(0).text();
})();
jsFiddle Demo
The issue is with your node selection. When you select by class name it returns an array of elements. Since you are only looking for the div with that class name, access the first index to reference it.
var node = document.getElementsByClassName('insert_name')[0];
edit
To make this iterate all of the nodes you could take this approach
var nodes = document.getElementsByClassName('insert_name');
var text = $('[class*="color"]').eq(0).text();
for(var i = 0; i < nodes.length; i++){
nodes[i].innerHTML = text;
}
Alternatively, since jQuery is already included, you could remove the body's onload event and just use this
jsFiddle Demo
$(function(){
$('.insert_name').html($('[class*="color"]').eq(0).text());
});
To ensure this only acts on the client-profile class the selector would be
$('.insert_name').html($('.client-profile [class*="color"]').eq(0).text());
If you are just trying to insert the name rather than all of the content, this should do the trick:
$(function() {
$('.insert_name').text($('td:contains("Name:")').next().text());
});
Here is the fiddle:
http://jsfiddle.net/b8LKQ/
Hope that helps!
I added a little more jQuery:
$(function() {
$('[class*="color"]').each(function(){
$('.insert_name').append($(this).text());
});
});
http://jsfiddle.net/zk4pc/7/
Hope that helps!
The code below shows a rendered HTML (from Compiled ASP .Net code). I would not be able to make any changes to it including adding new attributes like ID.
I could still do something with Javascript but because there is no unique ID for the column, I could not replace the underscore text "____________" with some other text.
The plan is to replace the underscore in column 3 for each row with some other text. Is there a way to identify Column 3 with Javascript?
Thank you.
<table width='100%'>
<tr>
<td align="left" valign="top" class='clsReadOnly'>Row 1
</td>
<td align="left" valign="top" class='clsReadOnly'>
abc
</td>
<td align="left" valign="top" class='clsReadOnly'>
__________________________
</td>
</tr>
<tr>
<td align="left" valign="top" class='clsReadOnly'>Row 2
</td>
<td align="left" valign="top" class='clsReadOnly'>
def
</td>
<td align="left" valign="top" class='clsReadOnly'>
__________________________
</td>
</tr>
<tr>
<td align="left" valign="top" class='clsReadOnly'>Row 3
</td>
<td align="left" valign="top" class='clsReadOnly'>
ghi
</td>
<td align="left" valign="top" class='clsReadOnly'>
__________________________
</td>
</tr>
</table>
If this is the only table on the page, you can do it with jQuery:
$('table')
.children('tr')
.each(function() {
$(this).children('td:last').html('<p>A Paragraph of Text</p>');
});
It depends on what you are trying to accomplish. If this is how your table will always look, you could do the following:
var cells = document.getElementsByClassName('clsReadOnly');
cells[2].innerHTML = "Row1 Column3";
cells[5].innerHTML = "Row2 Column3";
cells[8].innerHTML = "Row3 Column3";
If you don't know how many columns you will start with, you would have to do this:
var rows = document.getElementsByTagName('tr');
for (var i=0; i<rows.length; i++) {
var cells = rows[i].getElementsByTagName('td');
cells[2].innerHTML = 'Row'+(i+1)+' Column3';
}
jQuery would make this much easier, as you can select by tag, by parent, etc. Of course, you can do all of this in plain JavaScript, but it takes a lot more work.
http://jsfiddle.net/bShZa/
getElementsByClassName() is HTML5 and is not currently supported in IE. Here is the jsfiddle for the solution http://jsfiddle.net/V38MF/2/ w/o jQuery needed
var myTable = document.getElements('td');
for(var i=0; i<myTable.length; i++){
if((i+1)%3 == 0)
console.log(myTable[i].innerHTML);
}