Find out which row of table you've just moved - javascript

I want to make a table with dragabble and droppable rows which I can achieve with jquery ui, however I then want to update the number in first cell in each row to always correspond to the numerical order from the top down.
For example the table might start out like this:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>1</td><td>abc</td></tr>
<tr class="draggable droppable"><td>2</td><td>def</td></tr>
<tr class="draggable droppable"><td>3</td><td>ghi</td></tr>
</tbody>
</table>
After the user has dragged the rows about it may end up like this for example:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>2</td><td>def</td></tr>
<tr class="draggable droppable"><td>3</td><td>ghi</td></tr>
<tr class="draggable droppable"><td>1</td><td>abc</td></tr>
</tbody>
</table>
I then want to run a function to sort numbers in the first cells back into numerical order from the top down so that the html would change to look like this:
<table id="myTableId">
<tbody>
<tr class="draggable droppable"><td>1</td><td>def</td></tr>
<tr class="draggable droppable"><td>2</td><td>ghi</td></tr>
<tr class="draggable droppable"><td>3</td><td>abc</td></tr>
</tbody>
</table>
The rows have been moved but the row at the top still has the value 1 in the first cell, the second row still has the value 2 and so on...
I have found a JavaScript a function which counts the number of rows in a table, how can I write a JavaScript function to reorder the numbers 1,2 and 3 back into sequence in the first cells in the table?
<script>
var rows = document.getElementById('myTableId').getElementsByTagName('tbody')[0].getElementsByTagName('tr').length;
alert(rows);
</script>
For reference this is the jquery I am using to make the rows draggable and droppable:
$(function() {
$(".draggable").draggable( {
helper: function() { return "<div class='shadow'></div>"; },
start: moveShadow,
revert: true
});
function moveShadow(event, ui) {
var helper = ui.helper;
var element = $(event.target);
helper.width(element.width());
helper.height(element.height());
}
$(".droppable").droppable({
hoverClass: 'ui-state-active',
drop: function(event, ui) {
var target = $(event.target);
var draggable = ui.draggable;
draggable.insertBefore(target);
}
});
});

No need to count anything. Just run a loop and increment:
http://jsfiddle.net/isherwood/tLpjho9f/
var myCount = 1;
$('#myTableId tr.droppable').each(function() {
$(this).find('td').eq(0).text(myCount);
myCount ++;
});
You'll want to work that into the drop callback.

Related

change background-color on tablerow selection

I have a bunch of tables as partialViews which are loaded in using ajax.
now I want to write a global function that when someone clicks on a tablerow, the background-color turns orange, and when selecting a different tablerow the old one turns white again and the new one turns orange.
so I wrote this at the bottom of the _Layout.cshtml:
<script type="text/javascript">
$(document).ready(function() {
$("table tbody tr").on('click', function () {
var selected = $(this).hasClass("selectedTableRow");
$("table tbody tr").removeClass("selectedTableRow");
if (!selected)
$(this).addClass("selectedTableRow");
});
});
</script>
but it's not being reached at all, console.logs or alerts that I've placed in that function are not being fired. Why not?
btw my tables all have a standard setup
<table>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
you are creating tables dynamically so bind click event using document with .on, see below
$(document).ready(function() {
$(document).on('click',"table tr", function () {
var selected = $(this).hasClass("selectedTableRow");
$("table tr").removeClass("selectedTableRow");
if (!selected)
$(this).addClass("selectedTableRow");
});
});
$(document).ready(function() {
$("body").on('click', "table tr", function () {
$("table tr").removeClass("selectedTableRow");
$(this).addClass("selectedTableRow");
});
});

wrap divs within 2x2 table jquery

