JS (jQuery): Randomly trigger-click 2 table rows - javascript

Given this HTML:
<div id="TABLE1" class="tabs">
<table>
<tbody datasrc="Music">
<tr id="randomid">lorem</tr>
<tr id="foo">lorem</tr>
<tr id="abcde">lorem</tr>
<tr id="fghijk">lorem</tr>
<tr id="lmnop">lorem</tr>
<tr id="qwerty">lorem</tr>
</tbody>
</table>
</div>
<div id="TABLE_2" class="tabs">
<table>
<tbody datasrc="Music">
<tr id="random5">lorem</tr>
<tr id="farhaf">lorem</tr>
<tr id="haerf">lorem</tr>
<tr id="hagasdg">lorem</tr>
<tr id="hrfafh">lorem</tr>
<tr id="qwerty">lorem</tr>
</tbody>
</table>
</div>
<div id="LASTTABLE" class="tabs">
<table>
<tbody datasrc="Music">
<tr id="rtefdgag">lorem</tr>
<tr id="wrtjfd">lorem</tr>
<tr id="reaht">lorem</tr>
<tr id="aggag">lorem</tr>
<tr id="rthhre">lorem</tr>
<tr id="argarg">lorem</tr>
</tbody>
</table>
</div>
I am trying to trigger 2 <tr>'s from each table randomly. I cant even thing of the way doing this.
Currently for my test I use:
$("#button").on('click', function () {
$('#randomid').trigger('click')
})
but this trigger's only the first row from the first table.
So how can I:
When I press #button,
Get 2 random row's from each table, Trigger
click each row every 10 ms (so they have an order).
About the app:
It is a music player website. Each table has different style of music. Rock, Alternative, Jazz etc. There is a button 'randomly select music'). That button, will trigger 2 random tr's from each table so you end up with 2 jazz songs, 2 rock songs etc to be added to the playlist. The table looks something like this: http://dribbble.com/system/users/31916/screenshots/167289/k-dribble.png?1309036379 but those checkboxes are not actual checkboxes but images which change position on click to look and feel better than a checkbox and still act the same as a checkbox.
The user can trigger the 'checkbox' or choose a song by clicking anywhere on the row (logical), so the back-end is developed in a way to capture clicks anywhere on a row and not specificly the checkbox (thus I am not choosing to trigger those). I dont think there is a better solution that just trigger click randomly 2 row from each tble.
Support for IE8+.

See my version below,
DEMO
Note: Below code has some demo code and redundant vars which you can clean up, but I am leaving it there as to make the code look clear and self explanatory.
$(function() {
var $tables = $('table'); //gets the tree tables
var mQ = []; //music queue
var timer = null;
$('button').click(function () {
$('#result').html(''); //demo code
var t = 0, $tr;
var t1 = [];
$tables.each(function () {
$tr = $(this).find('tr');
t1[0] = Math.floor(Math.random()*$tr.length);
t1[1] = Math.floor(Math.random()*$tr.length);
while (t1[0] == t1[1]) { //To make sure not same row is selected
t1[1] = Math.floor(Math.random()*$tr.length);
}
mQ.push($tr.get(t1[0]));
mQ.push($tr.get(t1[1]));
});
timer = setInterval(function () {//Create timer to trigger click every 10ms
if (mQ.length == 0) {
clearInterval(timer);
return false;
}
$(mQ.shift()).click().addClass('selected');
}, 10);
});
$('tr').click(function () {
//do your magic
$('#result').append(this.id + '<br />');
});
});

I would first suggest that you do this a different way, but if you're set on triggering the click events here's the general idea.
$(".tab").each(function(){
var count = $(this).children(tr).length;
var r1 = Math.floor(Math.random()*count); //Get a random number less than the total count of rows
$(this).children('tr').eq(r1).trigger('click');//retrieve the nth (r1) item in the list and fire it's trigger event
});

