Popover menu in VueJS without JQuery? - javascript

In this answer is there exactly what I am looking for. A menu pops up, when clicking on a table row. The only problem is it uses JQuery...
So my question is, can the same be done without JQuery? Perhaps with VueJS, which I am using?

Translated the example
let rows = document.querySelectorAll("tr");
let btnPane = document.getElementById("button-pane");
document.active = '';
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
btnPane.addEventListener("mouseover", function() {
btnPane.style.display = "block";
if(document.active)
document.active.style.backgroundColor = "lightblue";
});
btnPane.addEventListener("mouseleave", function() {
btnPane.style.display = "none";
if(document.active)
document.active.style.backgroundColor = "";
});
rows.forEach(function(row) {
row.addEventListener("click", function(e) {
var posLeft = e.clientX + 10;
var posBottom = this.offsetTop + this.offsetHeight+8;
btnPane.style.top = posBottom + "px";
btnPane.style.left = posLeft + "px";
btnPane.style.display = "block";
document.active = this;
});
row.addEventListener("mouseleave", function() {
btnPane.style.display = "none";
});
});
table {
border-collapse: collapse;
}
th, td{
border-bottom: 1px solid #aaa;
}
#mytable tbody tr:hover {
background-color: lightblue;
}
.button-pane {
display: none;
position: absolute;
float: left;
top: 0px;
left: 0px;
background-color: lightblue;
width: 150px;
height: 30px;
padding: 0px;
text-align: center;
}
.button-pane button {
display: inline;
cursor: pointer;
}
<table id="mytable" border="1" width="100%">
<thead>
<tr>
<td>HEADER 1</td>
<td>HEADER 2</td>
<td>HEADER 3</td>
<td>HEADER 4</td>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>a</td>
<td>aa</td>
<td>aaa</td>
</tr>
<tr>
<td>Item 2</td>
<td>b</td>
<td>bb</td>
<td>bbb</td>
</tr>
<tr>
<td>Item 3</td>
<td>c</td>
<td>cc</td>
<td>ccc</td>
</tr>
</tbody>
</table>
<div id="button-pane" class="button-pane">
<button id="button1">Button 1</button>
<button id="button2">Button 2</button>
</div>
</div>

Related

How to select items using a input checkbox?

