Customize table with jquery - javascript

I want to design a customize table layout. For example after adding data my table is created. Now I am showing column name in one column and column data in another column, I want to add functionality if I drag one row to third column, Then column structure will be modified and that row will be added to new column.
For example: This is my table: jsfiddle.net/x8L57md2/
code:-
<tr>
<td>Name</td>
<td> Ankur </td>
</tr>
<tr>
<td>Address</td>
<td>jaipur</td>
</tr>
<tr>
<td>State</td>
<td> Rajasthan</td>
</tr>
<tr>
<td>Country</td>
<td>India</td>
</tr>
<table>
If I move state column to right side of ankur(name) then another table column will be created and append it to table with data.
Like this: jsfiddle.net/ttzr2ezh/
code:-
<table border="1">
<tr>
<td>Name</td>
<td> Ankur </td>
<td>State</td>
<td> Rajasthan</td>
</tr>
<tr>
<td>Address</td>
<td>jaipur</td>
</tr>
<tr>
<td>Country</td>
<td>India</td>
</tr>
<table>

Dragging tr elements is a little tricky. Here's a modified version of a clever approach from a different post. You can view a fully working JSFiddle here: http://jsfiddle.net/xwyoe0y9/
// make sure you reference jQuery and jQuery UI
$(document).ready(function() {
var dragInfo = {};
$('table.rearrangeable tr').draggable({
helper: 'clone',
start: function(event, ui) {
dragInfo.tr = this;
dragInfo.helper = ui.helper;
}
});
$('table.rearrangeable tr').droppable({
drop: function(event, ui) {
var tr = ui.draggable;
$(this).append(dragInfo.tr.innerHTML);
$(dragInfo.tr).remove();
$(dragInfo.helper).remove();
}
});
});

Look up jQuery UI, there is simple functionality for making a UI item 'sortable'.
With this new library installed you just need to label the rows or individual elements and in Javascript make them 'sortable'.
HTML:
<table>
<tr class='makeSortable'>
<td>Element1-Title</td>
<td>Element1</td>
</tr>
<tr class='makeSortable'>
<td>Element2-Title</td>
<td>Element2</td>
</tr>
<tr class='makeSortable'>
<td>Element3-Title</td>
<td>Element3</td>
</tr>
</table>
Javascript:
$(function() {
$( ".makeSortable" ).sortable();
$( ".makeSortable" ).disableSelection();
});

Related

Add event listener to dynamically create table row

I have a table with ajax call to create rows within the tbody element. I have the table created on the html page.
<table id='mytable'>
<thead>
<tr>
<th>First Col</th>
<th>Second Col</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
My javascript code to attach the event to second cell of each row in tbody
$('#mytable tbody').on( 'click', 'tr td:eq(2)', function() {
console.log($(this).html())
});
This code only works for the second cell of the first row of the tbody. Clicking the second cell of all other rows did not trigger the event. I have to work around this by check the cell index
if (this.cellIndex == 2) console.log($(this).html())
I still want to know how to make the correct selection.
To select the specific td of each row use nth-child() instead of eq():
$('#mytable tbody').on( 'click', 'tr td:nth-child(3)', function() {
console.log($(this).html())
});
You can just have an event listener for the entire table and then test what was clicked. Adding the event listener to the table you don't need to assign it again if the content of the table changes.
Adding a class name can both be useful for the usability (styling the cursor) and easier to find elements using JS.
document.getElementById('mytable').addEventListener('click', e => {
let td = e.target.closest('td[class="clickable"]');
if (td) {
console.log(e.target.innerText, 'was clicked');
}
});
td.clickable {
cursor: pointer;
}
<table id='mytable'>
<thead>
<tr>
<th>First Col</th>
<th>Second Col</th>
</tr>
</thead>
<tbody>
<tr>
<td>First</td>
<td class="clickable">Second 1</td>
</tr>
<tr>
<td>First</td>
<td class="clickable">Second 2</td>
</tr>
<tr>
<td>First</td>
<td class="clickable">Second 3</td>
</tr>
<tr>
<td>First</td>
<td class="clickable">Second 4</td>
</tr>
</tbody>
</table>

