How to permute 2 cells of a table - javascript

I'd like to do a small function that would permute 2 cells of a table with jQuery (or PHP/Ajax).
Let's say I have the following table:
<table class="table">
<tr>
<td class="btn" data-cellN="1">
01
</td>
<td class="btn" data-cellN="2">
02
</td>
</tr>
<tr>
<td class="btn" data-cellN="3">
05
</td>
<td class="btn" data-cellN="4">
06
</td>
</tr>
</table>
How to select 2 cells and permute them?
EDIT:
I made my way through the function thanks to your advice, nevertheless. It is working the first time bug I got a weird bug coming from the c1 c2 c3 variables, I don't know why,
could anyone help me to finish my function please?
Here is my Javascript: (it is wrapped in a doc ready)
var nbbuttonclicked=0; // to trigger the movecell function after the second button was clicked
var count=0; //Number of tinme we moved a cell
var table = {
c1:null,
c2:null,
c3:null,
check: function(){
$('td').on('click', function(){ //When the user click on a button we verify if he already clicked on this button
if( $(this).hasClass('btn-info') ) {
//If yes, then remove the class and variable c1
$(this).removeClass('btn-info');
table.c1=0;
nbbuttonclicked--;
}else{
//if no, then add a class to show him it is clicked and remember the value of the cell
$(this).addClass('btn-info');
if( typeof table.c1 === 'undefined' || table.c1===null) {
table.c1 = $(this);
console.log('c1:'+table.c1.html());
}else{
table.c2 = $(this);
console.log('c2:'+table.c2.html());
}
nbbuttonclicked++;
if( nbbuttonclicked==2 ) {
table.movecell(table.c1,table.c2); // we trigger the function to permute the values
}
}
});
},
movecell: function(c1, c2){
//We reset that variable for the next move
nbbuttonclicked=0;
//we move the cells
table.c3=c1.html();
c1.html(c2.html());
c2.html(table.c3)
c1.removeClass('btn-info');
c2.removeClass('btn-info');
table.c1=table.c2=table.c3=c1=c2=null;
},
// movecell: function(c1, c2){
// We check if the cells.html() are = to data-cellN. If yes, you won
// foreach()
// },
// var row = $('table tr:nth-child(1)')[0];
// moveCell(row, 0, 3);
};
table.check();
and here is a sample:
http://jsbin.com/exesof/2/edit

Try this code:
var cell0,
cell1,
next,
row0,
row1;
$('td').on('click', function() {
if(!cell0) {
cell0 = this;
row0 = cell0.parentNode;
return;
} else if(!cell1) {
cell1 = this;
row1 = cell1.parentNode;
// === Switch cells ===
next = cell0.nextSibling;
row1.insertBefore(cell0, cell1);
row0.insertBefore(cell1, next);
// ====================
row0 = row1 = cell0 = cell1 = next = null;
}
});
Working example you can try here: http://jsbin.com/irapeb/3/edit
Click one of the cells, than another one and see they are switched :)

This code will move the 4th td (referenced as cell[3]) on place of the first cell (cell[0]) in the first row (and the 1st becomes the 4th):
function moveCell(row, c1, c2) {
var cell = row.cells;
arr = [c1, c2].sort(),
c1 = arr[1],
c2 = arr[0];
row.insertBefore(row.insertBefore(cell[c1], cell[c2]).nextSibling, cell[c1].nextSibling);
}
var row = $('table tr:nth-child(1)')[0];
moveCell(row, 0, 3);
http://jsfiddle.net/2N2rS/3/
I wrote this function to simplify process. It uses native table methods.
Modifying the number of row (:nth-child(1)) and indexes of the table cells you can permute them as you need.

with jQuery, you can do it with:
$(document).ready(function() {
$("table.table tbody tr td:first-child").each(function(index, element) {
// this and element is the same
$(this).insertAfter($(this).next());
});
});
Assuming you don't ommited the tbody element (which is automatically added by some browser as default behaviour)
working example
If you want to do the process when clicking on the first cell, you just have to use on with click event instead of each.
$(document).ready(function() {
$("table.table tbody tr td:first-child").on('click', function(clickEvent) {
$(this).insertAfter($(this).next());
});
});

