Selecting a random HTML element using JavaScript only - javascript

I'm trying to select an element from my HTML code, to then use it in JavaScript (it needs to be highlighted). The HTML consists of a table with 36 td's.
My code so far:
var box;
function getRandom()
{
return (Math.floor(Math.random()*37))
}
function highlight()
{
box = document.getElementById(getRandom());
box.style.backgroundColor = "yellow";
}
If anyone can give me any pointers, it'd be appreciated. I know it would be easy using jQuery, but I haven't begun learning that yet.
Edit: excerpt of the HTML code, this goes up to name="36".
<table id="reflexTable">
<tbody>
<tr>
<td name="1"></td>
<td name="2"></td>
<td name="3"></td>
<td name="4"></td>
<td name="5"></td>
<td name="6"></td>
</tr>

A nicer way that does not involve setting element ids:
function highlight() {
// get all TDs that are descendants of table#reflexTable:
var tds = document.getElementById('reflexTable').getElementsByTagName('td');
// get a random int between 0 (inclusive) and tds.length (exclusive)
var rand = Math.floor( Math.random() * tds.length );
// highlight td at that index
tds[rand].style.backgroundColor = "yellow";
}
The big advantage of this method is that you can add/remove as many TDs as you please without needing to edit your JS to generate a valid random number.

getElementById gets the element which has the matching id. Your table data cells don't have an id at all. They have a name, but HTML doesn't allow that.
Switch to id.
HTML 4 doesn't allow an id to start with a number. Prefix the id with a common string. Then:
document.getElementById("foo" + getRandom());

You're not setting the id attribute, you're setting the name attribute, change it to:
<td id="1"></td>
...etc

Several things:
You should declare the box variable inside the highlight function.
You have to convert that random number to a string.
Quentin mentioned something important--you should give each table element an id of something like "s0","s1","s2", etc...
Start the naming at 0 because your getRandom function will sometimes return it.
function highlight(){
var number;
number = getRandom().toString();
var box;
box = document.getElementById("s" + number);
box.style.backgroundColor = "yellow";
}

Related

jquery help to get element in array that contains certain class

jqTds =[
<td class=​"hidden-xs sorting_1">​text1​</td>​
<td class="​ ">​text2​</td>​
<td class=​" ">​text3​</td>​
<td class=​" ">​text4​</td>​
<td class=​" ">​​Edit​​</td>​
<td class=​" ">​​Delete​​</td>​]
How can I get all elements that has a "anchor" with class "edit-row" or "delete-row" and get all other that does not have it
// I am editing a script that uses DataTables.Js what I am trying to do is getting all elements from a table row into (var jqTds = $('>td:not(.hide_me)', nRow)) and now I want to include an input in all elements except the ones that has save-row class and edit-row class cos they are link to save/delete
thanks in advance
No idea why you have them in "an array", but if you run this while they are still in the DOM, use the :has pseudo selector:
var $tds = $('td:has(a:.edit-row,a:delete-row)');
var $otherTds = $('td').not($tds);
The first one reads. *find any td that has an anchor within it with class edit-row or an anchor within it with class delete-row".
The second one simply says, find all tds and exclude the first lot from the matches :)
You can use $.grep() to filter your array.
Using the function passed to $.grep() you can try and find your elements within the current <td>. If neither a.edit-row or a.delete-row are found return true, otherwise return false:
var filteredTds = $.grep(jqTds, function(td){
var $td = $(td);
return !$td.find('a.edit-row').length && !$td.find('a.delete-row').length;
});
JSFiddle
I was able to do like this:
for (var i = 0; i < editColumn.length; i++) {
if ($(editColumn[i]).find("a").hasClass("edit-row") == true) {
editColumn[i].innerHTML = '<a class="save-row" href="">Salvar</a>';
}
else if ($(editColumn[i]).find("a").hasClass("delete-row") == true) {
editColumn[i].innerHTML = '<a class="cancel-row" href="">cancelar</a>';
}

Fade out Columns in HTML-Table with jQuery: Why is .fadeTo() so slow?

I want to fade out all cells in a column of my HTML-table when I click on a button in the Header of this col. For that I run the following JavaScript:
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var colo = $(event.target).parent().attr("id"); // colNo is stored as Icons id
myDOMElement.find(".myTable").find("tr").find("#"+colo) // each tr has an id according to its colNumber
.each(function(index) {
$(this).fadeTo(0,0.2);
}
});
});
This works as desired but is relative slow even on tables with only 200 rows.
Is there a better (faster) way to do this?
"#"+colo is (must be!) a unique id. No reason for the cascaded finds - and if not, you are facing other problems:
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var colo = $(event.target).parent().attr("id"); // colNo is stored as Icons id
$("#"+colo).fadeTo(0,0.2);
});
});
[edit]
As per the comments, in order to fade out Columns, the id must better hold information about row and column and will thus be unique per cell:
<tr>
<td id="1.1">scheme is <col>.<row></td>
<td id="2.1">
...
<tr>
<td id="1.2">
<td id="2.2">
...
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var roco= $(event.target).parent().attr("id");
var col = roco.split('.')[0];
var row = roco.split('.')[1];
// now search all TD#s which have the clicked col (1.~) as a beginning of their ID
myDOMElement.find("td[id^='" + col + ".']").each(function(index) {
this.fadeTo(0,0.2);
});
});
see also jQuery Attribute selector
Since I dont need the animation provided by .fadeOut() I fond a faster way to do this:
myDOMElement.find(".myTable").find("tr").find("#"+colo).css({opacity:0.2});

