I'm writing myself a little game in JavaScript, using jQuery. The game has a board, with cells in it, much like Minesweeper: the user clicks a cell, and its data needs to be changed in some way. Each cell is presented by a simple image, but has some more data associated with it.
What I mostly need is, when the user clicks a cell, I have to somehow determine the row and column which was clicked, manipulate the data appropriately and change the view.
On one hand, setting the click handler on every individual cell seems like an overkill, but if you set the click handler on the whole table, it becomes PITA to determine which table cell was clicked.
How would you handle such a situation? Maybe there is a plugin already that can simplify the whole thing?
add the click handler on the whole table. use event.target to get the clicked cell. add an attribute to each cell that will tell you what row/col it is, that way you dont have to run any massive/heavy JS to figure it out.
psuedocode:
$("table.game").click(function(e){
var cell = e.target;
var pos = $(cell).attr("name").split["_"];
var x = pos[0];
var y = pos[1];
return false;
});
markup:
<table class="game">
<tbody>
<tr>
<td name="0_0">
sdfasdfa
<td>
</tr>
</tbody>
</table>
note: having a name start with a digit isnt good, so fix as needed
This is a perfect example of a great use of the live() function. To find the x and y positions you just need to count the number of cells before or rows above this one:
$('#minesweeperTable td').live('click', function() {
var $this = $(this),
xPos = $this.prevAll('td').length,
yPos = $this.closest('tr').prevAll('tr').length
;
// your code here
});
The best thing about this is that no matter how many cells you have, there's only one event handler which makes for much better performance.
If your table is generated dynamically (js or php for instance) you could have each cell with a class and / or id attributes that gave you the information.
I don't know how you represent your cells so in pseudo code :
<table id="board">
<row>
<cell id="cell-0x0" />
<cell id="cell-0x1" />
...
</row>
<row>
<cell id="cell-1x0" />
...
</row>
...
</table>
Then in jQuery :
$('#board cell').click(function(){
var coord = $(this).attr('id').substr(5).split('x');
// do your stuff
});
If you have too many table cells setting the click handlers would be heavy, but you can make a workaround to calculate the box number from mouse click's event.page.X and event.page.Y this will give coordinatesof clicked pixel on your screen and you can calculate which box is under that pixel.
Or
You can also use event.target the get the node clicked.
check out jquery.event.
hope it helps, Sinan.
The click event bubbles and the original target can be found in the srcElement property of the event object (I think, or it might be another property, but it's there).
Related
I am working on one table, where I have created one button which I am using in different rows and tables based on some condition.
I have one scenario where I need to show the button to some specific users, I have implemented the condition however I am not able get the path of the button, I can hide the cell but in that case complete cell is removed from the table which is not looking good, please help me to get the path of the button, so that I can hide it, here is the code I am using:
totalrows = document.getElementById("DEVmyTable").rows.length;
for(i = 0;i<totalrows; i++){
if(actualusernamevalue == currentusernamevalue){
table.rows[i].cells[6].style.display = "";
}
if(actualusernamevalue != currentusernamevalue){
table.rows[i].cells[6].style.display = "none";
}
}
Here in Cells[6] my button is present which I am created dynamically like this:
row = document.getElementById("DEVFirstrow");
var w = row.insertCell(6);
w.innerHTML = '<button onclick="Releaseentry(this)"type="button"
id="release" class="btn btn-primary release">Release</button>';
I have not added the complete code here, but based on the ids I am using this code in different table and rows.
in this code I have hidden the cell, for hiding the button I am not able to get the path, and that is what I am looking for.
You actually style the cell based on table.rows[i].cells[6].style.display and not its content. You choose the 6th cell and style it.Another mistake you make is that you use id in the button while the button is used in multiple rows which makes the id useless as it should be unique.
What I would do is simply use the class of the buttons and then based on the checks you have decide what the button should do using jquery, so:
if(actualusernamevalue == currentusernamevalue){
$('.release').show();
}
if(actualusernamevalue != currentusernamevalue){
$('.release').hide();
}
If I understand well what you are trying to do at least. The simpler solution, the better solution!
EDIT: By the way, you should keep in mind that if someone wants to find the button when you play with the display property in both ways, they can always find it through the source code. If someone inspects the element and changes the CSS manually they will be able to see the button, so it's always important to have back end validation too for cases like this.
I think I have got my solution finally, Thanks #natan for your help.
table.rows[i].cells[6].getElementsByTagName('button')[0].style.display = "none";
table.rows[i].cells[6].getElementsByTagName('button')[0].style.display = "";
I should have used this code.
I have a html table 'TemplateData' populated dynamically from a db table...so for example could end up like:
ID Name Age
1 John 23
2 Mick 27
3 Mark 29
When the user clicks an image on screen it will post back the corresponding ID value. From here I want to change the background colour of the associating row.
So for example '2' has been posted back in 'fid'. so I have tried...
function highlightRowInTable(fid) {
var dtable = $("#TemplateData");
dtable.addClass("highlightedRow");
}
However this highlightes the outer cells of the table. I only want to highlight the corresponding row.
Iv been messing around with parents and siblings but cant find any working examples on line...any ideas?
It looks like your code is selecting the entire table, and then applying a class to it, though it is hard to say for sure. If you have an event listener attached to your table, you should be able to get the child element that was clicked on and toggle its class.
document
.getElementById('table')
.addEventListener('click', function(event){
// now event refers to the part of the dom that was clicked on
console.log(event)
});
Though I'm not sure without looking at your code. if you already have listeners set up, you might need to give every row an id based on fid, so that your function could specify the id to add class to.
function highlightRowInTable(fid) {
$(fid).addClass("highlightedRow");
}
when you create your table you can add an attribute to your <tr> to help select it later when an image is clicked.
#foreach (var row in table)
{
<tr data-uid="#row[id]">
<td></td>
</tr>
}
function highlightRowInTable(fid) {
var rows = $('tr').filter('[data-uid="' + fid + '"]');
rows.addClass("highlightedRow");
}
I'm trying to get the control which is inside of a cell table; in my table I have different controls, labels, checkboxes, etc.
I basically need to get the control which is used in that table
var x = document.getElementById('myTable').rows[0].cells;
alert(x[0].innerText);
//alert(x[3].innerHTML);
if (x.Control == checkbox) {
x.checked = true;
}
This will be in a loop but for now I just need to be able to check the checkbox by grabbing the control and setting that control to true
Any hints/help would be great
I doesn't really understand what you exactly need is it
document.getElementById("checkbox").checked = true;
here checkbox is the id of a particular checkbox
I would put a unique id on the form element instead and use that to grab it. In this way you can change the structure in the future. Example: perhaps you no longer want to use a table grid, but a grid of divs.
When you use innerHTML you will might also grab textnodes and other things you put in the cell.
An alternative - if you really want to find a specific cell in a table - is to give each cell a unique id on the form "cell-4-5" where 4 is the row and 5 is the column.
[EDIT]
If you want to have the cell contents returned as a DOM-object then childNodes can be used:
var x = document.getElementById('myTable').childNodes[0].childNodes[0].childNodes
If you want to have the cell contents returned as a string then innerHTML can be used:
var x = document.getElementById('myTable').childNodes[0].childNodes[0].innerHTML
To check if the checkbox is checked you need to keep it as a DOM element and thus use the first version.
I have an html table that looks like the following:
<table id="tree">
<tr id="foo-1">
<td>fooId1</td>
<td>fooName1</td>
<td>fooCsv1</td>
<td><button id="button-1" type="button" disabled>Save</button></td>
</tr>
<tr id="foo-2">
<td>fooId2</td>
<td>fooName2</td>
<td>fooCsv2</td>
<td><button id="button-2" type="button" disabled>Save</button></td>
</tr>
</table>
There are two modifications I want to do to this table:
-First, I want to make the fooName and fooCsv td elements editable (there are actually a couple more editable columns, but I'm just using two to make this example simpler). I know that I can simply put an input inside the td element and set the value, but was wondering if there's a simpler way.
-Second, I want the Save button in each row to become enabled when a user changes the text in that row via typing/copy-paste/etc. I've googled and found that I might be able to do this by adding a handler for an input event, but I'm not sure of the simplest way to incorporate this, and I'm not sure if it has ramifications for the first task I have.
I think this should be easy if I knew much about html and javascript, but I don't, so does anyone know a simple way to achieve what I'm trying to do?
<td contenteditable="true">fooName1</td>
And use what ever you want to post the table HTML
edit:
http://jsfiddle.net/9yyKN/11/
//Listen to blur event in contenteditable td elements
$('td[contenteditable=true]').blur(function () {
$(this).parent('tr').find('button').removeAttr('disabled');
});
//When a button is clicked find the nearest contenteditable td //element(s) and push their
text content to an array, this array is later being posted.
$('button').click(function () {
var contents = $(this).parents().find('td[contenteditable=true]');
var contentArray = [];
for (i = 0; i < contents.length; i++) {
contentArray[i] = contents[i].innerHTML;
}
$.post("test.php", contentArray);
});
I'm working on creating a javascript based spreadsheet application. Right now I can dynamically create the spreadsheet as a table with a supplied number of rows and columns and a text input in each cell as can be seen in this picture.
I'd like to have a generic event tied to all of the inputs in the table in which I am able to determine the row index and column index of the input that fired the event. Something like this:
$('.spreadsheet-cell').click(function () {
var rowIndex = $(this).attr('rowIndex');
var columnIndex = $(this).attr('columnIndex');
});
I originally tried implementing things by dynamically adding row and column index attributes to the html input element when I create it but when I add rows or columns after the original spreadsheet has been created things get messy trying to shift the value of these attributes around. I think I could make that method work if it came down to it but it seems messy and I'd prefer not to mess around so much with the DOM when I figure that there is probably some way using jQuery to determine the relative index of the parent <td> and <tr>.
Use jQuery .index. Within your function:
var rowIndex = $("#table tr").index($(this).closest('tr'));
var colIndex = $("#table td").index(this);