Append HTML block to an element with lowest value? - javascript

I have the following table:
<table id="sortme">
<tr>
<td>a</td>
<td>b <input type="hidden" name="pr" value="50"/>
</td>
</tr>
<tr>
<td>c</td>
<td>d <input type="hidden" name="pr" value="20"/>
</td>
</tr>
</table>
With the following script:
$(function () {
$('#sortme tr:has(input[name="pr"])').sort(function(a, b) {
return 1 * $(a).find("input[name='pr']").val() - 1 * $(b).find("input[name='pr']").val();
}).appendTo('#sortme');
});
The table will be re-sorted so that the second row, will become the first one, since 20 < 50.
Question:
In addition to that, how can I also append an HTML block right after the [input] that was found as the lowest, and reach this result:
<table id="sortme">
<tr>
<td>c</td>
<td>d <input type="hidden" name="pr" value="20"/>
<p class="min">Min. Value</p>
</td>
</tr>
<tr>
<td>a</td>
<td>b <input type="hidden" name="pr" value="50"/>
</td>
</tr>
</table>
I guess I should add some .appendTo("input[name='pr']") command as the last row to the script, but not sure how to do it.
Edit:
While Sachin's Solution is Good, I would also like to see a solution that appends the block to the lowest value, and will be independent of the first function which sorts the table. the reason is that I might want to append the block without doing any sorting.

