Copy Row from one table to another using Javascript - 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/

Related

Why doesn't my partial view render <tr> elements?

So I'm trying to create a table, where the table rows being divs that I've constructed from data that I get from my database.
I've seem to run into a issue.. I got this piece of javascript that starts running as soon as the page is ready, and it runs over and over again each 10 seconds. The purpose of this script is to update the partial view using ajax so that I don't have to refresh the browser to see changes in the table.
<script type="text/javascript">
$(document).ready(function () {
setInterval(CheckAvailability, 10000);
setTimeout
});
function CheckAvailability() {
$.ajax({
type: "POST",
url: "/Dashboard/CheckChange",
contentType: "application/json; charset=utf-8",
dataType: "json",
mimeType: "text/html",
success: function (response) {
if (response) {
$('#itemsss').load("/Dashboard/ReturnItems");
console.log("Updated!");
}
else {
console.log("Failed!");
}
}
});
};
</script>
This returns true every single time because it's something I've set explicitly.
It does load(); the content that this action returns though.
public IActionResult ReturnItems()
{
Items = new List<EbayProduct>();
using (var ctx = new UserContext())
{
Items = ctx.Users.Include(x => x.Items).Where(x => x.Username == "Admin").FirstOrDefault().Items;
}
return PartialView("_Item", Items);
//return null;
}
This is where I load the PartialView
<div id="itemsss">
<table id="foo-filtering" class="table table-bordered table-hover toggle-circle" data-page-size="7">
<thead>
</thead>
<tr>
<td>
<partial name="_Item" />
</td>
</tr>
<tfoot>
<tr>
<td colspan="5">
<div class="ft-right">
<ul class="pagination"></ul>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
And this is what the actual PartialView looks like
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<div class="container-1">
<div class="box-img">
<img src="#item.ProductImage" />
</div>
<div class="body">
<h3>#item.ItemName</h3>
<p>#item.SubTitle</p>
</div>
<div class="box-button">
<p>#item.SKU</p>
</div>
<div class="box-button">
<p class="mt-3 mr-2">$#item.Price</p>
<button class="btn btn-primary">Export</button>
</div>
</div>
</td>
</tr>
}
</tbody>
And here is where the issue occurs.. When I first load the page, it all works fine, it looks great and it works perfectly, but as soon as it does the first refresh.. Or .load();.. It suddenly stops working correctly, and by that I mean that it doesn't load any <tr> elements.
This is what the DOM looks like when I first load the page and it hasn't refreshed yet, each td contains the div with the class container-1 so it works just fine
And here is what it looks like after the first refresh and every single refresh after that
The jQuery call $('#itemsss').load("/Dashboard/ReturnItems") replaces existing content of the container with new elements - jQuery documentation states it as
.load() sets the HTML contents of the matched elements to the returned data.
Replacing the innerHTML of #itemsss wipes out the table element. Because <tbody>, <tr> and <td> tags are invalid outside a table, the parser ignores them, leaving #itemsss containing <div> elements only, as shown in the second picture.
If successful AJAX calls are intended to update the whole table the server could send complete HTML for the table, which could then be used to replace the content of #itemss, as shown in the post. Since picture 1 shows multiple tbody elements I assume this is not the case.
I tried appending tbody html to the table under different conditions: with or without a header and with or without existing table sections. Warning I am not a jQuery programmer - if useful, integrate and modify as best suited:
"use strict";
function appendTableBody( bodyHTML) {
let previous = $("#foo-filtering > tbody").last();
if( !previous.length) {
previous = $("#foo-table > thead").last();
}
if( previous.length) {
previous.after( bodyHTML);
}
else {
$("#foo-filtering").prepend( bodyHTML)
}
}
appendTableBody("<tbody><tr><td>appended section<\/td><\/tr><\/tbody>", true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- body-html -->
<table id="foo-filtering">
<thead>
<tr><th>Table Header</th></tr>
</thead>
<tbody>
<tr><td>Table section 1</td></tr>
</tbody>
<tbody>
<tr><td>Table section 2</td></tr>
</tbody>
<tfoot>
<tr><th>table footer</th></tr>
</tfoot>
</table>
I didn't try to replace an existing tbody element, but assume it would involve selecting the element and calling the .html() method.

HTML and JS, hide tome table inside divs

I have a code like this:
I have some html code like this:
<div id="mapLegendInside">
<div>
<table>
// code
</table>
<div>
<table class="esriLegendLayerLabel">
// code
</table>
<table class="esriLegendLayer"> <--- I need to hide this table
// code
</table>
<table class="esriLegendLayer">
// code
</table>
</div>
</div>
</div>
I need to set style="display: none" the table that I've pointed, the first one with class="esriLegendLaye. Right now, I can do this:
document.getElementById("mapLegendInside").style["display"] = "none";
And I will hide the whole main div but, how can I pick only the table that I've pointed? Please, I can't add class or id to the tables or divs inside, this code is generated byt an external javascript library, I just need to pick that 2nd table inside the 2nd element (div) inside the div of the main div (haha).
here's a fiddle with that code to play with:
https://jsfiddle.net/pmiranda/coe0wa67/
You can use document.querySelector or querySelectorAll.
// you can use `document.querySelector`
document.querySelector('#mapLegendInside table.esriLegendLayer').style.display = 'none';
// or - use `querySelectorAll`
setTimeout(() =>
document.querySelectorAll('#mapLegendInside table.esriLegendLayer')[0].style.display = 'block', 1000);
<div id="mapLegendInside">
<div>
<table>
<tr>
<td>Code</td>
</tr>
</table>
<div>
<table class="esriLegendLayerLabel">
<tr>
<td>Code - table.esriLegendLayerLabel</td>
</tr>
</table>
<table class="esriLegendLayer">
<tr>
<td>Code of the table that I need to hide</td>
</tr>
</table>
<table class="esriLegendLayer">
<tr>
<td>Code - table.esriLegendLayer</td>
</tr>
</table>
</div>
</div>
</div>
See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
An example for you would be
var layers = document.querySelectorAll('.esriLegendLayer');
Layers will be an array of the elements which have the class esriLegendLayer, you can change the selector you pass to be more or less specific as you need.
To only change the first you can use
document.querySelector('.esriLegendLayer').style.display = 'none'
You need to keep the table structure. Add tr and td to the table and the following code will work
table example
<table>
<tr>
<td>code</td>
</tr>
</table>
document.querySelectorAll("#mapLegendInside table")[2].style.display = "none";

<tr> dropdown issue in dynamic table. html / php

I am trying to do a drop-down table row beneath another one in a semi auto-generated table. I searched for a bit and learned that you could not animate table elements directly. I tried wrapping my table in a div and the animation worked.
My problem now is that I don't really know how to proceed to make my table with that div while looping on a specific part. It just messes up the table, some way or another.
<body>
<table>
<tbody>
<tr>
// HEAD OF TABLE //
</tr>
{{FOREACH}}
<tr>
// ALWAYS VISIBLE TR //
</tr>
<tr class="hidden hideable{{$i.id}}">
//CONTENTS//
</tr>
{{/FOREACH}}
</tbody>
</table>
$(document).ready(function() {
$(".btn").click(function(e){
e.preventDefault();
var tar = $('.hideable'+$(this).attr('attrib_target'));
tar.slideToggle('slow');
// tar.toggle();
});
});
Where should I open and close the div to have something functional?
EDIT: What I need is basically:
Table header (fixed)
Table Row with basic information (fixed)
Table Row hidden with more info (togglable)
The problem I have is the loop because I need to wrap the hidden table row inside a div AND a table (otherwise, the div is just ejected from the table because of their property). the loop keeps messing with my different attemps at doing it right to be able to animate the hidden part.
Thanks.
Any part of table elements, be it <tr> or <tbody> do not hide the overflowing content if the set height is less than the actual height of the contents. That's why the animations don't work with table elements. I would advise to wrapping your content inside a <div> and using slideToggle to animate.
Please check the code below:
$(document).ready(function() {
$(".btn").click(function(e) {
e.preventDefault();
var tar = $('.hideable' + $(this).attr('data-target'));
tar.slideToggle('slow');
// tar.toggle();
});
});
.hidden {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>
// HEAD OF TABLE //
</th>
</tr>
</thead>
<tbody>
<!-- {{FOREACH}} -->
<!-- FOREACH ITERATION 1 -->
<tr>
<td>
// ALWAYS VISIBLE TR //
<button type="button" class="btn" data-target="1">Show</button>
</td>
</tr>
<tr>
<td>
<div class="hidden hideable1">
//CONTENTS//
</div>
</td>
</tr>
<!-- END: FOREACH ITERATION 1 -->
<!-- FOREACH ITERATION 2 -->
<tr>
<td>
// ALWAYS VISIBLE TR //
<button type="button" class="btn" data-target="2">Show</button>
</td>
</tr>
<tr class="">
<td>
<div class="hidden hideable2">
//CONTENTS//
</div>
</td>
</tr>
<!-- END: FOREACH ITERATION 2 -->
<!-- {{/FOREACH}} -->
</tbody>
</table>

javascript - Slider filtering table numeric column

I am trying to add a slider on my page which is filtering a specific numeric column,of a specific class of a specific class table.
I have tried to correct and make modifications of many existing example1,example2 ... without success.
I use Zurb-Foundation slider. Slider works for now, but it is not linked with anything of my page(not useful at all). Here is the HTML for the slider ;
<div class="large-9 columns">
<div class="slider" data-slider data-initial-start="0.5" data-end="1" data-step="0.05" id="slider-filter">
<span class="slider-handle" data-slider-handle role="slider" tabindex="1" aria-controls="sliderOutput1"></span>
<span class="slider-fill" data-slider-fill></span>
</div>
</div>
<div class="small-3 columns">
<input type="number" id="slider-number">
</div>
According to the Foundation doc and examples above, here is my JS :
$(document).ready(function () {
$(function () {
$("#slider-filter").slider({
slide: function (event, ui) {
// in this function we can define what happens when a user changes the sliders
console.log("Slider is moving");
}
})
})
})
I am failing already at this part, of detecting my slider movement... I also tried according to the doc this line(var elem = new Foundation.Slider(element, options);) in order to use within the .slide()... no success.
Table example :
<table id="Table-to-filter">
<tr>
<td>First Column</td>
<td>Second Column</td>
<td>Third Column</td>
</tr>
<tr class="Prt">
<td>XXXX</td>
<td>23</td>
<td>XXXX</td>
</tr>
<tr class="Chi-to-filter">
<td>XXXX</td>
<td>51</td>
<td>XXXX</td>
</tr>
<tr class="Chi-to-filter">
<td>XXXX</td>
<td>77</td>
<td>XXXX</td>
</tr>
<tr class="Prt">
<td>XXXX</td>
<td>215</td>
<td>XXXX</td>
</tr>
<tr class="Chi-to-filter">
<td>XXXX</td>
<td>450</td>
<td>XXXX</td>
</tr>
<tr class="Chi-to-filter">
<td>XXXX</td>
<td>450</td>
<td>XXXX</td>
</tr>
Any detailed help would be more than appreciated to solve this problem using Foundation slider.
Thank you.
After Nowres Rafed's response :
FILTERING OF BIGDATA TABLE
After many tries, here is what I have been able to do. I have explications and questions about my code.
As you can see, my table is organised with this structure, an expandable parent row that gives many child rows if you click on arrow icon. I would like to use the slider to filter the "Score" column of both parent and child rows. My score is stored on a "accordion menu", not on a simple <td>.
I was wondering is there a better way to filter only the Score column ? I used the row.cells indice, does it change the speed to do it with the row.cells name (i.e "Score") ? Do you think I used the correct way to acces to my score value, using : $(colx.getElementsByClassName("accordion-title")).html();
Moreover, I divided the filtering of parent and child rows on two different loops, is it possible to improve this part ?
Many thanks for your help.
You are initializing the plugin in the wrong way, there is no jQuery plugin called slider in your code.
Here is a working example for your case:
$(function() {
var $filter = $('.slider');
$filter.foundation();
$filter.on('moved.zf.slider', function() {
var slideValue = $('#sliderOutput1').val();
// Do your filtering here
console.log(slideValue);
});
});
Live: https://codepen.io/anon/pen/VbYZgO
Just add your columns filtering code and it's done.
edited:
I think you can make it simpler: https://codepen.io/anon/pen/Qvjqyo
add score-value class on each accordion-title, you can extend the exemple if you wish to distinguish between child and parent rows...

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