I need to find index of cell in table below a given cell. Imagine that I don't know anything about td_end, I just click at td_start and need to find td_end. Example (need find index of red cell(td_end), knowing index of green cell (td_start)): http://jsfiddle.net/r5BDW/65/
Problem that table will contain a lot of cells with rowspan attr, so usual searching by equal index will not work. Any advice how to find such cells?
example table:
<table border="1" style="width: 100%;">
<tr><td>111</td><td rowspan="3">22</td><td>3</td></tr>
<tr><td>111</td><td>3</td></tr>
<tr><td>111</td><td class="td_start">3</td></tr>
<tr><td>111</td><td>22</td><td class="td_end">3</td></tr>
<tr><td>111</td><td>22</td><td>3</td></tr>
<tr><td>111</td><td >22</td><td>3</td></tr>
</table>
console.log($('.td_start').index() ) // =1
console.log($('.td_end').index() ) // =2
I think that would be almost a crazy act to guess all the possible colspan and rowspan combinations.
What I would try with, is to literally
"touch" the element that is visually beneath the selector element using elementFromPoint
jsFiddle demo
$.fn.nextVert = function(){
var b = this[0].getBoundingClientRect();
var nxtV = document.elementFromPoint(b.left, b.bottom+10);
if(nxtV.tagName==="TD") return $(nxtV);
};
$('.td_start').nextVert().text("hello");
console.log( $('.td_start').nextVert().index() ); // 2
by simply getting the elementFromPoint
starting from the this bottom value + some tiny offset (I used 10px)
chek this solution: http://jsfiddle.net/r5BDW/68/
find td with same left position
jQuery
$(document).ready(function() {
var $td2=$('.td_start2');
fidnBelow($td2);
var $td=$('.td_start');
fidnBelow($td);
});
function fidnBelow($td)
{
var rez='';
var p=$td.position();
var left=p.left;
var td_count=$('tr').size();
var ind_tr=$td.parent().index();
var $table=$('#table');
ind_tr++;
for(i=ind_tr;i<td_count;i++)
{
var $below_tr=$table.find('tr').eq(i)
$below_tr.find('td').each(function(){
var tp=$(this).position();
var tleft=tp.left;
if(left==tp.left) rez=$(this).html();
})
if(rez!='') break;
}
alert(rez);
}
Related
I am having difficulty in understanding as to why my search of a table column is always showing the first row and the matched row after that? Even though the keyword doesn't match the cell in row 1 it will always show on top? I have gone through my code several times and tried different approach it still wont hide the first row?
Here is my working code
$('#filterbyname').on("keyup", function () {
var val = $(this).val();
var matches = $("table.bill tr:not(:first-of-type)");
matches.each(function (i,e) {
debugger;
$row = $(this);
$cells = $row.find("td:nth-child(2)");
$cells.each(function (i2, e2) {
var cell = $(this).text();
debugger;
$row.toggle(cell.indexOf(val) >= 0);
});
});
});
You can see from the above code if cell.indexOf(val) >= 0) then it will toggle according the matching rows.
Any suggestions please?
In fact in your matches variables you are using tr:not(:first-of-type) which selects all the rows expect the first one, because :not selector excludes all elements that matches :first-of-type here, which means that they are not the first child in their parent, so the first tr will be ignored.
Change this code:
var matches = $("table.bill tr:not(:first-of-type)");
To the following:
var matches = $("table.bill tr");
In the process of creating a tile-swap puzzle game for my jQuery class. Right now I'm working on trying to make the clicked tile switch with the blank tile (I'll figure out how to limit it to adjacent tiles afterwards). I've stored indexes of both indexes in new variables, but I can't figure out how to assign a variable as the td elements index.
$(document).ready(function(){
$('img').click(function(){
var tileSelected = $(this); //grab the clicked tiles index
var tileIndexOld = $("img").index(tileSelected);
var blankTile = $("#blank"); //grab the blank tiles index
var blankIndexOld = $("img").index(blankTile);
var tileIndexNew = blankIndexOld; //swap tile and blank indexes
var blankIndexNew = tileIndexOld;
$(this).attr("index", tileIndexNew);
$("#blank").attr("index", blankIndexNew);
});
});
I've also tried doing things like $(tileSelected).index(tileIndexNew); and $(this).index() = tileIndexNew; etc. I just can't seem to figure out how to overwrite with the new index.
Edit:
Okay, I've been shown the wickedness of my (attempted) index swapping ways! Still working on the solution, but I'm changing tracks and focusing on altering the src's as suggested by Starscream1984. I'll update again once I've got it figured out, many thanks to all!
Solution:
After trying it three different ways (with multiple sub-variations) this is what I ended up with:
$(document).ready(function(){
$("td").click( function(){
var tileVertical = $(this).index(); //get clicked tiles vertical position via its td
var tileHorizontal = $(this).parent().index(); //get clicked tiles horizontal position via its tr
var blankTile = $("#blank").parent(); //getting the td that contains the blank tile
var blankVertical = blankTile.index(); //get blank tiles vertical position (via its td)
var blankHorizontal = blankTile.parent().index(); //get blank tiles horizontal position via its tr
if( Math.abs(blankVertical - tileVertical) + Math.abs(blankHorizontal - tileHorizontal) == 1) //check if clicked tile is adjacent to the blank tile
{
blankTile.empty().html( $(this).html() ); //put the tile html into the blank slot
$(this).html("<img id='blank' src='blank.jpeg' width='200px' />"); //fill the tile slot with the blank, ID IS CRITICAL!!!!
} //function will only run once if id is omitted from this tag!!!
return 1;
});
});
My original approach tried to use the index as a quick and dirty variable to swap out. What I discovered was that the index in this case is simply more like a map with x and y coordinates. It was the inner html of the table cell that needed to be swapped, not the index itself.
You need to move the elements around using jQuery DOM modification methods. This solution assumes that each tile is contained in a DIV in the grid.
$('img').click(function(){
var tileSelected = $(this);
var parentSelected = tileSelected.parent();
var blankTile = $("#blank");
var blankParent = blankTile.parent();
parentSelected.append(blankTile);
blankParent.append(tileSelected);
});
A)
$('img').each(function(index, elem){
console.log(index);
});
B)
$('img').click(function(){
var index = $(this).index();
//or
//var index = $('img').index($(this));
console.log(index);
});
Are the right ways. So your code seems to be correct. Are you sure that all imgages exists at the moment you run the function? Do you noticed that your selector find all img in DOM?
If you want to assign an index variable for the td, one approach to do it dinamically is the following:
$(document).ready(function(){
var tdArray = $("td");//grabs all td elements
for(i = 0; i < tdArray.length; i++){
$(tdArray[i]).attr('data-index',i);//adds a data-index attribute on each one
}
});
You could then handle a click event like this:
$("td").click(function(){
alert($(this).attr('data-index'));
});
To keep track of your blank tile, you could simple assign its data-index to a global variable.
I am trying to generate a table dynamically using ajax call. To simplify things i have just added my code to js fiddle here -> http://jsfiddle.net/5yLrE/81/
As you click on the button "HI" first two columns are created properly.. but some how as the td length reaches 2 . its not creating another row. The reason is that when i do find on the table elements its actually retrieving the children table elements. Can some one pls help.
I want a two column table.. Thank you.
sample code:
var tr = $("#maintable tbody tr:first");
if(!tr.length || tr.find("td:first").length >= max) {
$("#maintable").append("<tr>");
}
if(count==0) {
$("#maintable tr:last").append("<td>hi"+content+"</td>");
}
Basically the matching of descendants was allowing for great great grandchildren etc. Just needed to make the matching more specific.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5yLrE/91/
max = 2
$("button").click(function () {
var content = $('#template').html();
var $table = $("#maintable");
var tr = $table.find(">tbody>tr:last");
if (!tr.length || tr.find(">td").length >= max) {
// Append a blank row
tr = $("<tr>");
$table.append(tr);
}
tr.append("<td>hi " + content + "</td>");
});
This one always targets the last row and adds a row if it does not exists at all (or there are too many divs already) which is what I gather you intended.
I also used the templating I suggested to separate messy HTML strings from the code.
You will want to check the length of the table cells before incrementing a new table row. After you have reached your max column length, reset the row and start over.
JSFiddle
max_columns = 2;
count=0;
$("button").click(function() {
var content='column';
if(count==max_columns||!$('#maintable tr').length){
$("#maintable").append("<tr>");
count=0;
}
if(count!=max_columns)
$("#maintable tr:last").append("<td>"+content+"</td>");
else
$("#maintable tr:first").append("<td>"+content+"</td>");
count++;
});
I have a table cell in which other tables are displayed (with background colors). The inner tables aren't always shown; they can be hidden via a button (change class with jQuery). Now I want the outer cell to always be filled with color. That means if only one table is displayed, its width should be 100%. When two are displayed, each width should be 50%, and so on.
How am I supposed to solve this?
Here's an example:
...
<td>
<table class="show"><tr><td></td></tr></table>
<table class=""><tr><td></td></tr></table>
<table class="show"><tr><td></td></tr></table>
</td>
...
In this case, the width should be 50%
You can change the width value with Jquery.
var count_table = $(".show").length; // count ".show" elements
$(".show").each(function{ // iteration on each ".show"
var width = 100/count_table; // % value of new width
$(this).css("width", width+"%"); // CSS modification
});
This code is just adapted for one TD element. You need to iterate on each "td" too.
(I hope I answered your problem)
To change the width of your elements you can use jquery.
Here's the page explaining how.
Here is another way: http://jsfiddle.net/ypJDz/1
A bit too complicated for what you need, but a great deal of possibility to expand.
function resizeTables() {
var baby = $("td > table.show"),
amount = baby.length,
mother = $("body");
baby.width(function () {
var w = mother.width() / amount;
return w;
});
}
resizeTables();
$("button").click(function () {
var $this = $(this),
ID = $this.index() + 1;
$("td > table:nth-child(" + ID + ")").toggleClass("show");
resizeTables();
});
Suppose I have a form with 20 rows as shown in the figure below:
I'm naming the elements in the each row as:
1st row (Ambiance) -> v1[requirement], v1[observation], v1[status], v1[remarks]
2nd row (TV Room) -> v2[requirement], v2[observation], v2[status], v2[remarks]
3rd row (Cleanliness) -> v3[requirement], v3[observation], v3[status], v3[remarks]
.... and so on till 20th row
Using jquery or javascript can I find the number of rows present based on the names of the element? i.e., in this form name starts from v1 and ends at v20. So there are 20 rows.
UPDATE
The reason why I want the number of rows is because I plan to process the forms using:
for($i=1; $i<=$rowcount; $i++)
{
$v.$i = $_POST['v'.$i];
// then insert the first row into table and so on
}
If there is always a header row, then the number of rows will be the number of tr elements in the table -1, Eg.
var rowCount = $("#myTable tr").length -1;
This saves you having to use some convoluted method of attribute selector or string parsing.
This approach should work for you:
var rowCount = $("#data-table tr").filter(function() {
return $(this).find('[name^="v"]').length;
}).length;
This code will count only tose rows which have input with the name starting with v. I guess this is what you need.
Quick demo: http://jsfiddle.net/dfsq/2P5cN/
UPD
As per Mark Reed's comment we can make it even more simple:
var rowCount = $('#data-table tr').has('[name^=v]').length;
If you can't modify the markup at all, then you'll pretty much have to loop over everything and do your own counting. Something like this:
var tds = document.getElementsByTagName('td'); // or just $('td') for jQuery
var count_tds = tds.length;
var max = 0;
for (var i=0; i<count_tds; ++i) {
var td = tds[i]
var m = td.id.match(/^v(\d+)\[/)
if (m) {
if (m[1] > max) max=m[1]
}
}
Now max is the number of rows, assuming there are no extraneous elements with id's that match the pattern.
http://jsfiddle.net/usDD7/1/
EDIT Clearly I wasn't thinking with jQuery. See dfsq's answer for a much better solution (and my comment on that answer for a tiny improvement).