Updated with new code on Fiddle too
Maybe more like this? ...
$(function() {
$("button").click(function(e) {
$(".selected").removeClass("selected");
$("table").each(function(i) {
var irand = {
a: Math.floor((Math.random()*($(this).find("tr").length)-1)+1),
b: undefined
};
while (irand.b == irand.a || irand.b == undefined) {
irand.b = Math.floor((Math.random()*($(this).find("tr").length)-1)+1);
};
console.log($(this).find("tr").filter(function(i) { return i == irand.a || i == irand.b }).addClass("selected"));
});
});
});​
See working fiddle here ...

Related

Is there way to parse tr returned by 'this'?

Each row of my table has a button at the end of the row, which has an addEventListener like this,
button.addEventListener ("click", function() {
deleteSummary(this);
});
function deleteSummary(oButton)
{
console.log(oButton.parentNode.parentNode.innerHTML)
}
the console.log shows like this,
<td>966</td><td>TypeA</td><td>1234</td><td>10,000</td><td>9,861</td><td>139</td><td>2021-01-02</td><td>3</td><td>7</td><td>8</td><td>7</td><td>89</td><td>9</td><td>8</td><td>7</td><td>1</td><td><button>delete</button></td>
But I have no idea how to parse(?) it.
I always found answers you use document.getElementById() when googling.
Thanks
You should not aim to parse HTML. You have access to the DOM, so stick with that. You already found the tr element successfully, and then you can for instance use its cells property to get access to all the td elements, and you could map that list of cells to their text content. That way you get a standard array with all the cell texts of that particular row.
let buttons = document.querySelectorAll("td>button");
for (let button of buttons) {
// Your code:
button.addEventListener ("click", function() {
deleteSummary(this);
});
}
function deleteSummary(oButton) {
let tr = oButton.parentNode.parentNode;
let data = Array.from(tr.cells, cell => cell.textContent);
data.pop(); // Optional: get rid of the column with the delete button
console.log(data);
}
<table>
<tr>
<td>966</td>
<td>TypeA</td>
<td>1234</td>
<td>10,000</td>
<td>2021-01-02</td>
<td><button>delete</button></td>
</tr>
<tr>
<td>123</td>
<td>TypeB</td>
<td>9988</td>
<td>29,999</td>
<td>2020-09-20</td>
<td><button>delete</button></td>
</tr>
</table>

How to make a Div scroll to the bottom