Highlight matching part of string in TD when other TD is hovered

If i mouse over a TD element i want to highlight part of the string in another TD. Example: If i mouse over apple i want to highlight the apple part of applebanana.
I tried several things but didn't get closer to any solution. Thank you for your help.
My Code up to now: Cannot use word param because it is undefined. this.innerText does not return "apple".
Also onMouseout the hightlighted part of the string gets deleted.
function hightlightInput(word){
$(document.getElementById("testid")).html($(document.getElementById("testid")).html().replace(new RegExp("(apple)(?![^\">]*\"[^>]*>)", "i"), "<mark>$1</mark>"));
}
function resetHighlight() {
$(document.getElementById("testid")).find("mark").replaceWith(function() {
return $(document.getElementById("testid")).contents();
});
}
HTML
<table>
<tr>
<td onMouseOver="hightlightInput(this.innerText)"onMouseOut="resetHighlight()">apple</td>
<td id="testid">applebanana</td>
</tr>
</table>
In these situations, I always use a regexp and put the text in a <mark> element, which I remove later on.
You could then improve it by giving colors in and adding these as a style to the mark element, but by default it gives a yellow background to text (in most browsers). The mark element is easy to find back and usually doesn't get used for anything else, so its perfect for these things.
HTML:
<table>
<tr><td id="change">applebanana</td></tr>
<tr><td onMouseOver="highlightInput(this, this.textContent)"onMouseOut="resetHighlight(this)">apple</td></tr>
</table>
Here's a solution fully in native JS:
function highlightInput(element, word) {
element.innerHTML = element.innerHTML.replace(new RegExp("(" + word + ")(?![^\">]*\"[^>]*>)", "i"), "<mark>$1</mark>");
}
function resetHighlight(element) {
var marks = element.getElementsByTagName("mark");
var marksLength = marks.length;
for(var i = (marksLength - 1); i >= 0; --i)
{
element.replaceChild(document.createTextNode(marks[i].innerText), marks[i]);
}
}
Fiddle: http://jsfiddle.net/gpgekko/LshW6/1/
Here's a solution using the jQuery library:
function highlightInput(element, word) {
$(element).html($(element).html().replace(new RegExp("(" + word + ")(?![^\">]*\"[^>]*>)", "i"), "<mark>$1</mark>"));
}
function resetHighlight(element) {
$(element).find("mark").replaceWith(function() {
return $(this).contents();
});
}
Fiddle: http://jsfiddle.net/gpgekko/LshW6/
I'll leave the adaptation to find all elements to highlight up to you, let me know if you need help with that. But it's probably just looking through the table for occurrences of the word if I read your question correctly.

target the parent row of a particular cell