I have four divs like below.
<div class='link'>...</div>
<div class='link'>...</div>
<div class='link'>...</div>
<div class='link'>...</div>
I want to place them in a 2x2 table.
<table>
<tr>
<td><div class='link'>...</div> </td>
<td><div class='link'>...</div> </td>
</tr>
<tr>
<td><div class='link'>...</div> </td>
<td><div class='link'>...</div> </td>
</tr>
with jquery on document ready
=======
Actually I need nX2 grid layout for those DIV's, so I made each two divs have same height using jquery.css. But on zoom+- that grid setting disturbed, so I thought table layout would be better, I found wrapping a solution but I don't know how to wrap divs within nX2 table.
// i tried below each at once, but four divs, four rows wrapping a single div, i need how to wrap first two divs in one row, and each div in one td , totally a table....
1st trial $( ".linkbox" ).wrap( "<tr></tr>" );
2nd trial $( ".linkbox" ).wrap( "<table></table>" );
3rd $( ".linkbox" ).wrap( "<td></td>" );
What you can do this: DEMO
var t = $(document.createElement('table'));
t.appendTo('#target');
var tr;
var counter=1;
$('.link').each(function(){
console.log(this);
if(counter%2!=0)
{
tr = $(document.createElement('tr'));
tr.appendTo(t);
}
var td = $(document.createElement('td'));
td.appendTo(tr);
$(this).appendTo(td);
counter++;
});
Output:
<table>
<tbody>
<tr>
<td><div class="link">1</div></td>
<td><div class="link">2</div></td>
</tr>
<tr>
<td><div class="link">3</div></td>
<td><div class="link">4</div></td>
</tr>
</tbody>
</table>
Improved Demo by #Ruko
jsBin demo
$(".link").wrapAll("<table/>").each(function(i) {
$(this).wrap("<td/>");
if(i%2) $(this).parent().prev().andSelf().wrapAll("<tr/>");
});
To explain the jQuery above:
$(".link").wrapAll("<table/>") wrap them all into a table.
Each still refers to the DIV so we can do an each and pass the i index value
$(this).wrap("<td/>") wrap every DIV inside a TD element,
After the above is done, our DIV is now inside a TD element, and if i%2 is truthy means that we're currently inside the loop looking ad the ODD index element, so target the TD parent, target the previous TD element also, add to collection back the self and wrap them both into TR.
try
$("div.link").replaceWith(function (i, val) {
return $("<td/>", {
"class": $(this).attr('class'),
text: val
});
});
$("td.link").each(function (i, val1) {
if (i % 2 == 0) {
$("td.link:eq(" + i + "),td.link:eq(" + (i + 1) + ")").wrapAll($("<tr/>", {
'class': 'trNew'
}));
}
});
$("tr.trNew").wrapAll("<table/>");
DEMO
Try this jQuery code:
var table = $('<table></table>').addClass('foo');
for(i=0; i<3; i++){
var row = $('<tr></tr>').addClass('bar');
var td1 = $('<td></td>').addClass('bartd');
var td2 = $('<td></td>').addClass('bartd');
row.append(td1);
row.append(td2);
var div="<div class='link'> hi div </div>";
td1.append(div);
td2.append(div);
table.append(row);
}
$('html').append(table);
http://jsfiddle.net/rfa7Lh3g/3/

How to Get JQuery UI Droppable to Drop Multiple Elements?

I have been given a piece of code that allows the user to drag one row of a table to a div. I have been asked to allow the user to select multiple rows and drag them all to the div. I've been trying to modify the code I was given to do what I need it to do.
So, I have a table of rows, where the first column of each row contains a drop down box. I want the user to be able to select many check-boxes, and be able to drag all the rows corresponding to those checked check-boxes into another containing a table.
I managed to get the dragging part to work - the user is able to check many check-boxes, and its shows a group of rows being dragged. However, when I drop these rows, only one row in being dropped. Can anyone help me drop all the rows being dragged. Here is my code:
$(oTable.fnGetNodes()).draggable({
appendTo: "#event",
cursor: "move",
helper: function (event) {
var checkBoxes = $(".drag");
var rows = $('#lotsDataTable tr').filter(':has(:checkbox:checked)');
if (checkBoxes.length > 0) {
return $('<div class="dragContainer"><table></table></div>').find('table').append(rows.clone()).appendTo('#event');
} else {
return $('<div class="dragContainer"><table></table></div>').find('table').append($(event.target).closest('tr').clone()).appendTo('#event');
}
}
});
$("#event table").droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
accept: ":not()",
drop: function (event, ui) {
$(this).find(".placeholder").remove();
$("<tr></tr>").html(ui.draggable.html()).appendTo(this);
ui.draggable.draggable({ disabled: true });
}
});
This is the HTML that I want to drop to:
<div id="event">
<div class="datatable clearboth">
<table id="addLots" class="dataTable clearboth">
<tr class="placeholder" style="width: 100%">
<td style="height: 80px;">
Drag and drop rows here to add them to this event
</td>
</tr>
</table>
</div>
</div>
Only your helper has the modified content, the original draggable still only contains the original draggable. You can try dumping the helper's contents into your new <tr>:
$("<tr></tr>").html(ui.helper.html()).appendTo(this);