click event in js datatables (broken with paging)

I want to have a button with js click in each datatable row, but my code is broken by datatables paging system - default datatable option. Click works only on first datatable page. My only idea is to disable paging and create scrolable datatable, but I would prefer to keep paging for better UX.
Example datatable:
<table id="data_tables">
<thead>
<tr>
<td>Action</td>
<td>Name</td>
<td>Surname</td>
<tr>
</thead>
<tbody>
<!-- Datarow 1 -->
<tr>
<td><input type='button' class='my_button' data-id='1' value='click' /></td>
<td>John</td>
<td>Wayne</td>
</tr>
<!-- Datarow 2 -->
<tr>
<td><input type='button' class='my_button' data-id='2' value='click' /></td>
<td>Clark</td>
<td>Kent</td>
</tr>
</tbody>
</table>
Click event handler
//simple on() in jquery would do the trick in normal <table>
$( ".my_button" ).on( "click", function() {
var id = $(this).attr("data-id");
alert(id);
});
Is there a way to workaround this problem? Or maybe datatable api solution?
You can do something like this:
$("#data_tables").on("click", ".my_button", function() {
var id = $(this).data("id");
alert(id);
});

Substituting DOMSubtreeModified for MutationObserver issues

I am trying to check if new table row(s) <tr> were added to the table like this:
var myTab;e = $('#myTable tbody');
myTab.on("DOMSubtreeModified", function() {
console.log('Row added');
});
But this prints out to console 100's of 'Row added' messages, if for example 10 rows are added to the table simultaneously, even if one of them I't still prints out 'Row added' 10 times. This got me thinking that it is listening to absolutely all changes within myTable which is not what I want. I just want it to execute one time even if 100 rows are added (Rows are added in bulk couple at a time).
I found another solution via: MutationObserver but Can't figure out how to set it up in order to achieve my task (once rows are added to myTable) execute change event one time.
Here is example markup for the table.
<table id="myTable">
<thead>
<tr>
<th>
<div>Date</div>
<span>Time</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content</td>
<td>More content</td>
</tr>
<tr>
<td>Content</td>
<td>More content</td>
</tr>
<!-- etc.. -->
</tbody>
</table>
This is a very simple version of it with things like classes, data attributes, id's and other elements omitted, but should do the trick.
var target = $("#myTable").get(0);
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// do stuff when
// `childList`, `subtree` of `#myTable` modified
alert(mutation.type);
});
});
// configuration of the observer:
var config = { childList: true, subtree:true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
$("#myTable tbody").append("<tr><td>abc</td></tr><tr><td>def</td></tr>")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<th>
<div>Date</div>
<span>Time</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content</td>
<td>More content</td>
</tr>
<tr>
<td>Content</td>
<td>More content</td>
</tr>
<!-- etc.. -->
</tbody>
</table>

handle mdl table check box

I'm using material desigin lite in my website
I have implemented this example:
http://www.getmdl.io/components/index.html#tables-section
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
<td>25</td>
<td>$2.90</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
<td>50</td>
<td>$1.25</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
<td>10</td>
<td>$2.35</td>
</tr>
</tbody>
</table>
my question is how to handle the check box in the table , they are added by the class : .mdl-data-table--selectable
there is no Id or class for them so what is the way to use them in javascript or sql server (deleting rows what i'm trying to implement)
You could check if they're are clicked with a jquery on method, why am not using the normal .click is to because of event delegation. Jquery docs do a perfect job explaining that.
Before I explain how I did it I will have a snippet that you can immediately play with under my explanation.
I basically used inspect element to look at the tables structure and it looked something like this
<tr>
<td>
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td>
<td>25</td>
<td>$2.90</td>
With that information, we can do a lot. I personally used this to listen to clicks.
$(document).on("click",".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() { /* Code here*/ });
And with jquery parents & children methods we can achieve a lot, like read the content of all the table data with the following code in our click event listener
foo = $(this).parents().eq(2).children().text();
Or we can perhaps delete a whole row?
$(this).parents().eq(2).fadeOut();
What that would do is, look at the clicked checkbox using "this" as reference. Then go to levels up and remove a whole row.
<tr><!-- eq 2 -->
<td> <!-- eq 1 -->
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td>
<td>25</td>
<td>$2.90</td>
Or we can check for the content of a specific child like this
var secondChildContent = $(this).parents().eq(2).children().eq(2).text();
Where secondChildContent will be return the content. You can always change the eq (The one after children) value to the desired child number you want. In the following case secondChildContent would return "Acrylic"
<tr>
<td> <!-- eq 1 -->
<label>clickable checkbox code</label>
</td>
<td>Acrylic</td> <!-- eq 2 -->
<td>25</td> <!-- eq 3 -->
<td>$2.90</td> <!-- eq 4 -->
$(document).ready(function() {
$(document).on("click", ".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() {
//Removing row
$(this).parents().eq(2).delay(500).fadeOut(300);
var secondChildContent = $(this).parents().eq(2/*child number*/).children().eq(2).text();
var allChildrenContent = $(this).parents().eq(2).children().text();
var parentID = $(this).parents().eq(2).attr('id');
//Removing table on click of first checkbox
if (parentID == "header") {
$("#mdlTable").fadeOut(1000);
$("#log").html("<b>Table removed!</b>");
} else {
//Don't pay attention to this
$("#log").html(
"<b>Second child content is: </b>" + secondChildContent +
"<br><b>All children content is: </b>" + allChildrenContent
)
}
});
});
#log,
#mdlTable {
margin: 1% 1% 1% 1%;
}
<!DOCTYPE html>
<html>
<head>
<title>Table</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.indigo-pink.min.css">
<script src="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<table id="mdlTable" class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr id="header">
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
<td>25</td>
<td>$2.90</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
<td>50</td>
<td>$1.25</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
<td>10</td>
<td>$2.35</td>
</tr>
</tbody>
</table>
<div id="log"></div>
</body>
When a checkbox is selected, the tr gets the class "is-checked" with Material Design Lite.
So your jquery can be like this:
$("table").find("tr.is-checked").each(function(){
// Do some stuff!
});
Update: Just read that the class "mdl-data-table--selectable " is being deprecated... This is the article on github
You can use this OnClick API function.
It uses like Android onClickListener, but it is for JavaScript.
TablesOnClickListener = function() {
var fun;
this.setOnClickListener = function(listener) {
fun = listener;
$(document).on("click", ".mdl-checkbox__ripple-container.mdl-js-ripple-effect.mdl-ripple--center", function() {
//$(this).parents().eq(2).delay(500).fadeOut(300);
var secondChildContent = $(this).parents().eq(2 /*child number*/ ).children().eq(2).text();
var allChildrenContent = $(this).parents().eq(2).children().text();
var parentID = $(this).parents().eq(2).attr('id');
fun({
sen: secondChildContent,
text: allChildrenContent,
id: parentID
});
});
}
How to use:
Step 1: create new TablesOnClickListener
var tocl = new TablesOnClickListener()
Step 2: set Item OnClickListener
tocl.setOnClickListener(function(data){
console.log(data);
});
Now your Tables Item Listener are all set!

Get row elements without using "closest" selector - jquery javascript

I have a table with 4 columns . 4th column is a button (not shown in below code). When I click on the button in a row, I want to get row elements.
I have done it using closest selector. Is there any way to find table row element "Without using closest". This is the requirement for some reason.
Please assume there is a button at end of each row
<table id="food">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class='details'>
<td>1</td>
<td>Apple</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>2</td>
<td>Mango</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>3</td>
<td>Grape</td>
<td>Fruit</td>
</tr>
</tbody>
</table>
Here is the existing code, I need to replace closest. It will be awesome if I can use class names like $(this).somethin('.details');
$('#button1').click(function(){
var row = $(this).closest('tr');
//Do some stuff
})
Thanks
Use parents() and pass a class selector like
$('#button1').click(function(){
var row = $(this).parents('.details');
//Do some stuff
})
Note, you could also use closest in this case and pass the class selector
var row = $(this).closest('.details');

Categories