I have a table with a list of records. each row has class "list_request" and has a cell of class "record_approval":
<table>
<tr>
<th>name</th><th>date</th><th>id</th><th>group</th><th>approval</th>
<tr class="list_request">
<td>Frank</td><td>2012-2-15</td><td>01</td><td>Account</td><td class="record_approval">Dave Ellis</td>
</tr>
<tr class="list_request">
<td>Ellen</td><td>2012-2-19</td><td>04</td><td>Admin</td><td class="record_approval">Susan Peters</td>
</tr>
<tr class="list_request">
<td>Michael</td><td>2012-2-26</td><td>06</td><td>Admin</td><td class="record_approval"></td>
</tr>
I'd like to construct a javascript function that checks whether or not "record_approval" has a value (which value is unimportant), and if so, change the css color value for that row. Essentially, the approved records should have a different color than the unapproved ones.
something like...
function check_approval(){
var checkrow = document.querySelectorAll( "tr.request_list" )
var checkcell = document.querySelectorAll( "td.record_approval" )
for (i=0;i<checkcell.length;i++){
if (!checkcell.value){
this.parentNode.style.color = "ff9900";
}
else{
}
}
is this essentially the wrong approach?
Mistakes I found:
Unclosed for loop (missing closing })
You're looking for class request_list, but on your html it's list_request
You should be using checkcell[i] instead of checkcell inside your loop
Your color hex value should begin with a #.
There's no need to get all rows and cells from an event listener
It's unclear when you want that function to run. Should it respond to an event?
Also, I'd set a new css class on the row, instead of setting the color directly.
Apparently, you're looking for this:
var checkcell = document.querySelectorAll( "td.record_approval" );
for (i=0;i<checkcell.length;i++){
if (checkcell[i].innerHTML){
checkcell[i].parentNode.style.color = "#ff9900";
}
}
http://jsbin.com/anadij/1/edit
checkcell is an array of elements. you'll want to loop through them, accessing 'checkcell[i]' instead of checkcell.value.
your hex color should be defined with a "#" preceding ff9900
your for loop isn't closed properly
basically update it s.t.
if (!checkcell[i].value){
checkcell[i].parentNode.style.color = "#ff9900";
} else{
}

odd even class for table rows

I have table with rows where as in between have hidden rows and because of that odd even css class not able to set. How can I avoid those hidden rows?
HTML
<tr class="oddRow">
<td>Avinash</td>
<td>18-Jun-2010</td>
<td>LI1004</td>
<td>5,600.00</td>
<td>Sort</td>
</tr><tr class="oddRow" style="display:none;">
<td>Ajith</td>
<td>18-Jun-2010</td>
<td>LI1006</td>
<td>5,001.00</td>
<td>!</td>
</tr><tr class="evenRow">
<td>Ankur</td>
<td>14-Jun-2010</td>
<td>LI1005</td>
<td>5,000.00</td>
<td>me</td>
</tr><tr class="oddRow">
<td>Ajith</td>
<td>18-Jun-2010</td>
<td>LI1006</td>
<td>5,001.00</td>
<td>!</td>
</tr>
I know this isn't tagged jQuery but this would be the easiest way to apply this solution...
You don't need two CSS classes here (odd and even), just one. Start by setting the CSS for every row to use the "oddRow" style declarations by default. The "evenRow" style declarations should simply overwrite the defaults.
Add this JS function
var zebraStripes = function($) {
$('table.stripes tr').removeClass('evenRow')
.filter(':visible:odd').addClass('evenRow');
// using the :odd selector as it is zero-based
}
You can then bind this function to the document ready event as well as any event that changes row visibility.
Edit
Updated to work with jQuery 1.7, example here - http://jsfiddle.net/UZNKE/6/
Assuming your question is asking what I posted in the comments, you'll have to have a more in-depth 'hide' function which will change the classes of all subsequent functions. I expect you'll want to use something like this:
function hideRow(rowNum)
{
var rows = document.getElementById('table-id').getElementsByTagName('table');
// get current class and hide the row
var currentClass = rows[rowNum].className;
rows[rowNum].style.display = 'none';
// set up classname array
var classNames = new Array("oddRow", "evenRow");
// make sure 'j' points to the next desired classname
var j = 0;
if (classNames[j] == currentClass)
j = 1;
// make all subsequent visible rows alternate
for (i=rowNum+1; i<rows.length; i++)
{
// ignore empty rows
if (rows[i].currentStyle.display == "none")
continue;
// set class name
rows[i].className = classNames[j];
j = (j+1) % 2;
}
}
Note: I haven't tested the code, but I commented it so you should be able to figure out what's going on

Categories