Copy Row from one table to another using Javascript

I have created two tables on my page. I want that when a user clicks on a table row, the data of that row is copied to another table.
<div class="processor">
<table id="proctable">
<tr class="header">
<th>Description</th>
<th>Price</th>
</tr>
<tr class="hover">
<td><span id="4770K">Intel Core i7 4770K 4TH GEN. 3.5GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$320</td>
</tr>
<tr class="hover">
<td><span id="4771">Intel Core i7 4771 4TH GEN. 3.5GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$290</td>
</tr>
<tr class="hover">
<td><span id="4770">Intel Core i7 4770 4TH GEN. 3.4GHZ 8MB CACHE MAX TURBO FREQUENCY 3.9GHZ</span></td>
<td>$280</td>
</tr>
<tr class="hover">
<td><span id="4771">Intel Core i5 4670K 4TH GEN. 3.4GHZ 6MB CACHE MAX TURBO FREQUENCY 3.8GHZ</span></td>
<td>$240</td>
</tr>
</table>
<div id="aside">
<table id="comptable">
<tr class="header">
<th>Product</th>
<th>Price</th>
</tr>
</table>
</div>
I have searched for any help I may find but could not get any specific answer.
Here is the link to the code on jsfiddle
http://jsfiddle.net/jibranjb/LzgNd/#&togetherjs=fcgCI5QRn8
I am fairly new to Javascript and jQuery so please consider that.
Not sure what you wanted exactly. But if you want to store the data you can store it using arrays. ( you can use any data structure, I am using them as they are simple)
Check the below code, I am using items array, to store the selected row. On clicking the Add to List button, the selected tr will be added to the array and it will be display in the respective table.
var items = [];
$(".addBtn").on("click", function() {
var newTr = $(this).closest("tr").clone();
items.push(newTr);
newTr.appendTo( $("#comptable") );
});
I have added the Add to List button, the updated html markup would be;
<td>
<input class="addBtn" type="button" value="Add to List">
</td>
Updated Fiddle Demo
add this script ( using Jquery)
$('#proctable tr.hover').unbind('click').click(function(){
$(this).clone().appendTo('#comptable');
return false;
})
http://jsfiddle.net/4qFgX/3/
I will suggest this:
$('#proctable tr.hover').click(function () {
var x = $(this)[0].outerHTML
$('#comptable').append(x);
});
Something like this ?
$(function() { // when dom is ready
$('#proctable tr.hover a').on('click', function(e) { // when you click on a link
var row = $(this).parents('tr').eq(0); // you get the direct parent of the current clicked element
$('#comptable').append(row); // you append this parent row in the other table
e.preventDefault(); // your prevent the default link action
});
});
http://jsfiddle.net/LzgNd/1/

Using each() for checking which class is clicked