try this.. if you want to do it without sort:
$(function () {
var min = $("#sortme input[name='pr']:first").val()
$("#sortme input[name='pr']").each(function(){
if(parseInt($(this).val()) < parseInt(min))
min = $(this).val();
});
$('<p class="min">Min. Value</p>').insertAfter("#sortme input[name='pr'][value='" + min + "']:first");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="sortme" border="1|0">
<tr>
<td>a</td>
<td>b <input type="hidden" name="pr" value="50"/>
</td>
</tr>
<tr>
<td>c</td>
<td>d <input type="hidden" name="pr" value="20"/>
</td>
</tr>
</table>
or this with sort:
after sorting.. this will insert p tag after first input of table, as after sorting the minimum value will be on top.
$('<p class="min">Min. Value</p>').insertAfter("#sortme input:first");
Appending it before sort will not solve the purpose because you won't be very sure about where is the minimum value, in the last, in the top or somewhere in the middle.

$(function () {
$('#sortme tr:has(input[name="pr"])').sort(function(a, b) {
return 1 * $(a).find("input[name='pr']").val() - 1 * $(b).find("input[name='pr']").val();
}).appendTo('#sortme').first().find("input[name='pr']").after('<p class="min">Min. Value</p>');
});

First search the input with least value:
var minValue = Math.min.apply( null, $("input[name='pr']").map(function(){return this.value;}) );
Then append to input with this value:
.appendTo("input[value='" + minValue + "']")

Related

Where do I implement the getElementById in my JavaScript function?

Background: For my website I have to count the number of checked checkboxes in a table. Depending on the result, there is then a different 'output'. As long as fewer than or equal to 2 checkboxes are checked --> output A. If more than 2 boxes are checked OR the first checkbox is checked --> output B.
Now to my problem: I specifically don't understand this line of code:
const checked = [...this.querySelectorAll(".choice:checked")].map(inp => +inp.value);
If I understand correctly, it checks all input fields in the form, adds and converts the results. But how can I implement an ID here that I only give to the first checkbox in order to solve the problem?
And another question: Can I then link the values ​​with a logical operator?
My code:
.hide {
display: none;
}
<form id="listForm">
<table>
<tbody>
<tr id="G">
<td><b>G</b></td>
<td></td>
<td><input type="checkbox" class="choice" id="cbg" name="choiceG" value="1"></td>
</tr>
<tr>
<td id="A"><b>A</b></td>
<td></td>
<td><input type="checkbox" class="choice" name="choiceA" value="1"></td>
</tr>
<tr>
<td id="B"><b>B</b></td>
<td></td>
<td><input type="checkbox" class="choice" name="choiceB" value="1"></td>
</tr>
<tr>
<td id="C"><b>C</b></td>
<td></td>
<td><input type="checkbox" class="choice" name="choiceC" value="1"></td>
</tr>
<tr>
<td colspan="2" ;="" style="text-align:right;"><b>Sum:</b></td>
<td><input disabled="" type="text" size="2" name="total" id="total" value="0"></td>
</tr>
</tbody>
</table>
</form>
<div id="showwhen2" class="hide">
<p>2 or less boxes checked; first box is unchecked</p>
</div>
<div id="showwhen3" class="hide">
<p>first box or more than two boxes are checked</p>
</div>
<script>
document.getElementById("listForm").addEventListener("input", function() {
let sum = 0;
let sumg = 0;
const checked = [...this.querySelectorAll(".choice:checked")].map(inp => +inp.value);
const checkedg = [...this.querySelectorAll(".choice:checked")].map(inp => +inp.value);
if (checked.length > 0) sum = checked.reduce((a, b) => a + b);
if (checkedg.length > 0) sumg = checkedg.reduce((a, b) => a + b);
console.log(sum);
console.log(sumg);
document.getElementById("total").value = sumg + sum;
document.getElementById("showwhen3").classList.toggle("hide", sum < 3 || sumg <1);
document.getElementById("showwhen2").classList.toggle("hide", sum > 2);
});
</script>
This seems really overcomplicated.
const checkedCount = this.querySelectorAll(".choice:checked").length
if (checkedCount > 2 || this.querySelector('input#cbg').checked) {
//output B
} else {
//output A
}
querySelectorAll returns a list of all elements that match the selector (i. e. all checked inputs) and querySelector just one element. # is selector syntax for element ids.

how to change values in a table cell with a slider in HTML

I have a table with data in it in HTML and I want to change the data in each cell by adding the value from a slider when it's used by a user. i wanna take the numeric value displayed from the slider and add/subtract to the numeric values of the table rows. So far i have the table and the slider, but i have no idea how to add/subtract the value i get from the slider to the data already in the table.
function show_value2(x){
document.getElementById("slider_value2").innerHTML=x;
}
<body onload="main()">
<div class="slidecontainer">
Орбитална обикола:<span id="slider_value2" style="color:red;font-weight:bold;"></span><br>
<input type="range" min="-50" max="50" step="10" name="slide" value="0" onchange="show_value2(this.value)">
</div>
<table border = "1">
<tr>
<th>Планета </th>
<th>Орбитален обикколка (AU) </th>
<th>Средна температура на повърхността(C<sup>o</sup>) </th>
<th>Орбитален период (дни) </th>
</tr>
<tr>
<td>Меркурий</td>
<td>2,406</td>
<td>166,85</td>
<td>87</td>
<tr/>
<tr>
<td>Венера</td>
<td>4,545</td>
<td>463,85</td>
<td>244</td>
</tr>
<tr>
<td>Земя</td>
<td>6,283</td>
<td>13,85</td>
<td>365</td>
</tr>
<tr>
<td>Марс</td>
<td>9,553</td>
<td>-63,15</td>
<td>686</td>
</tr>
<tr>
<td>Юпитер</td>
<td>32,675</td>
<td>-120,15</td>
<td>4335</td>
</tr>
<tr>
<td>Сатурн</td>
<td>59,879</td>
<td>-130,15</td>
<td>10,757</td>
</tr>
<tr>
<td>Уран</td>
<td>120,515</td>
<td>-205,15</td>
<td>30,708</td>
</tr>
<tr>
<td>Нептун</td>
<td>188,925</td>
<td>-220,15</td>
<td>60,224</td>
</tr>
</table>
</body>
The code below documents what needs to be done to update the cells with the slider value, but the one problem it doesn't solve that you'll have to work with is that the cells contain formatted non-US string values that don't convert to numbers using JavaScript's conversion techniques.
// Get references to elements you'll use more than once, only once.
let sliderValue = document.getElementById("slider_value2");
// Get all the rows in the table starting with row 2
let rows = document.querySelectorAll("table tr:nth-child(n+2)");
// Do your event binding in JavaScript, not with HTML event attributes like onchange
// and in this case the input event is better because it fires immediately as the
// element recieves input (you don't have to let go of the slider to see the updated
// value).
document.getElementById("slider").addEventListener("input", function(){
sliderValue.textContent = this.value;
// Loop over all the rows in the table
rows.forEach(function(row){
// Loop over all the cells in the row, starting with the second cell
row.querySelectorAll("td:nth-child(n+2)").forEach(function(cell){
// Update the cell's content with the old content (converted to a floating
// point number and the slider's current value (converted to a number).
cell.textContent = parseFloat(cell.textContent) + +sliderValue.textContent;
});
});
});
/* Avoid inline styles. Apply classes instead */
#slider_value2 {
color:red;
font-weight:bold;
}
<body>
<div class="slidecontainer">
Орбитална обикола:<span id="slider_value2">0</span><br>
<input type="range" min="-50" max="50" step="10" id="slider" value="0">
</div>
<table border = "1">
<tr>
<th>Планета </th>
<th>Орбитален обикколка (AU) </th>
<th>Средна температура на повърхността(C<sup>o</sup>) </th>
<th>Орбитален период (дни) </th>
</tr>
<tr>
<td>Меркурий</td>
<td>2,406</td>
<td>166,85</td>
<td>87</td>
<tr/>
<tr>
<td>Венера</td>
<td>4,545</td>
<td>463,85</td>
<td>244</td>
</tr>
<tr>
<td>Земя</td>
<td>6,283</td>
<td>13,85</td>
<td>365</td>
</tr>
<tr>
<td>Марс</td>
<td>9,553</td>
<td>-63,15</td>
<td>686</td>
</tr>
<tr>
<td>Юпитер</td>
<td>32,675</td>
<td>-120,15</td>
<td>4335</td>
</tr>
<tr>
<td>Сатурн</td>
<td>59,879</td>
<td>-130,15</td>
<td>10,757</td>
</tr>
<tr>
<td>Уран</td>
<td>120,515</td>
<td>-205,15</td>
<td>30,708</td>
</tr>
<tr>
<td>Нептун</td>
<td>188,925</td>
<td>-220,15</td>
<td>60,224</td>
</tr>
</table>
</body>
The following should do it:
function show_value2(x, prep=null){
let trs=[...document.querySelectorAll('table tr')];
trs.slice(1).forEach(tr=>[...tr.children].slice(1)
.forEach(td=>{
if (prep) td.dataset.val=+td.textContent.replace(',','.')
else td.textContent=(+td.dataset.val+x).toFixed(3)
})
)
}
show_value2(0,true);
<div class="slidecontainer">
Орбитална обикола:<span id="slider_value2" style="color:red;font-weight:bold;"></span><br>
<input type="range" min="-50" max="50" step="10" name="slide" value="0" oninput="show_value2(+this.value)">
</div>
<table border = "1">
<tr>
<th>Планета </th>
<th>Орбитален обикколка (AU) </th>
<th>Средна температура на повърхността(C<sup>o</sup>) </th>
<th>Орбитален период (дни) </th>
</tr>
<tr>
<td>Меркурий</td>
<td>2,406</td>
<td>166,85</td>
<td>87</td>
<tr/>
<tr>
<td>Венера</td>
<td>4,545</td>
<td>463,85</td>
<td>244</td>
</tr>
<tr>
<td>Земя</td>
<td>6,283</td>
<td>13,85</td>
<td>365</td>
</tr>
<tr>
<td>Марс</td>
<td>9,553</td>
<td>-63,15</td>
<td>686</td>
</tr>
<tr>
<td>Юпитер</td>
<td>32,675</td>
<td>-120,15</td>
<td>4335</td>
</tr>
<tr>
<td>Сатурн</td>
<td>59,879</td>
<td>-130,15</td>
<td>10,757</td>
</tr>
<tr>
<td>Уран</td>
<td>120,515</td>
<td>-205,15</td>
<td>30,708</td>
</tr>
<tr>
<td>Нептун</td>
<td>188,925</td>
<td>-220,15</td>
<td>60,224</td>
</tr>
</table>
The function show_value2() can be called in two different ways:
called as show_value2(0,true) will set up the table by copying the current conts of each numeric table cell into the dataset property
called as show_value2(x) will add the numeric value x to the dataset.val property of each cell and put it into the cell again.

Wrong Result Calculate value with checkbox use Jquery

Now im doing some Calculate Checkbox Value Using JQuery and PHP code. The mechanism is, when User checked the checkbox, it will sum the price. I implemented a formula for JQuery but the result it not correct. here is my code
JQUERY
<script>
$(function() {
$('.dealprice').on('input', function(){
const getItemPrice = $(this).closest("tr").find('input[name=itemprice]').val();
var eachPrice = 0;
$('.dealprice:checkbox:checked').each(function(){
eachPrice += isNaN(parseInt(getItemPrice)) ? 0 : parseInt(getItemPrice);
});
$("#totalDeal").text(eachPrice.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
});
});
</script>
for more detail. i made a sample on this site https://repl.it/#ferdinandgush/Sum-Calculate-checkbox just click "run" button and you can able to test it. i need to display correct calculate following that table format
Please help.
You just have to define getItemPrice inside the loop, otherwise you are calculating it only once for the item that was clicked, instead of doing it for every item.
$(function() {
$('.dealprice').on('input', function(){
var eachPrice = 0;
$('.dealprice:checkbox:checked').each(function(){
const getItemPrice = $(this).closest("tr").find('input[name=itemprice]').val();
eachPrice += isNaN(parseInt(getItemPrice)) ? 0 : parseInt(getItemPrice);
});
$("#totalDeal").text(eachPrice.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
});
});
<table class="tg">
<thead>
<tr>
<th class="tg-qh0q">Item</th>
<th class="tg-qh0q">Price</th>
<th class="tg-qh0q">Deal</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-0lax">Book</td>
<td class="tg-0lax">$ 10 <input type="hidden" name="itemprice" value="10"></td>
<td class="tg-0lax"><input type="checkbox" class="dealprice" name="deal[12][0]"></td>
</tr>
<tr>
<td class="tg-0lax">Pencil</td>
<td class="tg-0lax">$ 5 <input type="hidden" name="itemprice" value="5"></td>
<td class="tg-0lax"><input type="checkbox" class="dealprice" name="deal[12][1]"></td>
</tr>
<tr>
<td class="tg-0lax">Pen</td>
<td class="tg-0lax">$ 8 <input type="hidden" name="itemprice" value="8"></td>
<td class="tg-0lax"><input type="checkbox" class="dealprice" name="deal[12][2]"></td>
</tr>
<tr>
<td class="tg-amwm" colspan="2">Total</td>
<td class="tg-0lax"><span id="totalDeal">0</span></td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You have to put the getItemPrice inside of the function of where you get its checked. Please check the following code:
$(function() {
$('.dealprice').on('input', function(){
var eachPrice = 0;
$('.dealprice:checkbox:checked').each(function(){
const getItemPrice = $(this).closest("tr").find('input[name=itemprice]').val();
eachPrice += isNaN(parseInt(getItemPrice)) ? 0 : parseInt(getItemPrice);
});
$("#totalDeal").text(eachPrice.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'));
});
});
Also check this repl https://repl.it/repls/LavenderAgonizingRoot

Dynamic table if checkbox is unchekd empty() the td cell with JS

I have dynamic table that in one td passes php vales of prices and on end of the table is sum of those prices. There is also a checkbox in every row default checked. I need to empty the content of row where checkbox is unchecked so it removes that price value out of sum calculation.
Question, will that even remove that value? I know setting the td field to hide does not.
Value cell:
<td style="width:10%" class="rowDataSd" id="value">
<?php echo
str_replace(array(".", ",",), array("", "."), $row['rad_iznos']);
?>
</td>
Checkbox cell:
<td style="width:3%">
<input class="w3-check" type="checkbox" checked="checked" id="remove" name="uvrsti" value="<?php echo $row['rad_id']?>">
</td>
I tried with this but nothing happens with no errors:
$(document).ready(function(){
if($("#remove").is(':checked')) {
$("#value").show();
} else {
$("#value").empty();
}
});
I can pass the unique values into each checkbox and value element into id's like:
id="<?php echo $row['rad_id']?>"
. So they tie each other but don't know how to say in JS to empty those elements.
I was also thinking something along the lines of, if on some row checkbox is unchecked empty closest td with id="value". My guess is that would be best solution but I don't know how to write it.
Or even if checkbox is unchecked remove css class .rowDataSd to closest td with id="vale" based on whom calculation is made.
Sum script:
var totals=[0,0,0];
$(document).ready(function(){
var $dataRows=$("#sum_table tr:not('.totalColumn, .titlerow')");
$dataRows.each(function() {
$(this).find('.rowDataSd').each(function(i){
totals[i]+=parseFloat( $(this).html());
});
});
$("#sum_table td.totalCol").each(function(i){
$(this).html('<span style="font-weight: bold;text-shadow: 0.5px 0 #888888;">'+totals[i].toFixed(2)+' kn</span>');
});
});
As seen on picture need to remove row out of calculation if checkbox is unchecked. Keep in mind I dont want to delete to row, just remove it our of calculation.
Any help with how to approach this is appreciated.
Here is a basic example.
$(function() {
function getPrice(row) {
var txt = $(".price", row).text().slice(1);
var p = parseFloat(txt);
return p;
}
function calcSum(t) {
var result = 0.00;
$("tbody tr", t).each(function(i, r) {
if ($("input", r).is(":checked")) {
result += getPrice(r);
}
});
return result;
}
function updateSum(tbl) {
var t = calcSum(tbl);
$("tfoot .total.price", tbl).html("$" + t.toFixed(2));
}
updateSum($("#price-list"));
$("#price-list input").change(function() {
updateSum($("#price-list"));
});
});
#price-list {
width: 240px;
}
#price-list thead th {
width: 33%;
border-bottom: 1px solid #ccc;
}
#price-list tfoot td {
border-top: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="price-list">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td class="item name">Item 1</td>
<td class="item price">$3.00</td>
<td><input type="checkbox" checked /></td>
</tr>
<tr>
<td class="item name">Item 2</td>
<td class="item price">$4.00</td>
<td><input type="checkbox" checked /></td>
</tr>
<tr>
<td class="item name">Item 3</td>
<td class="item price">$5.00</td>
<td><input type="checkbox" checked /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Sum</td>
<td class="total price">$0.00</td>
<td> </td>
</tr>
</tfoot>
</table>
It all boils down to setting up an event handler for the checkboxes. The event handler should perform the following:
Track the checkbox change event for all checkboxes and the DOM ready event
Calculate the total of all rows with checkbox checked
Set the total to the total element
It call also perform any desired changes on the unchecked row .. not done in sample code below
THE CODE
$(function() {
$('.select').on('change', function() {
let total = $('.select:checked').map(function() {
return +$(this).parent().prev().text();
})
.get()
.reduce(function(sum, price) {
return sum + price;
});
$('#total').text( total );
})
.change();//trigger the change event on DOM ready
});
THE SNIPPET
$(function() {
$('.select').on('change', function() {
let total = $('.select:checked').map(function() {
return +$(this).parent().prev().text();
})
.get()
.reduce(function(sum, price) {
return sum + price;
});
$('#total').text( total );
})
.change();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>1000</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 2</td>
<td>1200</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 3</td>
<td>800</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 4</td>
<td>102000</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
</tbody>
</table>
<span>TOTAL</span><span id="total"></span>

Custom validation plugin fails with multiple table rows

Trying to self create a validation that compares Gross and Tare values in the table using jQuery validation plugin. Tare should always be smaller than Gross.
Here is the JS code:
$.validator.addMethod('lessThan', function (value, element, param) {
if (this.optional(element)) return true;
var i = parseInt(value);
var j = parseInt($(param).val());
return i <= j;
}, "Tare must less than Gross");
$('#myForm').validate({rules: {tare: {lessThan: ".gross"}}});
And my HTML:
<form id="myForm">
<table id="lineItemTable">
<thead>
<th>
<tr>
<td>Gross</td>
<td>Tare</td>
</tr>
</th>
</thead>
<tbody>
<tr>
<td><input type="text" name='gross' class="gross"/></td>
<td><input type="text" name='tare' class="tare"/></td>
</tr>
<tr>
<td><input type="text" name='gross' class="gross"/></td>
<td><input type="text" name='tare' class="tare"/></td>
</tr>
</tbody>
</table>
</form>
This code works fine when only have one row involved.
When comes two table rows, it compares the 2nd row tare value with the 1st row gross value. Apparently I want it to compare 2nd row tare value with 2nd row gross value. Also for some reason the error message shows up at the 1st row.
Here is one screen shot:
Please advise how do I change my code to make it working properly.
And here is the CDN that I am using:
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
Looking for $('.gross').val() will always retrieve the value of the first matched element (in the whole document).
Instead, look only in the row containing the element being validated:
var j = parseInt($(element).closest('tr').find(param).val());
$.validator.addMethod('lessThan', function(value, element, param) {
console.log(element);
if (this.optional(element)) return true;
var i = parseInt(value);
var j = parseInt($(element).closest('tr').find(param).val());
return i <= j;
}, "Tare must less than Gross");
$('#myForm').validate({
rules: {
tare: {
lessThan: ".gross"
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="myForm">
<table id="lineItemTable">
<thead>
<th>
<tr>
<td>Gross</td>
<td>Tare</td>
</tr>
</th>
</thead>
<tbody>
<tr>
<td>
<input type="text" name='gross' class="gross" />
</td>
<td>
<input type="text" name='tare' class="tare" />
</td>
</tr>
<tr>
<td>
<input type="text" name='gross' class="gross" />
</td>
<td>
<input type="text" name='tare' class="tare" />
</td>
</tr>
</tbody>
</table>
</form>

Categories

Resources