Drag and drop multiple rows from one table to another table - javascript

I need to drag and drop table rows by selecting desired rows from on table to another table. First provide option to select needed rows from one table and then all the selected rows need to be drag and drop into some other table.
I have done the sample to drag and drop single row from on table to another. Find the below code:
html:
<div id="table1" class="bitacoratable">
<table>
<thead>
<tr>
<th>ID</th>
<th>ClassName</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Class 1</td>
</tr>
<tr class="childrow">
<td collspan = "2" >
<table class="childgrid">
<tr class="draggable_tr">
<td>1</td>
<td>Student 1</td>
</tr>
<tr class="draggable_tr">
<td>2</td>
<td>Student 2</td>
</tr>
<tr class="draggable_tr">
<td>3</td>
<td>Student 3</td>
</tr>
<tr class="draggable_tr">
<td>4</td>
<td>Student 4</td>
</tr>
<tr class="draggable_tr">
<td>5</td>
<td>Student 5</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>2</td>
<td>Class 2</td>
</tr>
<tr class="childrow">
<td collspan = "2">
<table class="childgrid">
<tr class="draggable_tr">
<td>6</td>
<td>Student 6</td>
</tr>
<tr class="draggable_tr">
<td>7</td>
<td>Student 7</td>
</tr>
<tr class="draggable_tr">
<td>8</td>
<td>Student 8</td>
</tr>
<tr class="draggable_tr">
<td>9</td>
<td>Student 9</td>
</tr>
<tr class="draggable_tr">
<td>10</td>
<td>Student 10</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div id="table2" class="bitacoratable">
<table>
<thead>
<tr>
<th>ID</th>
<th>ClassName</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Class 1</td>
</tr>
<tr class="childrow">
<td>
<table class="childgrid">
<tr class="draggable_tr">
<td>1</td>
<td>Student 1</td>
</tr>
<tr class="draggable_tr">
<td>2</td>
<td>Student 2</td>
</tr>
<tr class="draggable_tr">
<td>3</td>
<td>Student 3</td>
</tr>
<tr class="draggable_tr">
<td>4</td>
<td>Student 4</td>
</tr>
<tr class="draggable_tr">
<td>5</td>
<td>Student 5</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>2</td>
<td>Class 2</td>
</tr>
<tr class="childrow">
<td>
<table class="childgrid">
<tr class="draggable_tr">
<td>6</td>
<td>Student 6</td>
</tr>
<tr class="draggable_tr">
<td>7</td>
<td>Student 7</td>
</tr>
<tr class="draggable_tr">
<td>8</td>
<td>Student 8</td>
</tr>
<tr class="draggable_tr">
<td>9</td>
<td>Student 9</td>
</tr>
<tr class="draggable_tr">
<td>10</td>
<td>Student 10</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
Script:
$("#table1 .childgrid tr, #table2 .childgrid tr").draggable({
helper: 'clone',
revert: 'invalid',
start: function (event, ui) {
$(this).css('opacity', '.5');
},
stop: function (event, ui) {
$(this).css('opacity', '1');
}
});
$("#table1 .childgrid, #table2 .childgrid").droppable({
drop: function (event, ui) {
$(ui.draggable).appendTo(this);
}
});
$(document).on("click", ".childgrid tr", function () {
$(this).addClass("selectedRow");
});
CSS:
table
{
border-collapse:collapse;
}
table, td, th
{
border:1px solid black;
}
.bitacoratable {
height: 400px;
overflow-y: auto;
width: 220px;
float:left;
}
#table1 {
margin-right: 100px;
}
.selectedRow {
background-color: #E7E7E7;
cursor: move;
}
How to do it for mutilple rows?
Regards,
Karthik.