i have a textbox and a button. After pressing the add button to the table inside a div.
I want the div to scroll to the bottom of the page when max-height:100px; exceededoverflow-y:auto; addbarcode(); method is a ajax post which will call a jquery dataTable methodto populate data on the server side.
try 1
var element = document.getElementById("divcontent");
element.scrollIntoView(false);
try 2
var element = document.getElementById("divcontent");
$('#divcontent').scrollTo(element.get(0).scrollHeight);
try 3
var objDiv = document.getElementById("divcontent");
objDiv.scrollTop = objDiv.scrollHeight;
above attempts all doesnt work.
edit
<div class="row" id="divcontent" style="max-height:100px; overflow-y:auto">
<div class="col-md-12 col-sm-12">
<table class="table table-striped table-responsive" id="codelist">
<thead>
<tr>
<th>
SN
</th>
<th>
Serial Number
</th>
</tr>
</thead>
</table>
</div>
Javascript
$(document).ready(function () {
$("#scanner").on('keyup paste', function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) { //Enter keycode
var artno = $(this).val();
if (artno.length == 32 && ) {
addbarcode();
$(this).val("");
} else {
$(this).val("");
}
var element = document.getElementById("divcontent");
element.scrollIntoView(false);
}
});
})
final working code
added animate to allow smooth scrolling . also added timer as ajax code run faster than html render .so setting a little delay allows the javascript to capture full height.
function divscrolldown() {
setTimeout(function () {
$('#divcontent').animate({
scrollTop: $("#divcontent").offset().top
}, 500);
}, 200);
element.scrollIntoView(false);
If false, the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor.
MDN: Element.scrollIntoView()
This worked for me:
$('#scroll').scrollTop(1000000);
There's more answers here: Scroll to bottom of div?

Hiding container if all children are hidden in Angular

I am creating a number of tables dynamically, which all have a number of rows that are also created dynamically using Angular.
My goal is to have each table hidden if there are no visible rows in that table's tbody.
<table ng-repeat="package in listOfPackages" ng-if="this.getElementsByTagName('tbody')[0].childNodes.length > 0 ">
<tbody>
<tr ng-repeat="thing in package.things" ng-if="thing.status === 'interesting'">
<td>{{thing.someInfo}}</td>
<td>{{thing.someOtherInfo}}</td>
</tr>
</tbody>
</table>
The line ng-if="this.getElementsByTagName('tbody')[0].childNodes.length > 0" seems to be my problem - I do not know the proper way to find an element's own children, and check how many it has visible.
Is there any possible way to do this in angular?
create a function in your controller something like
$scope.showPackageTable = function (package) {
var toShow = false;
for (var thing in package.things) {
if (thing.status === 'interesting') { toShow = true; }
}
return toShow;
}
then you can use that in your html ng-if="showPackageTable(package)"

Keep rows with certain values always at the bottom while sorting in jquery tablesorter plugin

I'm using JQuery Table sorter plugin(http://tablesorter.com/docs/) in my application it works great but I would like to exclude certain rows which has N/A for the clicked column while sorting and keep them always at the end.
As far as i have checked if we put elements in tfoot it will always remains at the bottom. But i wanted to display those rows initially only when sorting happens I would like to move them at the end.
Below is my HTML
<table id="myTable" class="tablesorter">
<thead>
<tr>
<th>Code</th><th>Name</th><th>Count</th><th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>1011</td><td>Cheif Executives</td><td>2385</td><td>20%</td>
</tr>
<tr>
<td>1012</td><td>General and Operations Manager</td><td>2986</td><td>N/A</td>
</tr>
<tr>
<td>1013</td><td>Advertising Promo Managers</td><td>3412</td><td>30%</td>
</tr>
<tr>
<td>1014</td><td>Marketing Managers</td><td>2154</td><td>5%</td>
</tr>
</tbody>
</table>
Javascript
In JavaScript we can specify a text extraction method for table sorter. While sorting higher to lower I'm trying to make the N/A as ' ' which has lower ASCII value than other symbols so the row will be in lower end of the table. Similarly lower to higher sorting i need to replace N/A with ~ symbol to give N/A a higher value to make to appear at the end.
Below is the code snippet I'm trying
$(document).ready(function () {
$("#myTable").tablesorter({
textExtraction: function (node) {
var s = '';
var hdrs = $("#myTable th");
var direction = '';
hdrs.each(function (index) {
if ($(this).hasClass('headerSortDown')) {
direction = 'down';
return;
}
else if ($(this).hasClass('headerSortUp')) {
direction = 'up';
return;
}
});
if (direction === 'down')
s = $(node).text().replace('N/A', ' ');
else if (direction === 'up')
s = $(node).text().replace('N/A', '~');
return s;
},
cssAsc: 'headerSortUp',
cssDesc: 'headerSortDown'
});
});
But it seems like the css classes are not getting added by default so the result is not as expected. My expected Result during both sort is the row while has code 1012 should always appear below the table.
Note i cant add any static classes to the table markup for the N/A values since it is from the table is generated dynamically
Thanks in advance
I'm glad that I fixed this issue by myself and I'm happy to share this to folks who might need this in future. There are two things to this issue
Tell table sorter to consider the N/A as empty. this can be done using the textExtraction(method used to extract values from the cells for sorting) method that table sorter provides
Ask tableSorter to keep all the empty values to the bottom using emptyTo attribute
Below is the code
$(document).ready(function () {
$("#myTable").tablesorter({
textExtraction: function (node) {
var txt = $(node).text();
txt = txt.replace('N/A', '');
return txt;
},
emptyTo: 'bottom'
});
});

How to renumber remaining table rows after .hide()

The Javascript increments each visible number in these dynamically generated rows of a static table.
The jQuery dutifully hides each row when clicked, but, of course, the numbers don't change. How can I use jQuery to re-number the rows when the visitor is done removing the unwanted lines? I want the user to click 'renumber' to renumber the remaining rows correctly. What I have didn't work :-)
Help is deeply appreciated.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
var keepTrack = 1;
</script>
<table>
<tr><td colspan="2" id="renumber">renumber</td></tr>
<tr id="sWH1">
<td>
<script>
document.write(keepTrack);keepTrack++;
</script></td>
<td>someWordsHere</td></tr>
<script>
$(document).ready(function() {
$("#sWH1").click(function() {
$("#sWH1").hide(100);});
});</script>
<tr id="sWH2">
<td>
<script>
document.write(keepTrack);keepTrack++;
</script></td>
<td>someWordsHere</td></tr>
<script>
$(document).ready(function() {
$("#sWH2").click(function() {
$("#sWH2").hide(100);});
});</script>
<tr id="sWH3">
<td>
<script>
document.write(keepTrack);keepTrack++;
</script></td>
<td>someWordsHere</td></tr>
<script>
$(document).ready(function() {
$("#sWH3").click(function() {
$("#sWH3").hide(100);});
});</script>
</table>
<script language="JavaScript" type="text/JavaScript">
$(document).ready(function() {
$("#renumber").click(function() {
'magically renumber the remaining table rows'
});
});
</script>
The straightforward answer
To renumber the rows you can use the each() method that allows you to iterate over a set of elements (the rows in this case) and provides an i enumerator parameter.
A general example:
$(some-tr-selector).each(function(i) {
$(this).children(some-td-selector).text(i+1);
});
Now to do this, you'll need to define better selectors. The problem with your current code is that your selectors are too specific. This prevents you from creating general event handlers, instead of creating a click handler for each row.
How to improve your code
Consider setting a class for the relevant numbered rows. This will allow you to create a single click handler for all rows and make the relevant rows much easier to select when renumbering.
For example:
HTML
<table>
<tr><td colspan="2" id="renumber">renumber</td></tr>
<tr class="numbered_row">
<td class="row_number"></td>
<td>someWordsHere</td>
</tr>
<tr class="numbered_row">
<td class="row_number"></td>
<td>someWordsHere</td>
</tr>
<tr class="numbered_row">
<td class="row_number"></td>
<td>someWordsHere</td>
</tr>
...
</table>
Javascript
$(document).ready(function() {
// Number all rows onload
$('table tr.numbered_row').each(function(i) {
$(this).children('.row_number').text(i+1);
});
// Row click handler
$('table tr.numbered_row').on('click', function() {
$(this).hide(100);
});
// Renumber click handler
$('#renumber').on('click', function() {
$('table tr.numbered_row:visible').each(function(i) { // Iterate over all _visible_ rows
$(this).children('.row_number').text(i+1);
});
});
});
Note how by adding two classes numbered_row and row_number we are able to do everything efficiently in one block of code: initial numbering of the rows, a single click handler to hide them and the renumbering action.
An even more general approach
If you wanted, you could make this even more general and efficient, by chaining the each() and on() methods as well as handling the renumbering within the on() each time a row is hidden.
For example:
$(document).ready(function() {
// Number all rows onload
$('table tr.numbered_row').each(function(i) {
$(this).children('.row_number').text(i+1);
// Row click handler
}).on('click', function() {
// Hide current row
$(this).hide(100);
// Renumber visible rows
$('table tr.numbered_row:visible').each(function(i) { // Iterate over all _visible_ rows
$(this).children('.row_number').text(i+1);
});
});
});
Here is another solution:
http://jsbin.com/ufahac/1/edit
This is your code with few changes: the table has an id=myTable
and 'magically renumber the remaining table rows' has been replaced with
$('#myTable tr[id]:visible').each(function(i){
$(this).find('td:first').text(i+1);
})

Categories

Resources