This can be done in pure javascript:
Fetch clicked sell count;
Fetch data of both cells, when they are selected;
Replace cell values with the opposite ones;
Store new values in DB via ajax call.
Now it's up to you to write the script.

Related

Finding cell value of dynamically generated table row

I am trying to delete an array record based on what table row is clicked.
This function adds a button to a row and appends it to the end of the table
function addButtons(table, tr){
var delBtn = document.createElement("button");
delBtn.innerHTML = "×"
delBtn.onclick = deleteBu(tr)
tr.appendChild(delBtn);
table.children[1].appendChild(tr)
}
The function below is meant to delete an array record based on the row clicked. For example, in row 1, the first cell is "45". Based on this, the record is deleted if it is found in the array storageProblem.
Here is what I have so far. The issue is because I am using tr as the action listener, so simply clicking on the row will delete the row, it is not localized to the button. But using tr is the only way I have found to get the first td of a row.
function deleteBu(tr){
$(tr).click(function(){
var value=$(this).find('td:first').html();
for(i = 0; i < storageProblem.length; i++){
if(value == storageProblem[i][0]){
storageProblem.splice(i, 14)
loadCallProblemTable()
}
}
})
}
I'm not sure if I've understood your question right but maybe try this solution:
function deleteBu(x) {
var Index = $(x).closest('tr').index();
console.log("Row index: " + Index);
}

Javascript: How To Get Cell bgcolor Above Current Cell Element?

SampleImage
<tr>
<td></td>
<td bgcolor = "Brown"></td>
<td></td>
</tr>
<tr>
<td></td>
<td id="current"></td>
<td></td>
</tr>
How do I use Javascript to get the bgcolor of the cell above a cell using the cell's id as reference to the chosen cell then compare if the bgcolor is equal to Brown?
EDIT:
function move2(barName, start, currentCell, totSec,barLength) {
var no = start;
var current = currentCell;
var totalSec = totSec;
var span = no - current;
var bar = barName + no;
var lengthCount = 0;
var progLength = barLength - 1;
var elem = document.getElementById(bar);
var width = 0;
var stop = 0;
function fill(){
while(no < current){
if(lengthCount >= progLength){
stop = 1;
break;
}
elem.style.width = '100%';
if ($(this).parent().next().children("elem").index() == "Brown") {
elem.className = 'progress-bar progress-bar-danger';
}
no++;
bar = barName + no;
elem = document.getElementById(bar);
lengthCount++;
stop = 0;
}
}
}
Sorry, my attempts have been trying some jQuery codes I've found on some other posts where the problems are kinda similar but I just don't get the parent and children methods. I'm working on a progress bar where if the cell above it(Row for time periods) is brown (Break Time) the progress bar should turn red, hence changing the default cell's class from progress-bar-success to progress-bar-danger if the cell above it is brown.
I went about this virtually the same way as Sandip, albeit sans the use of jQuery. First, I've asked the browser to call my function when the page has finished loading. Next, I extend the HTMLCollection data-type so that we can use the array data-type's forEach function on an HTMLCollection.
Once done, the page calls our code and immediately locates the cell we seek (t1). Having done this, we simply step through the rows collection of the table to find the one that matches the parentNode of our t1 - this will be the row that contains it. Next we step through the cells collection and search for the t1 cell again - this means we now have the both row and the cell indices of our initial target, t1.
From there, we simply subtract 1 to the rows index and get our final target, t2. Once we have this cell, we can get any info from it we like, like the value of an attribute (bgcolor) or the contents, etc, etc.
<!doctype html>
<html>
<head>
<script>
window.addEventListener('load', onDocLoaded, false);
function byId(id){return document.getElementById(id);}
HTMLCollection.prototype.forEach = Array.prototype.forEach;
function onDocLoaded(evt)
{
// 1. get id=current cell
var curCell = byId('current');
// 2.get current row
var curRow = curCell.parentNode;
var table = curRow.parentNode.parentNode; // parentNode twice, since we're using both a table and a tbody element to wrap the rows.
// 3. get index of current row in table's 'rows' collection
var rowIndex = -1;
table.rows.forEach( function(elem, index, array){if (elem == curRow)rowIndex = index;});
// 4. get index of current cell in table's current row's 'cells' collection
var cellIndex = -1;
table.rows[rowIndex].cells.forEach( function(elem, index, array){if (elem == curCell)cellIndex = index;});
// 5. get data from the original target cell - the one below the one with an id of 'current'
alert( table.rows[rowIndex-1].cells[cellIndex].getAttribute('bgcolor') );
alert( table.rows[rowIndex-1].cells[cellIndex].textContent );
}
</script>
</head>
<body>
<table>
<tbody>
<tr>
<td></td>
<td bgcolor = "Brown">blah</td>
<td></td>
</tr>
<tr>
<td></td>
<td id="current"></td>
<td></td>
</tr>
</tbody>
</table>
</body>
</html>
Find the closest row and then find previous row and then get all cells and find your required property through each loop
$(document).ready(function () {
$("#current").closest("tr").prev().find("td").each(function (a, b) {
if(String(b["bgColor"]).trim()=="Brown")
{
//here is cell which has brown bgcolor
alert("brown");
}
});
});
You should use jquery in getting the background-color of that object.
like this:
var color=$("#tdwithbgcolor").css("background-color");
$("#tdtosetcolor").css("background-color",color);