You could use draggable's helper function. There's a nice implementation here.
Here's how it looks using the above as a guideline for your particular code:
JsFiddle Demonstration:
Explanation of what's going on:
(1) If there's only one selected, then we'll just treat this as a single drag and drop. Because it was not clicked yet (mouse holding down and dragging right away), we'll manually add the selectedRow class to ensure it gets properly removed from its original location.
(selected.length === 0) {
selected = $(this).addClass('selectedRow');
}
(2) Make a temporary container to store all the rows as one unit, as if we were dragging one item.
var container = $('<div/>').attr('id', 'draggingContainer');
container.append(selected.clone().removeClass("selectedRow"));
return container;
(3) You can modify the CSS so that we're always clicking on the items before it shows the move cursor. I already did, but feel free to change it as you like.
(4) Now we append all the table rows in our temporary divider into the .childgrid we chose to drop into and remove all elements that originally were selected.
$("#table1 .childgrid, #table2 .childgrid").droppable({
drop: function (event, ui) {
$(this).append(ui.helper.children());
$(this) is what we chose, and we're appending the elements inside our temporary divider that the helper returns, which are the table rows.
$('.selectedRow').remove();
}
Now to get rid of those table rows that we selected earlier.
});
Let me know if there are any bugs and I'll try my best to sort them out. It works on my end. Since you can highlight the text in the table rows, there could possibly be some issues if you drag and drop too fast and you're highlighting text rather than selecting the row itself.

Related

show more or less when clicking on button