This is my code snippet, I want to display the difference of two selected columns and create a new table with columns selected and difference along as a column. I am not getting how can I select table columns with the help of checkbox (basically bind the checkbox with table columns). I cant find anything on Stack Overflow or any other site for the reference.
Edit: I have added the JS code for getting the column data corresponding to that particular header, right now I am hard coding it to header "Three". How can I pick the particular column data bind to the input checkbox clicked?
columnTh = $("table th:contains('Three')");
columnIndex = columnTh.index() + 1;
let arr = [];
alert(columnIndex)
arr = $('table tr td:nth-child(' + columnIndex + ')').text()
alert(arr)
table {
border: 1px solid white;
text-align: center;
padding: 6px;
background: #e1edf9;
}
td {
border: 1px solid white;
text-align: center;
padding: 6px;
}
td:first-child,
tr:first-child {
background-color: #003a6a !important;
color: white !important;
}
.table-scroll {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
}
.table-scroll table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-scroll tr:first-child {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
.table-scroll tfoot tr {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
tr:first-child {
z-index: 5;
}
#media screen and (max-width: 500px) {
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
max-width: 140px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table-scroll" class="table-scroll">
<table id="main-table" class="main-table">
<tbody>
<tr>
<th>One</th>
<th>Two <input type="checkbox" id="c2" value="on" name="cb2"/></th>
<th>Three<input type="checkbox" id="c3" value="on" name="cb3"/></th>
<th>Four<input type="checkbox" id="c4" value="on" name="cb4"/></th>
<th>Five<input type="checkbox" id="c5" value="on" name="cb5"/></th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>21</td>
<td>2</td>
<td>93</td>
<td>74</td>
<td>85</td>
</tr>
<tr>
<td>21</td>
<td>32</td>
<td>93</td>
<td>24</td>
<td>15</td>
</tr>
<tr>
<td>91</td>
<td>72</td>
<td>13</td>
<td>14</td>
<td>85</td>
</tr>
<tr>
<td>411</td>
<td>422</td>
<td>423</td>
<td>144</td>
<td>145</td>
</tr>
<tr>
<td>151</td>
<td>522</td>
<td>93</td>
<td>54</td>
<td>515</td>
</tr>
<tr>
<td>610</td>
<td>621</td>
<td>363</td>
<td>464</td>
<td>65</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>13</td>
<td>41</td>
<td>5</td>
</tr>
<tr>
<td>11</td>
<td>120</td>
<td>143</td>
<td>214</td>
<td>5</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td>31</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
</tr>
<tr>
<td>41</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
</tr>
<tr>
<td>51</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
</tr>
<tr>
<td>61</td>
<td>62</td>
<td>63</td>
<td>64</td>
<td>65</td>
</tr>
</tbody>
</table>
</div>
I don't know how you want to display the difference, but this might get you started:
const table = document.getElementById("main-table"),
checkboxes = table.querySelectorAll('th > input[type="checkbox"]');
let columns = {};
for(let i = 0; i < checkboxes.length; i++)
{
checkboxes[i].addEventListener("input", onInput);
}
function onInput(e)
{
const input = e.target,
column = input.parentNode.cellIndex,
tds = table.querySelectorAll('td:nth-child(' + (column + 1) + ')');
if (input.checked)
{
let list = [];
for(let i = 0; i < tds.length; i++)
{
list[list.length] = tds[i].textContent;
}
columns[column] = list;
}
else
{
delete columns[column];
}
if (Object.keys(columns).length > 1)
showDifference();
else
table.classList.remove("result");
}
function showDifference()
{
table.classList.add("result");
let cells = table.getElementsByClassName("result"),
trs = table.querySelectorAll("tr");
if (!cells.length)
{
cells = [];
for(let i = 0, cell; i < trs.length; i++)
{
cell = document.createElement(i ? "td" : "th");
if (!i)
cell.textContent = "Results";
cell.className = "result";
cells[cells.length] = cell;
trs[i].appendChild(cell);
}
}
let dif = [];
for(let r in columns)
{
for(let i = 0; i < columns[r].length; i++)
{
if (dif[i] === undefined)
dif[i] = [];
dif[i][dif[i].length] = columns[r][i];
}
}
for(let i = 0; i < dif.length; i++)
{
cells[i+1].textContent = dif[i];
}
}
table {
border: 1px solid white;
text-align: center;
padding: 6px;
background: #e1edf9;
}
td {
border: 1px solid white;
text-align: center;
padding: 6px;
}
td:first-child,
tr:first-child {
background-color: #003a6a !important;
color: white !important;
}
.table-scroll {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
}
.table-scroll table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-scroll tr:first-child {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
.table-scroll tfoot tr {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
tr:first-child {
z-index: 5;
}
#media screen and (max-width: 500px) {
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
max-width: 140px;
}
}
.main-table:not(.result) th.result,
.main-table:not(.result) td.result
{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table-scroll" class="table-scroll">
<table id="main-table" class="main-table">
<tbody>
<tr>
<th>One</th>
<th>Two <input type="checkbox" id="c2" value="on" name="cb2"/></th>
<th>Three<input type="checkbox" id="c3" value="on" name="cb3"/></th>
<th>Four<input type="checkbox" id="c4" value="on" name="cb4"/></th>
<th>Five<input type="checkbox" id="c5" value="on" name="cb5"/></th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>21</td>
<td>2</td>
<td>93</td>
<td>74</td>
<td>85</td>
</tr>
<tr>
<td>21</td>
<td>32</td>
<td>93</td>
<td>24</td>
<td>15</td>
</tr>
<tr>
<td>91</td>
<td>72</td>
<td>13</td>
<td>14</td>
<td>85</td>
</tr>
<tr>
<td>411</td>
<td>422</td>
<td>423</td>
<td>144</td>
<td>145</td>
</tr>
<tr>
<td>151</td>
<td>522</td>
<td>93</td>
<td>54</td>
<td>515</td>
</tr>
<tr>
<td>610</td>
<td>621</td>
<td>363</td>
<td>464</td>
<td>65</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>13</td>
<td>41</td>
<td>5</td>
</tr>
<tr>
<td>11</td>
<td>120</td>
<td>143</td>
<td>214</td>
<td>5</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td>31</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
</tr>
<tr>
<td>41</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
</tr>
<tr>
<td>51</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
</tr>
<tr>
<td>61</td>
<td>62</td>
<td>63</td>
<td>64</td>
<td>65</td>
</tr>
</tbody>
</table>
</div>

:nth-child(even) selector by class with specific elements [duplicate]

This question already has answers here:
Excluding an element from nth-child pattern
(5 answers)
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Closed 2 years ago.
I have a table that has a light gray background for the even rows and white for the odd ones. it works perfectly by using .tr:nth-child(even) {}
HTML
<table>
<tr></tr>
<tr class="hidden"></tr>
<tr class="hidden"></tr>
<tr></tr>
</table>
CSS
tbody tr:nth-of-type(even) {
background-color: var(--bg);
}
I made a search field that filters table rows by adding hidden class for tr elements that not match after that the tr:nth-child(even) doesn't work.
I tried to add search-result class on the elements that match and then I made tr:nth-of-type(even) { .... }, also that not worked.
Is there any way that I can do that? for example, a way to select even elements by class?
Fixed version of the codepen in the comments using a variant of the proof of concept I have at the bottom. Count up indexes to check if even, excluding elements with display:none, done every update. This may need to be optimized for very large tables.
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("input");
filter = input.value.toUpperCase();
table = document.getElementById("table");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
//let table = document.getElementsByTagName('table')[0]
(function(){
let i = 0
table.querySelectorAll('tr:not(.hidden)').forEach(el =>
el.style.display !== 'none' && i++ % 2 === 0 ? el.classList.add('even') : el.classList.remove('even'))
})()
}
* {
box-sizing: border-box;
}
#input {
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#table {
list-style-type: none;
padding: 0;
margin: 0;
width: 100%;
}
#table tr {
border: 1px solid #ddd;
margin-top: -1px;
background-color: #fff;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
}
#table th, #table td {
text-align: left;
padding: 12px;
}
#table tr :not(td) {
background-color: #424242;
color: white;
}
#table tr:not(.even) {
background-color: #eee!important;
}
<input type="text" id="input" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="table">
<tr>
<th style="width:60%;">Name</th>
<th style="width:40%;">Age</th>
</tr>
<tr>
<td>Adam</td>
<td>22</td>
</tr>
<tr>
<td>malik</td>
<td>40</td>
</tr>
<tr>
<td>Asal</td>
<td>32</td>
</tr>
<tr>
<td>Asal</td>
<td>26</td>
</tr>
<tr>
<td>Asali</td>
<td>40</td>
</tr>
<tr>
<td>malik</td>
<td>40</td>
</tr>
<tr>
<td>maaaalik</td>
<td>40</td>
</tr>
</table>
select non-hidden and use counter to find even. add class.
let table = document.getElementsByTagName('table')[0]
let i = 0
table.querySelectorAll('tr:not(.hidden)').forEach(el =>
i++ % 2 === 0 && el.classList.add('even'))
.even {
background-color: red;
}
.hidden {
opacity: 0.2;
}
<table>
<tr>
<td>1</td>
</tr>
<tr class="hidden">
<td>2</td>
</tr>
<tr class="hidden">
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr class="hidden">
<td>2</td>
</tr>
<tr class="hidden">
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr class="hidden">
<td>2</td>
</tr>
<tr class="hidden">
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr class="hidden">
<td>2</td>
</tr>
<tr class="hidden">
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>