Can't properly delete rows from a dynamically generated table using a button

I have the following code which is supposed to generate rows in a table where each row has its own content and delete button.
<!DOCTYPE html>
<html>
<head>
<title>table</title>
</head>
<body>
<input id="inputText">
<button onclick = "addRow()">Add text</button>
<table id = "table">
</table>
<script>
function addRow(){
var newRow = document.createElement("tr");
var col1 = document.createElement("td");
var col2 = document.createElement("td");
newRow.appendChild(col1);
newRow.appendChild(col2);
var button = document.createElement("button");
button.innerHTML = "delete";
button.onclick = function () {
var index = this.parentNode.parentNode.rowIndex;
document.getElementById("table").deleteRow(index);
}
col1.appendChild(button);
var enteredText = document.getElementById("inputText").value;
col2.innerHTML = enteredText;
document.getElementById("table").appendChild(newRow);
}
</script>
</body>
</html>
The problem is that no matter which delete button I press, it deletes the last row.
I tried using console.log(this.parentNode.parentNode) to see if it returns the right <tr> object, and it indeed does. But for some reason, the attribute rowIndex is -1 no matter what button is pressed; hence only the last row is deleted. Does it mean that each dynamically generated <tr> doesn't know its row index?
You can use HTMLTableElement.insertRow() function instead.
var newRow = document.getElementById("table").insertRow();
// newRow.rowIndex will return you the proper index
Here is a working fiddle
Update
It was a bug in the Webkit layout engine, (that moved to the forked Blink engine as well). This is why it works well in Firefox but not in earlier versions of Chrome (Blink) or Safari (Webkit).
The bug report is here, it's fixed now.
There are numerous way to achieve what you require. Here is another such example that is based on the code that you posted. Hopefully it will give you some further ideas.
(function() {
// create references to static elements, no need to search for them each time
var inputText = document.getElementById("inputText"),
butAdd = document.getElementById("butAdd"),
table = document.getElementById("table");
// a generic function for finding the first parent node, starting at the given node and
// of a given tag type. Retuns document if not found.
function findParent(startNode, tagName) {
var currentNode,
searchTag;
// check we were provided with a node otherwise set the return to document
if (startNode && startNode.nodeType) {
currentNode = startNode;
} else {
currentNode = document;
}
// check we were provided with a string to compare against the tagName of the nodes
if (typeof tagName === 'string') {
searchTag = tagName.toLowerCase();
} else {
currentNode = document;
}
// Keep searching until we find a parent with a mathing tagName or until we get to document
while (currentNode !== document && currentNode.tagName.toLowerCase() !== searchTag) {
currentNode = currentNode.parentNode;
}
// return the match or document
return currentNode;
}
// for deleting the current row in which delete was clicked
function deleteRow(e) {
// find the parent with the matching tagName
var parentTr = findParent(e.target, 'tr');
// did we find it?
if (parentTr !== document) {
// remove it
parentTr.parentNode.removeChild(parentTr);
}
}
// for adding a row to the end of the table
function addRow() {
// create the required elements
var newRow = document.createElement("tr"),
col1 = document.createElement("td"),
col2 = document.createElement("td"),
button = document.createElement("button");
// add some text to the new button
button.appendChild(document.createTextNode("delete"));
// add a click event listener to the delete button
button.addEventListener('click', deleteRow, false);
// append all the required elements
col1.appendChild(button);
col2.appendChild(document.createTextNode(inputText.value));
newRow.appendChild(col1);
newRow.appendChild(col2);
// finally append all the elements to the document
table.appendChild(newRow);
}
// add click event listener to the static Add text button
butAdd.addEventListener('click', addRow, false);
}());
<input id="inputText">
<button id="butAdd">Add text</button>
<table id="table"></table>