could someone help me with this block of code please.
I have a table that usually comes with more than 5 rows.
I want to show only 5 when loading the page, and when clicking on "SHOW MORE" show the rest, when clicking on "SHOW LESS" show only 5.
SHOW MORE and SHOW LESS must be the same button
Can someone help me. I started using Jquery, but I wanted to use pure JS
$("[id*='trid'] > tr").each(function(index) {
if (index >= 5) {
$(this).hide();
}
});
function mostrarRegistros() {
$("[id*='trid'] > tr").each(function(index) {
$(this).show();
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tbody id="trid">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John 3</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 4</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 5</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 6</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
<br />
<br />
<br />
<button type="button" onclick="mostrarRegistros()">Show More/ Show Less</button>
Here is a solution using vanilla js, its one way to do it but could do it differently like attach the button dynamically which would simplify it abit.
If you have multiple tables use a class to define that the table should have reveal functionality, then grab all tables and pass in the element to a function which provides the functionality, then return the set of methods which can call on the buttons, using an id as an identifier.
const tableReveal = function(elm, options) {
// merge options
options = Object.assign({}, {
limit: 3
}, options)
// the tr's
let trs = elm.querySelectorAll('tbody tr')
// shown state
let shown
// funcs
const hide = () => {
trs.forEach((tr, index) => index >= options.limit ? tr.style.display = 'none' : '')
shown = false
}
const show = () => {
trs.forEach((tr) => tr.style.display = 'table-row')
shown = true
}
// initial state
hide()
// reveal funcs
return {
toggle: () => shown ? hide() : show(),
hide,
show
}
}
/**
* Usage:
* - For each over every table-reveal class, init reveal func and pass in element + options, return and assign table[id] for button
*/
let table = {}
document.querySelectorAll('.table-reveal').forEach(el => table[el.getAttribute('id')] = tableReveal(el, {
limit: 5
}))
<table style="width:100%" class="table-reveal" id="table-reveal-1">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John 3</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 4</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 5</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 6</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
<button type="button" onclick="table['table-reveal-1'].toggle()">Show More / Show Less</button>
<table style="width:100%" class="table-reveal" id="table-reveal-2">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John 3</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 4</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 5</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 6</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
<button type="button" onclick="table['table-reveal-2'].toggle()">Show More / Show Less</button>
And this is a solution from me on jquery, using the pseudo-classes :visble, which determines the visible tags of the tr, as well as the lt() selector to determine the minimum value of the rows in the table.
Also in my example, the button changes the text depending on the need to hide or show the text:
$('button').text('Show More');
and
$('button').text('Show Less');
$('#trid tr').hide();
$('#trid tr:lt(5)').show();
$('button').text('Show More');
function mostrarRegistros() {
if ($('#trid tr:visible').length <= 5) {
$('#trid tr').show();
$('button').text('Show Less');
} else {
$('#trid tr').hide();
$('#trid tr:lt(5)').show();
$('button').text('Show More');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tbody id="trid">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John 3</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 4</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 5</td>
<td>Doe</td>
<td>80</td>
</tr>
<tr>
<td>John 6</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
<br />
<br />
<br />
<button type="button" onclick="mostrarRegistros()"></button>

set div full height and width in click from another div

I am loading an html file into a content div based on a click from a menu bar. The HTML contains 5 tables but for some reason the div only shows the first 5 lines of the first table, then you need a scroll bar to view the rest of the tables. I want to see all the tables on a single view and only have the scroll bars if the information exceeds the screen. Any suggestions would help. I have tried to set the width and height to 100% on the div but that did not work. When I view the table HTML alone it looks the way I want it to.
Thanks for any and all help.
function load_codes() {
document.getElementById("content").innerHTML = '<object type="text/html" data="codes2.html" ></object>';
}
function load_mrgsql() {
document.getElementById("content").innerHTML = '<object type="text/html" data="mergesqlcode.html" ></object>';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidebar">
<h2>Sidebar</h2>
<p>Open Merge Analysis WorkBook</p>
<p>
Open Merge Analysis SQL file
</p>
<p>
Common Merge Code List
</p>
<p>Merge Analysis Statistics</p>
<p>My Statistics</p>
</div>
<div id="content" style="height: auto; width:auto; min-height:100%; display: block; overflow: auto;">
<h1>Merge Analysis Tracking</h1>
<p>Welcome to the Merge Analysis Tracking Tool</p>
<p>Look around</p>
</div>
<!-- HTML with Tables (only 2 shown) -->
<body>
<table class="table">
<thead>
<tr>
<th colspan="3">Case Close Codes</th>
</tr>
</thead>
<tr>
<td>BFU</td>
<td>BIOLOGICAL FATHER UNKNOWN</td>
</tr>
<tr>
<td>DGC</td>
<td>IV-D GOOD CAUSE</td>
</tr>
<tr>
<td>DNO</td>
<td>NCP DECEASED</td>
</tr>
<tr>
<td>ERR</td>
<td>CASE ENTERED IN ERROR</td>
</tr>
<tr>
<td>FOR</td>
<td>FOREIGN</td>
</tr>
<tr>
<td>INC</td>
<td>INCARCERATED, INSTITUTIONALIZED, MEDICAL</td>
</tr>
<tr>
<td>JNC</td>
<td>INITIATING JURISDICTION NON COOPERATION</td>
</tr>
<tr>
<td>LCO</td>
<td>LOCATE ONLY</td>
</tr>
<tr>
<td>LOC</td>
<td>LOSS OF CONTACT</td>
</tr>
<tr>
<td>NCA</td>
<td>NO CURRENT ORDER/ARREARS
<$500</td>
</tr>
<tr>
<td>NCO</td>
<td>NON-COOPERATION</td>
</tr>
<tr>
<td>P21</td>
<td>PATERNITY 21</td>
</tr>
<tr>
<td>PBI</td>
<td>PATERNITY BEST INTEREST</td>
</tr>
<tr>
<td>PEX</td>
<td>PATERNITY EXCLUDED</td>
</tr>
<tr>
<td>QLO</td>
<td>QUICK LOCATE ONLY</td>
</tr>
<tr>
<td>RSC</td>
<td>RECIPIENT OF SERVICES REQUEST CLOSURE</td>
</tr>
<tr>
<td>UL1</td>
<td>UNABLE TO LOCATE 1 YEAR</td>
</tr>
<tr>
<td>UL3</td>
<td>UNABLE TO LOCATE 3 YEARS</td>
</tr>
</table>
<table class="-table">
<thead>
<tr>
<th colspan="4">Relationship Codes</th>
</tr>
</thead>
<tr>
<td>01</td>
<td>SELF</td>
</tr>
<tr>
<td>02</td>
<td>SPOUSE</td>
</tr>
<tr>
<td>05</td>
<td>CHILD</td>
</tr>
<tr>
<td>06</td>
<td>GRANDCHILD</td>
</tr>
<tr>
<td>07</td>
<td>NEPHEW OR NIECE</td>
</tr>
<tr>
<td>08</td>
<td>SIBLING</td>
</tr>
<tr>
<td>09</td>
<td>FIRST OR SECOND COUSIN</td>
</tr>
<tr>
<td>10</td>
<td>OTHER RELATIVE</td>
</tr>
<tr>
<td>13</td>
<td>UNBORN</td>
</tr>
<tr>
<td>15</td>
<td>STEP CHILD</td>
</tr>
<tr>
<td>16</td>
<td>STEP GRANDCHILD</td>
</tr>
<tr>
<td>17</td>
<td>STEP NEPHEW OR NIECE</td>
</tr>
<tr>
<td>18</td>
<td>STEP BROTHER OR SISTER</td>
</tr>
<tr>
<td>19</td>
<td>OTHER SPECIFIED RELATIVE</td>
</tr>
<tr>
<td>20</td>
<td>ATTORNEY</td>
</tr>
<tr>
<td>27</td>
<td>OTHER</td>
</tr>
<tr>
<td>28</td>
<td>FATHER</td>
</tr>
<tr>
<td>29</td>
<td>ALLEGED FATHER</td>
</tr>
<tr>
<td>30</td>
<td>STEP FATHER</td>
</tr>
<tr>
<td>31</td>
<td>GRAND FATHER</td>
</tr>
<tr>
<td>32</td>
<td>MOTHER</td>
</tr>
<tr>
<td>33</td>
<td>STEP MOTHER</td>
</tr>
<tr>
<td>34</td>
<td>GRAND MOTHER</td>
</tr>
<tr>
<td>35</td>
<td>SISTER</td>
</tr>
<tr>
<td>35</td>
<td>SISTER</td>
</tr>
<tr>
<td>36</td>
<td>AGENCY</td>
</tr>
<tr>
<td>36</td>
<td>AGENCY</td>
</tr>
<tr>
<td>37</td>
<td>AUNT</td>
</tr>
<tr>
<td>37</td>
<td>AUNT</td>
</tr>
<tr>
<td>38</td>
<td>UNCLE</td>
</tr>
<tr>
<td>38</td>
<td>UNCLE</td>
</tr>
<tr>
<td>39</td>
<td>BROTHER</td>
</tr>
<tr>
<td>39</td>
<td>BROTHER</td>
</tr>
<tr>
<td>40</td>
<td>ADOPTED CHILD</td>
</tr>
<tr>
<td>40</td>
<td>ADOPTED CHILD</td>
</tr>
<tr>
<td>99</td>
<td>UNKNOWN</td>
</tr>
<tr>
<td>99</td>
<td>UNKNOWN</td>
</tr>
</table>
If I understand your question correctly, you want to make the object have it's full height and not display scrollbars, instead of the other way around.
If so, you should be able to do something like this:
function load_codes() {
let elem = document.getElementById("content")
elem.innerHTML = '<object type="text/html" data="codes2.html" ></object>';
elem.onload = function(e) {
elem.style.height = e.contentWindow.document.body.offsetHeight;
}
}
That should get what you need. You may need to do additional css to remove the object's borders.

Filtering: How to hide/show (toggle) certain table rows on click?

Assuming this table (actually it could have more columns and rows):
<table id="vehicles">
<tr>
<th>Type</th>
<th>Color</th>
<th>Wheels</th>
</tr>
<tr>
<td>Car</td>
<td>Red</td>
<td>4</td>
</tr>
<tr>
<td>Motorcycle</td>
<td>Green</td>
<td>2</td>
</tr>
<tr>
<td>Bike</td>
<td>Blue</td>
<td>2</td>
</tr>
<tr>
<td>Car</td>
<td>Blue</td>
<td>4</td>
</tr>
<tr>
<td>Bike</td>
<td>Green</td>
<td>2</td>
</tr>
<tr>
<td>Motorcycle</td>
<td>Red</td>
<td>2</td>
</tr>
</table>
Now my goal is to be able to click on the table data (cells), for example "Car", and then show only the two cars. Another click on "Car" should show the hole table again. Or one click on "Red", and then only the red vehicles (red car and red motorcycle) should be shown. How can this be achieved using jQuery?
$(function () {
$( "td" ).on( "click", function() {
var type = $(this).text();
$('td:first-child').parent('tr:not(:contains('+type+'))').toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="vehicles">
<tr>
<th>Type</th>
<th>Color</th>
<th>Wheels</th>
</tr>
<tr>
<td>Car</td>
<td>Red</td>
<td>4</td>
</tr>
<tr>
<td>Motorcycle</td>
<td>Green</td>
<td>2</td>
</tr>
<tr>
<td>Bike</td>
<td>Blue</td>
<td>2</td>
</tr>
<tr>
<td>Car</td>
<td>Blue</td>
<td>4</td>
</tr>
<tr>
<td>Bike</td>
<td>Green</td>
<td>2</td>
</tr>
<tr>
<td>Motorcycle</td>
<td>Red</td>
<td>2</td>
</tr>
</table>
Stores the text from current td, hides tr nodes which do not contain the text.
Here's a really really simple test that might help you get started.
$(function () {
$("#vehicles tr td").click(function () {
var desc = $(this).html();
$("#vehicles tr").css("background-color", "white");
$("#vehicles").find(":contains(" + desc + ")").closest("tr").css("background-color", "red");
});
});
This assigns a click event to every TD element, stores its value somewhere and then checks if said value exists in the table, highlighting the elements that are matched. Give it a spin, I think it'll set you off in the right direction.

How to create Html table in table from server side visual basic

I'm working in asp.net, visual basic.
I need to create html table inside a table.
I need to create all through server side.
The table will be with 6 cols and n rows. in the last col (more data) will be a link, and when clicking on that link (let say on row2) it will expand the specific row and show another table with 5 cols and m rows
clicking on that link again will close the row and hide the inside table.
For now I just try to do it in the client side, a little example to me, but I'm stuck.
I have this for now:
<div id="shutfuyotTable">
<table class="tblShutaf" dir="rtl" runat="server">
<thead>
<tr>
<td>num</td>
<td>name</td>
<td>sum1</td>
<td>sum2</td>
<td>notes</td>
<td>moreData</td>
</tr>
</thead>
<tbody>
<tr>
<td>row1</td>
<td>row1</td>
<td>row1</td>
<td>row1</td>
<td>row1</td>
<td>row1</td>
<tr>
<td colspan="5">
<table id="Table1">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
</table>
</td>
</tr>
</td>
</tr>
<tr>
<td>row2</td>
<td>row2</td>
<td>row2</td>
<td>row2</td>
<td>row2</td>
<td>row2</td>
<tr>
<td colspan="5">
<table id="Table2">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
</table>
</td>
</tr>
</tr>
<tr>
<td>row3</td>
<td>row3</td>
<td>row3</td>
<td>row3</td>
<td>row3</td>
<td>row3</td>
<tr>
<td colspan="5">
<table id="Table3">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
</table>
</td>
</tr>
</tr>
</tbody>
</table>
</div>
In the css I put row1 (id) as display: none;
I'm not manage to do the javascript, that when I'm clicking on the link it will show or hide the table.
What do I need to add in this code (Maybe onClick function?!?)
and what I need to do in javascript?

Toggle the <TR>

I am trying to do hide the belonging rows. For example if you click on 'Sub Title 1' which will then hide Item 1, Item 2 and Item 3 rows only.
Example:
<table border="1">
<tbody>
<tr class="head">
<td> title </td>
</tr>
<tr class="sub-title">
<td>Sub Title 1</td>
</tr>
<tr> <td>Item 1</td> </tr>
<tr> <td>Item 2</td> </tr>
<tr> <td>Item 3</td> </tr>
<tr class="sub-title">
<td>Sub Title 2</td>
</tr>
<tr> <td>Item 4</td> </tr>
<tr> <td>Item 5</td> </tr>
<tr> <td>Item 6</td> </tr>
</tbody>
</table>
-
$('.sub-title').click( function() {
$(this).parent().nextUntil('.sub-title').toggle();
})
It doesn't seem to work...
nextUntil selects for siblings, not children. Remove the "parent" from your call.
Edited to respond to further question about excluding some rows based on class. Obviously you can also accommodate Kolink's response about preventing toggle's "display: block" overwriting the default "display: table-row", but as long as you test in all supported browsers, I don't see any problem with using toggle.
$('.sub-title').click( function() {
$(this).nextUntil('.sub-title').each(function() {
if (!$(this).hasClass('order'))
$(this).toggle();
});
});
You have to toggle manually:
$(".sub-title").on("click",function() {
$(this).nextUntil(".sub-title").each(function() {
this.style.display = this.style.display == "none" ? "" : "none";
});
});

Categories

Resources