Javascript - Expand/Collapse table rows

Given the following table/code, I'd like to add two items. I don't know JavaScript well enough and this code was left by another programmer. The code works as expected in every other way.
Here are the two items:
The table should start in a collapsed state. All nodes should be
collapsed to the 'Grandparent' level.
There should be a link for 'expand all' and a separate 'collapse all' link.
Here is the table I'm using:
$(function() {
$('#mytable').on('click', '.toggle', function () {
var findChildren = function (tr) {
var depth = tr.data('depth');
return tr.nextUntil($('tr').filter(function () {
return $(this).data('depth') <= depth;
}));
};
var el = $(this);
var tr = el.closest('tr');
var children = findChildren(tr);
var subnodes = children.filter('.expand');
subnodes.each(function () {
var subnode = $(this);
var subnodeChildren = findChildren(subnode);
children = children.not(subnodeChildren);
});
if (tr.hasClass('collapse')) {
tr.removeClass('collapse').addClass('expand');
children.hide();
} else {
tr.removeClass('expand').addClass('collapse');
children.show();
}
return children;
});
});
table td, th {
border: 1px solid #eee;
font-family: Arial;
font-size: 16px;
}
.level0 td:first-child {
padding-left: 5px;
}
.level1 td:first-child {
padding-left: 25px;
}
.level2 td:first-child {
padding-left: 50px;
}
.level3 td:first-child {
padding-left: 75px;
}
.collapse .toggle {
background: url("open.gif");
background-repeat: no-repeat;
}
.expand .toggle {
background: url("closed.gif");
background-repeat: no-repeat;
}
.toggle {
height: 20px;
width: 20px;
display: inline-block;
}
.age {
text-align: center;
}
.nam {
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="mytable" style="border-collapse: collapse" cellpadding="6">
<thead>
<tr>
<th width="250px">Type</th>
<th width="50px">Age</th>
<th width="50px">Name</th>
</tr>
</thead>
<tr data-depth="0" class="collapse level0">
<td><span class="toggle collapse"></span>GRANDPARENT</td>
<td class="age">80</td>
<td class="nam">Ethel</td>
</tr>
<tr data-depth="1" class="collapse level1">
<td><span class="toggle"></span>CHILD 1</td>
<td class="age">55</td>
<td class="nam">Susan</td>
</tr>
<tr data-depth="2" class="collapse level2">
<td><span class="toggle collapse"></span>GRANDCHILD 1</td>
<td class="age">32</td>
<td class="nam">Kristen</td>
</tr>
<tr data-depth="3" class="collapse collapsable level3">
<td>GREAT GRANCHILD 1</td>
<td class="age">12</td>
<td class="nam">Layla</td>
</tr>
<tr data-depth="1" class="collapse collapsable level1">
<td><span class="toggle collapse"></span>CHILD 2</td>
<td class="age">52</td>
<td class="nam">Joanne</td>
</tr>
<tr data-depth="2" class="collapse collapsable level2">
<td><img src="list.gif"/>GRANDCHILD 2</td>
<td class="age">28</td>
<td class="nam">Marie</td>
</tr>
</table>
What do I need to add to the JavaScript to accomplish this?
Is this the kind of result you want ?
(I played a little with your code to make it work more or less like I think it should.)
Anyway, I don't understand all about what has been done, and I propose you only a JS solution.
But… I think the classes in your trs could be modified to get your “all hidden” result at the loading of the page without using any JS.
I commented where I added the new things:
EDIT: And I cleaned a little the code, too.
$('.collapse').on('click', function() {
//console.log($(this).attr('data-depth'));
var findChildren = function(tr) {
var depth = tr.data('depth');
return tr.nextUntil($('tr').filter(function() {
return $(this).data('depth') <= depth;
}));
};
var children = findChildren($(this));
if ($(children).is(':visible')) {
$(this).addClass("closed");
$(children).hide();
} else {
$(this).removeClass("closed");
$(children).show();
var children = findChildren($(".closed"));
$(children).hide();
}
});
// HERE IS THE CODE I ADDED
$('#show_all').on('click', function() {
$("#mytable tr.collapse").removeClass("closed").show();
});
$('#hide_all').on('click', function() {
$("#mytable tr.collapse:not([data-depth='0'])").hide();
$("#mytable tr.collapse.level0").addClass("closed");
});
$(document).ready(function() {
$('#hide_all').trigger('click');
});
table td,
th {
border: 1px solid #eee;
font-family: Arial;
font-size: 16px;
}
.level0 td:first-child {
padding-left: 10px;
}
.level1 td:first-child {
padding-left: 30px;
}
.level2 td:first-child {
padding-left: 50px;
}
.level3 td:first-child {
padding-left: 70px;
}
.age {
text-align: center;
}
.nam {
text-align: left;
}
.closed td:first-child::before {
content: "• ";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- HERE IS THE HTML I ADDED FOR THE BUTTONS -->
<button id="show_all"><p>Show all</p></button>
<button id="hide_all"><p>Hide all</p></button>
<!-- END -->
<table id="mytable" style="border-collapse: collapse" cellpadding="6">
<thead>
<tr>
<th width="250px">Type</th>
<th width="50px">Age</th>
<th width="50px">Name</th>
</tr>
</thead>
<tr data-depth="0" class="collapse level0">
<td>GRANDPARENT</td>
<td class="age">80</td>
<td class="nam">Ethel</td>
</tr>
<tr data-depth="1" class="collapse level1">
<td>CHILD 1</td>
<td class="age">55</td>
<td class="nam">Susan</td>
</tr>
<tr data-depth="2" class="collapse level2">
<td>GRANDCHILD 1</td>
<td class="age">32</td>
<td class="nam">Kristen</td>
</tr>
<tr data-depth="3" class="collapse level3">
<td>GREAT GRANCHILD 1</td>
<td class="age">12</td>
<td class="nam">Layla</td>
</tr>
<tr data-depth="1" class="collapse level1">
<td>CHILD 2</td>
<td class="age">52</td>
<td class="nam">Joanne</td>
</tr>
<tr data-depth="2" class="collapse level2">
<td>GRANDCHILD 2</td>
<td class="age">28</td>
<td class="nam">Marie</td>
</tr>
</table>
And here is the snippet before my last edition, in case the “cleaned” one doesn't fit your needs:
$('.collapse').on('click', function() {
//console.log($(this).attr('data-depth'));
var findChildren = function(tr) {
var depth = tr.data('depth');
return tr.nextUntil($('tr').filter(function() {
return $(this).data('depth') <= depth;
}));
};
var children = findChildren($(this));
if ($(children).is(':visible')) {
$(children).hide();
} else {
$(children).show();
}
});
// HERE IS THE CODE I ADDED
$('#show_all').on('click', function() {
$("#mytable tr.collapse:not([data-depth='0'])").show();
});
$('#hide_all').on('click', function() {
$("#mytable tr.collapse:not([data-depth='0'])").hide();
});
$(document).ready(function() {
$('#hide_all').trigger('click');
});
table td,
th {
border: 1px solid #eee;
font-family: Arial;
font-size: 16px;
}
.level0 td:first-child {
padding-left: 5px;
}
.level1 td:first-child {
padding-left: 25px;
}
.level2 td:first-child {
padding-left: 50px;
}
.level3 td:first-child {
padding-left: 75px;
}
.collapse .toggle {
background: url("open.gif");
background-repeat: no-repeat;
}
.expand .toggle {
background: url("closed.gif");
background-repeat: no-repeat;
}
.toggle {
height: 20px;
width: 20px;
display: inline-block;
}
.age {
text-align: center;
}
.nam {
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- HERE IS THE HTML I ADDED -->
<button id="show_all"><p>Show all</p></button>
<button id="hide_all"><p>Hide all</p></button>
<!-- END -->
<table id="mytable" style="border-collapse: collapse" cellpadding="6">
<thead>
<tr>
<th width="250px">Type</th>
<th width="50px">Age</th>
<th width="50px">Name</th>
</tr>
</thead>
<tr data-depth="0" class="collapse level0">
<td><span class="toggle collapse"></span>GRANDPARENT</td>
<td class="age">80</td>
<td class="nam">Ethel</td>
</tr>
<tr data-depth="1" class="collapse level1">
<td><span class="toggle"></span>CHILD 1</td>
<td class="age">55</td>
<td class="nam">Susan</td>
</tr>
<tr data-depth="2" class="collapse level2">
<td><span class="toggle collapse"></span>GRANDCHILD 1</td>
<td class="age">32</td>
<td class="nam">Kristen</td>
</tr>
<tr data-depth="3" class="collapse collapsable level3">
<td>GREAT GRANCHILD 1</td>
<td class="age">12</td>
<td class="nam">Layla</td>
</tr>
<tr data-depth="1" class="collapse collapsable level1">
<td><span class="toggle collapse"></span>CHILD 2</td>
<td class="age">52</td>
<td class="nam">Joanne</td>
</tr>
<tr data-depth="2" class="collapse collapsable level2">
<td><img src="list.gif" />GRANDCHILD 2</td>
<td class="age">28</td>
<td class="nam">Marie</td>
</tr>
</table>

How to convert jquery code into a reusable plugin/function

I have created a bootstrap datatable like string and its working perfect but i am defining the table in my code only. I want to write it like plugins.
I want to call the function only when i call it like this $('table').newDataTable() but write now i reached this
$(document).ready(function() {
var showInterval = 10;
var showCount = showInterval;
var startCount = 0;
$('table tbody tr').hide();
$('table tbody tr').slice(startCount, showCount).show();
$('.top_div_left select').on('change', function() {
var showCount = $(this).val();
$('table tbody tr').hide();
$('table tbody tr').slice(startCount, showCount).show();
});
$('.top_div_right input').on('input propertychange', function() {
var showCount = $('.top_div_left select').val();
var thisText = $(this).val().trim().toLowerCase();
var i;
if (thisText == "") {
$('table tbody tr').hide();
$('table tbody tr').slice(startCount, showCount).show();
} else {
var trLength = $('table tbody tr').slice(startCount, showCount).length;
$('table tbody tr').slice(startCount, showCount).each(function() {
var rowText = $(this);
if (rowText.text().toLowerCase().indexOf(thisText) == -1) {
$(this).hide();
} else {
$(this).show();
};
});
};
});
var totalRows = $('table tbody tr').length;
var pagiLength = Math.ceil(totalRows / showCount);
for (var i = 1; i <= pagiLength; i++) {
$('.pagination ul li.right').before('<li class="page">' + i + '</li>');
};
$('.pagination ul li.page').eq($('table').attr('data-page') - 1).addClass('active');
$(document).on('click', '.pagination ul li.page a', function(e) {
e.preventDefault();
$('.pagination ul li').removeClass('active');
$(this).parent('li').addClass('active');
var newPage = $(this).text();
showCount = showInterval * newPage;
startCount = showCount - showInterval;
$('table tbody tr').hide();
$('table tbody tr').slice(startCount, showCount).show();
});
$('.pagination ul li.left a').on('click', function(e) {
e.preventDefault();
$('.pagination ul li.page.active').prev('li.page').find('a').trigger('click');
});
$('.pagination ul li.right a').on('click', function(e) {
e.preventDefault();
$('.pagination ul li.page.active').next('li.page').find('a').trigger('click');
});
});
.clear {
clear: both;
}
table {
border-collapse: collapse;
border: 1px solid #ccc;
width: 600px;
margin: 0 auto;
text-align: left;
}
table tr td,
table tr th {
padding: 7px 10px;
}
.top_div {
width: 600px;
margin: 0 auto 10px;
}
.top_div .top_div_left {
float: left;
}
.top_div .top_div_left select {
width: 100%;
border: 1px solid #ccc;
border-radius: 7px;
height: 30px;
padding: 0 10px;
box-sizing: border-box;
outline: none;
}
.top_div .top_div_right {
float: right;
}
.top_div .top_div_right input {
width: 100%;
border: 1px solid #ccc;
border-radius: 7px;
height: 30px;
padding: 0 10px;
box-sizing: border-box;
outline: none;
}
.pagination {
width: 600px;
margin: 10px auto 0;
text-align: right;
}
.pagination ul {
font-size: 0;
border: 1px solid #ccc;
border-radius: 5px;
padding: 0;
float: left;
overflow: hidden;
}
.pagination ul li {
list-style: none;
display: inline-block;
font-size: 16px;
border-right: 1px solid #ccc;
}
.pagination ul li:last-child {
border: none;
}
.pagination ul li a {
padding: 6px 12px;
display: block;
color: #000;
text-decoration: none;
}
.pagination ul li.active a,
.pagination ul li:hover a {
background: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="top_div">
<div class="top_div_left">
<select>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
<div class="top_div_right">
<input type="text">
</div>
<div class="clear"></div>
</div>
<table cellpadding="0" cellspacing="0" border="1" data-page="1">
<thead>
<tr>
<th>S.No</th>
<th>Name</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Gaurav Aggarwal</td>
<td>First</td>
</tr>
<tr>
<td>2</td>
<td>Anurag Verma</td>
<td>Second</td>
</tr>
<tr>
<td>3</td>
<td>Ankit</td>
<td>Third</td>
</tr>
<tr>
<td>4</td>
<td>Abhishek</td>
<td>Fourth</td>
</tr>
<tr>
<td>5</td>
<td>Niharika</td>
<td>Fifth</td>
</tr>
<tr>
<td>6</td>
<td>Nidhi</td>
<td>Six</td>
</tr>
<tr>
<td>7</td>
<td>Rashmi</td>
<td>Seven</td>
</tr>
<tr>
<td>8</td>
<td>Deepti</td>
<td>Eighth</td>
</tr>
<tr>
<td>9</td>
<td>Neha</td>
<td>Nineth</td>
</tr>
<tr>
<td>10</td>
<td>Shruti</td>
<td>Tenth</td>
</tr>
<tr>
<td>11</td>
<td>Gaurav Aggarwal</td>
<td>First</td>
</tr>
<tr>
<td>12</td>
<td>Anurag Verma</td>
<td>Second</td>
</tr>
<tr>
<td>13</td>
<td>Ankit</td>
<td>Third</td>
</tr>
<tr>
<td>14</td>
<td>Abhishek</td>
<td>Fourth</td>
</tr>
<tr>
<td>15</td>
<td>Niharika</td>
<td>Fifth</td>
</tr>
<tr>
<td>16</td>
<td>Nidhi</td>
<td>Six</td>
</tr>
<tr>
<td>17</td>
<td>Rashmi</td>
<td>Seven</td>
</tr>
<tr>
<td>18</td>
<td>Deepti</td>
<td>Eighth</td>
</tr>
<tr>
<td>19</td>
<td>Neha</td>
<td>Nineth</td>
</tr>
<tr>
<td>20</td>
<td>Shruti</td>
<td>Tenth</td>
</tr>
<tr>
<td>21</td>
<td>Gaurav Aggarwal</td>
<td>First</td>
</tr>
<tr>
<td>22</td>
<td>Anurag Verma</td>
<td>Second</td>
</tr>
</tbody>
</table>
<div class="pagination">
<ul>
<li class="left">«
</li>
<li class="right">»
</li>
</ul>
</div>
I won't update the entire code but explain how to decouple the table from your code. Lets cut down the entire example to just one requirement - Display number of rows selected in the dropdown.
Use JavaScript namespacing to separate your plugin. Pass a generic table object and necessary parameters to the plugin. Idea is to make the function work on any kind of table.
Many times plugins take json object as a parameter. Usually when the input parameters grow large.
$(document).ready(function() {
var showInterval = 5;
var showCount = showInterval;
var startCount = 0;
$('.top_div_left select').on('change', function() {
showCount = $(this).val();
mytableFilter.filter("#mytable", showCount);
});
mytableFilter.filter("#mytable", showCount);
});
(function (mytableFilter, $, undefined) {
mytableFilter.filter = function(tableSelector, count) {
$(tableSelector).find('tbody tr').hide();
$(tableSelector).find('tbody tr').slice(0, count).show();
};
}(window.mytableFilter = window.mytableFilter || {}, jQuery));
JSFiddle
Jquery Plugin Tutorial

Hide/Show HTML tables [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an HTML document which contains tables. Some tables are subtables of other ones. You can have an example here:
HTML :
<table class='top'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>A</td>
</tr>
</table>
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>B</td>
</tr>
</table>
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>C</td>
</tr>
</table>
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>D</td>
</tr>
</table>
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>E</td>
</tr>
</table>
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>F</td>
</tr>
</table>
<table class='top'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>G</td>
</tr>
</table>
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>H</td>
</tr>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>I</td>
</tr>
</table>
CSS :
table {
border-collapse: collapse;
border-width: 0px 0;
box-shadow: 3px 3px 4px #AAA;
}
.greyrow{
background-color: #c7c7c7;
font-size: 16px;
text-align: center;
color: black;
font-family: Verdana;
}
td{
width: 100px;
}
.top{
margin-bottom: 10px;
}
.sub1{
display: none;
margin-left: 20px;
margin-bottom: 10px;
}
.sub2{
display: none;
margin-left: 40px;
margin-bottom: 10px;
}
I would like to have only the toplevel tables displayed as default. This can be done with the css property "display: none".
I would like to show the subtables when the user clicks on the upper level table. Any existing jquery script for this ?
Here, I've created a jsfiddle with what you're asking for. You can create as many subtables as you could possibly want, this code will still work, and it's light on the fiddle.
HTML edit: I've surrounded the table you're cascading from, and the tables being cascaded from it in a div tag with the class ". clickable" <div class="clickable">...</div>
CSS edit: I've set all ".clickable" children with the same class (.clickable>.clickable{...}) to display:none;
JS edit: The code is activated when you click on the immediate child table element. It then gets that table's parent and finds its immediate child with the ".clickable" class and slideToggles it (you can set a different effect if you'd like, I assumed that this was the look you wanted)
HTML
<div class="clickable">
<table class='top'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>A</td>
</tr>
</table>
<div class="clickable">
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>B</td>
</tr>
</table>
<div class="clickable">
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>C</td>
</tr>
</table>
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>D</td>
</tr>
</table>
</div>
</div>
<div class="clickable">
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>E</td>
</tr>
</table>
<div class="clickable">
<table class='sub2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>F</td>
</tr>
</table>
</div>
</div>
</div>
<div class="clickable">
<table class='top'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>G</td>
</tr>
</table>
<div class="clickable">
<table class='sub1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>H</td>
</tr>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>I</td>
</tr>
</table>
</div>
</div>
CSS
table {
border-collapse: collapse;
border-width: 0px 0;
box-shadow: 3px 3px 4px #AAA;
}
.greyrow {
background-color: #c7c7c7;
font-size: 16px;
text-align: center;
color: black;
font-family:Verdana;
}
td {
width: 100px;
}
.top {
margin-bottom:10px;
}
.sub1 {
margin-left: 20px;
margin-bottom:10px;
}
.sub2 {
margin-left: 40px;
margin-bottom:10px;
}
.clickable {
cursor:pointer;
}
.clickable>.clickable {
display:none;
}
JS
$(".clickable").children("table").click(function () {
$(this).parent().children(".clickable").slideToggle();
});
I made a jsFiddle to do this. Is this what you are looking for?
HTML:
<table class='top' id='A'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>A</td>
</tr>
</table>
<table class='sub1 sub_A' id='A1'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>B</td>
</tr>
</table>
<table class='sub2 sub_A1'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>C</td>
</tr>
</table>
<table class='sub2 sub_A1'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>D</td></tr>
</table>
<table class='sub1 sub_A' id='A2'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>E</td>
</tr>
</table>
<table class='sub2 sub_A2'>
<tr class='greyrow'>
<td>SubLevel 2</td>
<td>F</td>
</tr>
</table>
<table class='top' id='G'>
<tr class='greyrow'>
<td>TopLevel</td>
<td>G</td>
</tr>
</table>
<table class='sub1 sub_G'>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>H</td>
</tr>
<tr class='greyrow'>
<td>SubLevel 1</td>
<td>I</td>
</tr>
</table>
CSS:
table {
border-collapse: collapse;
border-width: 0px 0;
box-shadow: 3px 3px 4px #AAA;
}
.greyrow{
background-color: #c7c7c7;
font-size: 16px;
text-align: center;
color: black;
font-family: Verdana;
}
td{
width: 100px;
}
.top{
margin-bottom: 10px;
}
.sub1{
display: none;
margin-left: 20px;
margin-bottom: 10px;
width: 200px;
}
.sub2{
display: none;
margin-left: 40px;
margin-bottom: 10px;
width: 200px;
}
JQuery:
$(document).ready(function() {
var Clicks = [];
function click(id, numClicks) {
this.id = id;
this.numClicks = numClicks;
}
$(".top").click(function() {
var access = -1;
for (var c=0;c<Clicks.length;c++) {
if (Clicks[c].id === this.id) {
Clicks[c].numClicks += 1;
access = c;
c = Clicks.length;
}
}
if (access === -1) {
access = Clicks.length;
Clicks.push(new click(this.id, 1));
}
if (Clicks[access].numClicks % 2 !== 0) {
$((".sub_"+(this.id))).css('display', 'block');
} else {
$((".sub_"+(this.id)+'1')).css("display", "none");
$((".sub_"+(this.id))).css("display", "none");
}
});
$(".sub1").click(function() {
id = this.id;
var access = -1;
for (var c=0;c<Clicks.length;c++) {
if (Clicks[c].id === id) {
Clicks[c].numClicks += 1;
access = c;
c = Clicks.length;
}
}
if (access === -1) {
access = Clicks.length;
Clicks.push(new click(this.id, 1));
}
if (Clicks[access].numClicks % 2 !== 0) {
$((".sub_"+(id))).css('display', 'block');
} else {
$((".sub_"+(id))).css("display", "none");
}
});
});

Categories

Resources