How to dynamically click a label to check entire row only?

The number of rows are dynamic so I cant fixate on the name of the row, here is the fiddle: http://jsfiddle.net/1vp29wxq/1/
$('.NameOfSensor').on("click", function () {
var tr = $(this).parents('tr:first');
var thisRow = tr.find(".rowMode");
var checkChecked = $("input[class='rowMode']:checkbox:checked");
var checkBoxes = $("input[class='rowMode']:checkbox");
if (checkChecked.length < checkBoxes.length)
{
checkBoxes.prop("checked", true);
}
else {
checkBoxes.prop("checked", false);
}
});
What I get from that is that all check boxes are selected, but I just want the ones from the row where it is clicked. Also, whatever I tried I cant seem to incorporate the 2 variables (tr and thisRow) I created, can I get some help? Also, the number of columns in which the checkboxes are, are always 6 (sometimes I just hide them).
Change your code into this:
$('.NameOfSensor').on("click", function () {
var tr = $(this).closest('tr');
var checkChecked = $(tr).find("input[class='rowMode']:checkbox:checked");
var checkBoxes = $(tr).find("input[class='rowMode']:checkbox");
if (checkChecked.length < checkBoxes.length)
{
checkBoxes.prop("checked", true);
}
else {
checkBoxes.prop("checked", false);
}
});
Your selector was wrong and got all rows.
Search for checkboxes within the clicked line:
var tr = $(this).closest('tr'); // fast alternative to `.parents('xxx:first')`
var checkChecked = $("input[class='rowMode']:checkbox:checked", tr),
checkBoxes = $("input[class='rowMode']:checkbox", tr);
DEMO: http://jsfiddle.net/1vp29wxq/2/

How to get the row value on clicking a link

I have a table with 3 rows, each having hrefs. On click of these links, i need to get the entire value of the row where the link is clicked.
Data
Test1_link image_link view-link
Test2_link image_link view-link
the data above are links, on click on any link, its corresponding row value should be rendered.
Can anyone please suggest me on how to achieve that?
Thanks.
You could put a simple script immediately after your table:
<script>
(function (d) {
// Get the table element
var table = function() {
var tables = d.getElementsByTagName('table');
return tables[tables.length - 1];
}();
table.onclick = function (e) {
var target = e.target;
// If an <a> was clicked
if( target.nodeName.toLowerCase() === 'a' ) {
// Find the tr containing that a
var node = target;
while (node.nodeName.toLowerCase() !== 'tr' )
node = node.parentNode;
var tr = node;
// Output the contents of the table cells in that row
var cells = tr.cells;
for (var i = 0; i < cells.length; i++ )
console.log(cells[i].innerHTML);
// Return false to prevent the link from loading
return false;
}
}
})(document)
</script>
JSFiddle
Try this with jQuery http://www.jquery.com.
<table class="js-mytable">
<tr data-id="23" data-something="you've got it!">
<td>
Test Link
</td>
<td>
Image Link
</td>
<td>
View Link
</td>
</tr>
</table>
<script>
//run after document ready event
$(function(){
//all links in table with class js-mytable
$('table.js-mytable').on('click','a',function(){
//var $cell = $(this).parents('td'); //get the parent td of the link
var $row = $(this).parents('tr'); //get the parent tr of the link
//get the html5 data attributes from the row
var id = $row.data('id');
var something = $row.data('something');
//do something with the vars
//alert('Id: '+id+': '+something);
//get the full html <tr>...</tr>
//we need to merge it to a new pseudo html element
//to get the full html with surrounding <tr>
var html = $('<div>').append($row.clone()).html();
alert(html);
return false; //prevent default link action (href)
});
});
</script>
If you need more details, you need to extend your question...
JsFiddle: http://jsfiddle.net/7ud43

Categories