So here's my problem, I'm new to jQuery. What I am trying to do here is check for user to click on a certain table cell/row and it would then display a div named popup of an index the same as the table cell votes. Without having to make separate functions of all the rows in my table.
Using some numerical value will display all the dialogs from a click of the cell of the same value the first time and from the second time only the correct one.
I bet there's some other way to do it and maybe there's just a stupid error.
Using the index value in the click and dialog function won't work.
I am open to suggestions on improvement also.
The scripts:
<script type='text/javascript'>
$(document).ready( function() {
$('.votes').each(function(index) {
$('.votes:eq(index)').click(function() {
$('.popup:eq(index)').dialog();
});
});
});
</script>
HTML for the table part, only a snippet
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
HTML for the div part, only a snippet of the div:
<div class='popup'>
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class='popup'>
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
jsFiddle Demo
You don't have to iterate using each for .click, that will happen internally. You can use .index() to get the index of the element clicked with reference to its parent.
$('.votes').click(function() {
$('.popup').eq($(this).index()).dialog();
});
Initially, the main problem is that you are not using string concatenation to apply the index to the selector (demo):
$('.votes:eq(index)')
// the Sizzle selector engine doesn't know what the string "index" is.
instead of
$('.votes:eq(' + index + ')')
// using concatenation calls the .toString() method of index to apply "0" (or "1", "2", etc.)
// so that the parsed string becomes '.votes:eq(0)' which the Sizzle selector engine understands
Once the Sizzle selector engine understands which elements to target (demo), the second problem is how jQueryUI changes the DOM with the .dialog method.
Inital markup:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
Once the first click event is handled, one of the div.popup elements is transformed into a jQueryUI Dialog and is appended to the body, removing it from its initial position, like so:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
<div class="ui-dialog ui-widget ..."> ... </div>
So your initial indexes no longer apply. Fortunately, there are several solutions to both problems (a few of which I've listed below).
Solutions to Problem 1:
Use string concatenation as described above.
Use the .eq method instead, which will accept the index variable as-is
Use a delegate handler instead and grab the index from within the handler:
Example of 2:
$('.votes').eq(index);
Example of 3:
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.parent().index(vote);
});
Solutions to Problem 2:
Create all of the dialogs initially and open them as needed.
Create the dialogs using a deep clone of the div element. (Not recommended)
Remove the td element to match the removed and re-appended div element. (Not recommended)
Example of 1:
var popups = [];
$('.popup').each(function (i, elem) {
var popup = $(elem).data('index', i).dialog({
"autoOpen": false
});
popups.push(popup)
});
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.index();
popups[index].dialog('open');
});
I'm sure there are other solutions as well, but these are the ones I thought of of the top of my head.
Functional demo: http://jsfiddle.net/2ChvX/2/
UPDATE:
With your chosen table structure, you're actually looking for the index of the parent tr element as that is what corresponds with the div.popup element. To get the index of the parent tr element, change the line that gets the index from:
index = vote.index();
to:
index = vote.parent().index();
Updated fiddle: http://jsfiddle.net/AZpUQ/1/
Updated
FWIW, here's an example using the jQueryUI dialog (which I presume you are using?) and javascript sectionRowIndex and cellIndex.
Reusable code allowing you to identify the cell the user clicked in and perform appropriate action.
http://jsfiddle.net/KbgcL/1/
HTML:
<table id="myTable">
<tr>
<th>Label:</th>
<th>Washington</th>
<th>Idaho</th>
<th>California</th>
</tr>
<tr>
<td class='label'>Votes</td>
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
</tr>
<tr>
<td class='label'>Voters</td>
<td class='voters'>5,000</td>
<td class='voters'>15,000</td>
<td class='voters'>25,000</td>
</tr>
</table>
<div id="msg"></div>
jQuery/javascript:
var myTr;
$('#msg').dialog({
autoOpen:false,
title: 'Report:'
});
$('#myTable tr td').click(function() {
myTr = $(this).closest('td').parent()[0].sectionRowIndex;
myCell = this.cellIndex;
myState = $('#myTable').find('tr:eq(0)').find('th:eq(' +myCell+ ')').html();
myVoters = $('#myTable').find('tr:eq(' +myTr+ ')').find('td:eq(' +myCell+ ')').html();
if (myTr==2 && myCell==3){
//California
$('#msg').html('There are ' +myVoters+ ' voters in ' +myState);
$('#msg').dialog('open');
}else if(myTr==1 && myCell==1){
$('#msg').html('There were ' +myVoters+ ' votes made in ' +myState);
$('#msg').dialog('open');
}
});

Categories

Resources