I asked a question yesterday and that got me going on the right path, but I'm absolutely stuck again.
Outline:
I have 3 tables;
table 1 - expected data (#expected)
table 2 - expected confirmed data (#scannedExp)
table 3 - unexpected confirmed data (#scannedUnExp)
So for a example..
if I was to enter "6666" in the input box
it would reduce qty in the "#expected" table by 1 but create a column in the "#scannedExp" table with qty of 1 (with the i.e desc, cage grabbed from the #expected table).
if we was to enter '6666' this time it would delete the "#expected" row, but increase the table "#scannedExp"
if again we was to enter '6666' this time it would add a row to "#scannedUnExp" with just the code and qty (dont need the desc or cage)
and if we was to enter say "1234" it would add a row in "#scannedUnExp"
for some reason my codes not working in Jsfiddle as it works to some extent in my browser.
http://jsfiddle.net/j3psmmo3/
<body>
<input type="text" style="width: 200px" id="code" name="code" />
<input id = "btnSubmit" type="submit" value="Submit"/>
<P>Scanned Expected</P>
<table id = "scannedExp" > <thead>
<tr>
<th>Code</th>
<th>Desc</th>
<th>Qty</th>
<th>Cage</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<P>Scanned Un Expected</P>
<table id = "scannedUnExp" > <thead>
<tr>
<th>Code</th>
<th>Qty</th>
<th>Cage</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<P>Data Expected</P>
<table id = "expected"> <thead>
<tr>
<th>Code</th>
<th>Desc</th>
<th>Qty</th>
<th>Cage</th>
</tr>
</thead>
<tbody>
<tr id="4444" >
<td>4444</td>
<th>Car Door</th>
<td>3</td>
<th>S2222</th>
</tr>
<tr id="5555" >
<td>5555</td>
<th>door handel</th>
<td>1</td>
<th>S2222</th>
</tr>
<tr id="6666" >
<td>6666</td>
<th>headlight</th>
<td>2</td>
<th>S2222</th>
</tr>
<tr id="7777">
<td>7777</td>
<th>seat</th>
<td>5</td>
<th>S2222</th>
</tr>
</tbody>
</table>
</body>
my javascript
$(window).load(function(){
$("#btnSubmit").on("click", function(){
numRows = $("#expected tr").length; //loop thought expected data
for(var i=1 ; i<numRows ; i++){
var code = $("#expected tr:nth-child(" + i + ") td:nth-child(1)").html();
var desc = $("#expected tr:nth-child(" + i + ") td:nth-child(2)").html();
var qty = $("#expected tr:nth-child(" + i + ") td:nth-child(3)").html();
var cage = $("#expected tr:nth-child(" + i + ") td:nth-child(4)").html();
// if code is in expected data -1 from qty col
if(code == $("#code").val()){
$("#expected tr:nth-child(" + i + ") td:nth-child(3)").html(parseInt(qty) - 1);
//delete if last one in expected table
if(qty ==1 ){$("#" + code).remove();}
// loop thought scanned expected table
numRowsB = $("#scannedExp tr").length;
for(var ib=1 ; ib<numRows ; ib++){
var codeExp = $("#scannedExp tr:nth-child(" + ib + ") td:nth-child(1)").html();
var qtyExp = $("#scannedExp tr:nth-child(" + ib + ") td:nth-child(3)").html();
// if in scannedExp add qty by one
if(codeExp == $("#code").val()){
$("#scannedExp tr:nth-child(" + ib + ") td:nth-child(3)").html(parseInt(qtyExp) + 1);
return true;
}
else{ //if not found in expected table add row to scannedExp
$("#scannedExp tbody").append("<tr><td>" + $("#code").val() + "</td><td>" + desc + "</td><td>1</td><td>" + cage + "</td></tr>");
return true;
}
}
return true;
}
else{
alert("not in expected");
}
}})
});
I noticed from your fiddle that the button does not trigger the click event.
Your code had 3 problems that I have fixed and then the code worked fine.
First
I think you meant to use $(document).ready() instead of $(window).load().
Since you want to listen to events, it is better to wait until all DOM elements are loaded and the document is ready before attempting to do anything else.
But since the event trigger I am about to tell you about in my second point does not depend on the document being ready or not, it is not necessary. So I removed it.
Second:
I modified the code to use $(document).on('click','selector',function(){}); instead of $(element).on('click',function(){});
//Use this event
$(document).on('click','#btnSubmit',function(){
...
...
});
//Instead of using this
$("#btnSubmit").on("click", function(){
...
...
});
the .on() I used will work for DOM controls that have been loaded from the page, or ones that you added dynamically. That's why I rely on it all the time.
Third
You forgot a semi-colon at the last line of your code...
...
...
else{
alert("not in expected");
}
}}) // <-- This line has no semi-colon
});
You may check the modified code on this fiddle
The code works fine after the modification.
Related
I'm making a web-based POS. I have two table, one is for displaying the search products using jquery and when I clicked the product it will transfer to the second table. So my second table is dynamically dependent of what the user clicked. This is my table look like with css.
I want to get the total price of Sub.Total column automatically and display to the bottom specially in the Total p tag.
This is my html table code.
<table id="table2">
<thead>
<tr>
<th>Barcode</th>
<th>Description</th>
<th>Price</th>
<th>Unit</th>
<th>Qty</th>
<th>Sub.Total</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tableData">
</tbody>
</table>
<table id="table1">
<thead>
<tr>
<td>Barcode</td>
<td>Product Name</td>
<td>Price</td>
<td>Unit</td>
<td>Stocks</td>
</tr>
</thead>
<tbody id="products">
</tbody>
</table>
This is my query from search box.
$show = "SELECT * FROM products WHERE product_name LIKE '$name%' ";
$query = mysqli_query($db,$show);
if(mysqli_num_rows($query)>0){
while($row = mysqli_fetch_array($query)){
echo "<tr class='js-add' data-barcode=".$row['id']." data-product=".$row['product_name']." data-price=".$row['sell_price']." data-unt=".$row['unit']."><td>".$row['id']."</td><td>".$row['product_name']."</td>";
echo "<td>₱".$row['sell_price']."</td>";
echo "<td>".$row['unit']."</td>";
echo "<td>".$row['quantity']."</td>";
}
}
This is for displaying the cliked rows from searched products.
$('body').on('click','.js-add',function(){
var target = $(this);
var product = target.attr('data-product');
var price = target.attr('data-price');
var barcode = target.attr('data-barcode');
var unit = target.attr('data-unt');
swal("Enter number of item to buy:", {
content: "input",
})
.then((value) => {
if (value == "") {
swal("Error","Entered none!","error");
}else{
var qtynum = parseInt(value);
if (isNaN(qtynum)){
swal("Error","Please input a valid number!","error");
}else{
var total = value * price;
$('#tableData').append("<tr><td>"+barcode+"</td
<td>"+product+"</td>
<td>"+accounting.formatMoney(price,{symbol:"₱",format: "%s %v"})+"</td><td>"+unit+"</td>
<td>"+value+"</td>
<td class='totalPrice'>"+accounting.formatMoney(total,{symbol:"₱",format: "%s %v"})+"</td>
<td><button class='btn btn-danger' type='button' id='delete-row'>×</button><tr>");
}
}
});
});
I'd tried this code but it return NaN.
$(document).ready(function(){
var TotalValue = 0;
$("#tableData tr").each(function(){
TotalValue += parseFloat($(this).find('.totalPrice').text().replace(/,/g, "₱"));
});
alert(TotalValue);
});
I'd tried modifying the code but I cant get the job done. Hope someone will help about this one. Thanks in advance.
Edit: Updated answer.
Based off what you tried here would be a working solution using your logic.
$(document).ready(function(){
var TotalValue = 0;
var TotalPriceArr = $('.totalPrice').get()
$(TotalPriceArr).each(function(){
TotalValue +=parseInt($(this).text().replace('₱', ''))
});
alert(TotalValue);
});
I am wanting to concatenate strings from 2 separate elements and have them stored in a variable.
Currently my code is setting the variable equal to:
"Daily: 1070300, Weekly: 1070300, Monthly: 1070300"
My goal is to make the variable in the console equal to:
"Daily: 10, Weekly: 70, Monthly: 300"
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function() {
str += $(this).text() + ": " + $(this).parents().siblings('tr').find('.value').text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
Thank you for your help all!
Each time through the key loop, you're grabbing the content of all three value cells (since $(this).parents().siblings('tr').find('.value') matches all three). There are many ways to fix this but one easy one I see is to use the index argument on the inner loop to select the value cell corresponding to the current key (using jQuery's eq function):
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function(index) {
str += $(this).text() + ": " + $(this).parents().siblings('tr').find('.value').eq(index).text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
The code is very inefficient when you keep looking up stuff in the loop. So fixing it to read the index would work, it just causes the code to do more work than needed.
How can it be improved. Look up the two rows and one loop using the indexes.
var keys = $("table .key") //select the keys
var values = $("table .value") //select the values
var items = [] // place to store the pairs
keys.each(function(index, elem){ //loop over the keys
items.push(elem.textContent + " : " + values[index].textContent) // read the text and use the index to get the value
})
console.log(items.join(", ")) // build your final string by joing the array together
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
</table>
Collect the .key and .value classes into a NodeList convert the NodeList into arrays. Then merge the 2 arrays into key/value pairs stored in an Object Literal. Finally convert the object into a string so it can be displayed.
Demo
Details are commented in Demo
// Collect all th.key into a NodeList and turn it into an array
var keys = Array.from(document.querySelectorAll('.key'));
// As above with all td.value
var vals = Array.from(document.querySelectorAll('.value'));
function kvMerge(arr1, arr2) {
// Declare empty arrays and an object literal
var K = [];
var V = [];
var entries = {};
/* map the first array...
|| Extract text out of the arrays
|| Push text into a new array
|| Then assign each of the key/value pairs to the object
*/
arr1.map(function(n1, idx) {
var txt1 = n1.textContent;
var txt2 = arr2[idx].textContent;
K.push(txt1);
V.push(txt2);
entries[K[idx]] = V[idx];
});
return entries;
}
var result = kvMerge(keys, vals);
console.log(result);
// Reference the display area
var view = document.querySelector('.display');
// Change entries object into a string
var text = JSON.stringify(result);
// Clean up the text
var final = text.replace(/[{"}]{1,}/g, ``);
// Display the text
view.textContent = final
<table>
<tbody>
<tr>
<th class="key">Daily</th>
<th class="key">Weekly</th>
<th class="key">Monthly</th>
</tr>
<tr>
<td class="value">10</td>
<td class="value">70</td>
<td class="value">300</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class='display' colspan='3'></td>
</tr>
</tfoot>
</table>
You can also solve that using unique ids, like that:
$(document).ready(function() {
var str = '';
$('tbody > tr').each(function() {
$(this).find('.key').each(function() {
var index = $(this).attr('id').slice(3)
str += $(this).text() + ": " + $('#value'+index).text() + ", ";
})
});
console.log(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<th class="key" id="key1">Daily</th>
<th class="key" id="key2">Weekly</th>
<th class="key" id="key3">Monthly</th>
</tr>
<tr>
<td class="value" id="value1">10</td>
<td class="value" id="value2">70</td>
<td class="value" id="value3">300</td>
</tr>
</tbody>
</table>
I'm using a table to display items, an onclick event on cell[0] should output (alert) the data from cell[1] and cell[2].
I'm not sure with which approach I could access them.
Here is my code so far
http://jsfiddle.net/5uua7eyx/3/
Perhaps there is a way to use my variable input
HTML
<table id="items">
<tr>
<td onclick="ClickPic(this)">Picture0</td>
<td>Name0</td>
<td>Price0</td>
</tr>
<tr>
<td onclick="ClickPic(this)">Picture1</td>
<td>Name1</td>
<td>Price1</td>
</tr>
</table>
JS
function ClickPic(e) {
"use strict";
var input = e.target;
alert("Clicked!");
}
Thank you
You're passing this, which represents the element clicked, not the event object.
All you need to do is use the parameter to get the sibling .cells from the .parentNode, then use the elem.cellIndex to figure out the next indices:
function ClickPic(elem) {
"use strict";
var cells = elem.parentNode.cells;
var currIdx = elem.cellIndex;
alert(cells[currIdx + 1].textContent + " " + cells[currIdx + 2].textContent);
}
<table id="items">
<tr>
<td onclick="ClickPic(this)">Picture0</td>
<td>Name0</td>
<td>Price0</td>
</tr>
<tr>
<td onclick="ClickPic(this)">Picture1</td>
<td>Name1</td>
<td>Price1</td>
</tr>
</table>
x
If you know the index numbers will always be 1 and 2, then you can shorten it.
alert(cells[1].textContent + " " + cells[2].textContent);
you can change your js function to something like this
<script type="text/javascript">
function ClickPic(e) {
var s = '';
$(e).siblings().each(function() {
s = s + ',' + $(this).text()
});
alert(s);
}
I wish to construct a complete table using jQuery.
I try to learn or copycat from this question
Create table with jQuery - append
but no luck.
What I want to create is
<table>
<thead>
<tr>
<th>Problem 5</th>
<th>Problem 6</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
The jQuery code I created is
var $table = $('<table/>');
var $thead = $('<thead/>');
$thead.append('<tr>' + '<th>Problem 5</th>' + '<th>Problem 6</th>' + '</tr>';
$table.append(thead);
var $tbody = $('<tbody/>');
$tbody.append( '<tr><td>1</td><td>2</td></tr>' );
$table.append(tbody);
$('#GroupTable').append($table);
But it failed running.
Can anyone tell me why?
You are missing a right paren in your $thead declaration:
$thead.append('<tr>' + '<th>Problem 5</th>' + '<th>Problem 6</th>' + '</tr>');
^
and you aren't appending your variables correctly:
$table.append($thead);
^
$table.append($tbody);
^
Here's a working fiddle.
thead, tbody is undefined? $thead, $tbody?
$table.append(thead);
and
$table.append(tbody);
I am trying to sort a table - so when a user clicks on the table heading, it will sort in ascending/descending order. I've got it to the point where I can sort the table based on the column value. However, I have groupings of table rows (two rows per table body), and I want to sort the columns based on the values in the columns of the first row of each table body, but when it reorders the table, it want it to reorder the table bodies, not the table rows.
<table width="100%" id="my-tasks" class="gen-table">
<thead>
<tr>
<th class="sortable"><p>Name</p></th>
<th class="sortable"><p>Project</p></th>
<th class="sortable"><p>Priority</p></th>
<th class="sortable"><p>%</p></th>
</tr>
</thead>
<tbody>
<tr class="sortable-row" id="44">
<td><p>dfgdf</p></td><td><p>Test</p></td>
<td><p>1</p></td><td><p>0</p></td>
</tr>
<tr>
<td></td>
<td colspan="3"><p>asdfds</p></td>
</tr>
</tbody>
<tbody>
<tr class="sortable-row" id="43">
<td><p>a</p></td>
<td><p>Test</p></td>
<td><p>1</p></td>
<td><p>11</p></td>
</tr>
<tr>
<td></td>
<td colspan="3"><p>asdf</p></td>
</tr>
</tbody>
<tbody>
<tr class="sortable-row" id="40">
<td><p>Filter Tasks</p></td>
<td><p>Propel</p></td>
<td><p>10</p></td>
<td><p>10</p></td>
</tr>
<tr>
<td></td>
<td colspan="3"><p>Add a button to filter tasks.</p></td>
</tr>
</tbody>
</table>
With the following javascript:
jQuery(document).ready(function () {
jQuery('thead th').each(function(column) {
jQuery(this).addClass('sortable').click(function() {
var findSortKey = function($cell) {
return $cell.find('.sort-key').text().toUpperCase() + ' ' + $cell.text().toUpperCase();
};
var sortDirection = jQuery(this).is('.sorted-asc') ? -1 : 1;
var $rows = jQuery(this).parent().parent().parent().find('.sortable-row').get();
jQuery.each($rows, function(index, row) {
row.sortKey = findSortKey(jQuery(row).children('td').eq(column));
});
$rows.sort(function(a, b) {
if (a.sortKey < b.sortKey) return -sortDirection;
if (a.sortKey > b.sortKey) return sortDirection;
return 0;
});
jQuery.each($rows, function(index, row) {
jQuery('#propel-my-tasks').append(row);
row.sortKey = null;
});
jQuery('th').removeClass('sorted-asc sorted-desc');
var $sortHead = jQuery('th').filter(':nth-child(' + (column + 1) + ')');
sortDirection == 1 ? $sortHead.addClass('sorted-asc') : $sortHead.addClass('sorted-desc');
jQuery('td').removeClass('sorted').filter(':nth-child(' + (column + 1) + ')').addClass('sorted');
});
});
});
You need to sort the tbody elements, not the row elements. You said that yourself in your description of the problem, but your code actually sorts rows, not tbodies.
A secondary problem is that your sort treats everything as a string, which breaks when sorting 1-digit numeric strings ("2") against two-digit strings ("10").
To fix, replace this:
var $rows = jQuery(this).parent().parent().parent()
.find('.sortable-row').get();
jQuery.each($rows, function(index, row) {
row.sortKey = findSortKey(jQuery(row).children('td').eq(column));
});
with this:
var $tbodies = jQuery(this).parent().parent().parent()
.find('.sortable-row').parent().get();
jQuery.each($tbodies, function(index, tbody) {
var x = findSortKey(jQuery(tbody).find('tr > td').eq(column));
var z = ~~(x); // if integer, z == x
tbody.sortKey = (z == x) ? z : x;
});
And then replace $rows with $tbodies throughout your script, and row with tbody.
Example:
http://jsbin.com/oxuva5
I highly recommend the jQuery plugin http://tablesorter.com/ instead of rolling your own.
It's fully featured and well supported.