Toggle multiple table rows - javascript

I got this table, used for menu and submenu items.
It's a combination of PHP (to read the menu items and per menu item all submenu items) and HTML.
What I need is to find a way to toggle visibility on only the submenu items of main menu item.
I've tried lots of stuff with javascript and jQuery (getelementbyID, byName, byClassname ) but it all doesn't seem to work.. (perhaps it's so simple that I'm making it diffcult..)
What I do is I get the mainmenu item per row in the DB table, ordered by order number.
While posting the table row with content, I query the submenu DB table for the submenu items.
I post the submenu items as additional normal TR lines, so it's no separate table or anything, just a new TR.
For both while loops, I run a counter so I can use that as a reference number.
I set the display to 'none' on those submenu items, but I'm not sure where to go from there.
ex:
<table>
<!-- column text //-->
<tr>
<th>1st var</th><th>2nd var</th><th>3rd var</th>
</tr>
<!-- mainmenu item //-->
<tr>
<td>1st var</td><td>2nd var</td><td>3rd var</td>
</tr>
<!-- submenu item //-->
<tr>
<td>1st var</td><td>2nd var</td><td>3rd var</td>
</tr>
<!-- next mainmenu item //-->
<tr>
<td>1st var</td><td>2nd var</td><td>3rd var</td>
</tr>
<!-- and so on //-->

If I get it what are you asking then it can be solve with CSS alone.
You need class for submenu that hides all submenues and you need class for menues that will on hover change next sibling table cell display property (so next row).
So when you hover first row it will change next row TD elements (initially they have display set to none). You need to set hover style for submenu row as well to table-cell if you dont wana your submenu row disapear after you move on it.
table{
width: 100%;
border: solid 1px #ccc;
}
th{background: #eee;}
.submenu>td{display: none; color: red;}
.menu:hover + .submenu>td{display: table-cell;}
.submenu:hover>td{display: table-cell;}
<table cellspacing="0" cellpadding="0">
<tr>
<th>1st var</th><th>2nd var</th><th>3rd var</th>
</tr>
<tr class="menu">
<td>Menu A1</td><td>Menu A2</td><td>Menu A3</td>
</tr>
<tr class="submenu">
<td>Submenu A1</td><td>Submenu A2</td><td>Submenu A3</td>
</tr>
<tr class="menu">
<td>Menu B1</td><td>Menu B2</td><td>Menu B3</td>
</tr>
<tr class="submenu">
<td>Submenu B1</td><td>Submenu B2</td><td>Submenu B3</td>
</tr>
</table>

Related

add rows and columns to atable and display the row and column no

I need help in javascript code for dynamically adding rows and columns and displaying the rows and column no. dynamically.
<!DOCTYPE html>
<html>
<head>
<style>
table, td {
border:1px solid black;
}
</style>
</head>
<body>
<p>Click on each tr element to alert its index position in the table:</p>
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
</body>
This is what I have tried but I am not sure whether the table rows and columns are generated dynamically and also the column is not renerated and displayed.
Please help.
First of all don't add the event handler to each td/tr element manually, use JQuery to add it to all td elements:
$('td').click(function(e) {
console.log($(this).parent().index(), $(this).index());
});
Inside the event handler, $(this).parent().index() and $(this).index() will give you the row and column number respectively.
I suggest looking at the JQuery append() or clone() functions for dynamically adding rows/columns, but you haven't really specified exactly what you're trying to do in this respect.

<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>

Using same Class to use the click method to show the nearest hidden element by its class

What I am trying to achieve: What I am trying to achieve is very simple I have a table with 2 table body tags. The first one gets shown as its just the main content. The last td element has an anchor tag, this anchor tag when clicked should show the next tbody tag using the jQuery method slideToggle().
Problem: The problem I am having is these are dynamically made tables using Angular.js. So if there are 5 items then there are 5 div elements each with a table that all have the same class for each tbody within the div. This makes sense as for each I would like the click function to show that specific tables second div if the user wants to see additional content related to that item.
Things tried:
$(this).next('.test').slideToggle();
$(this).closest('tbody').find('.test').slideToggle();
$(this).closest('.test').slideToggle();
$(this).closest('tr').find('.test').slideToggle();
Posts look into on StackOverflow for similar issue:
affect only the clicked element in jquery for multiple elements with same class
Using a class name in jQuery's .closest()
jQuery closest(); not working
Jquery adding click function to several spans with the same Class
Non Stack Overflow sites:
https://www.sitepoint.com/jquerys-closest-parents/
HTML:
<div class="productsList" ng-repeat="products in productListing.products">
<div class="productSection">
<div class="figureDiv">
<figure class="img">
<img ng-src="{{products.image}}" />
</figure>
</div>
<div class="description">
<h2 ng-bind="products.summary"></h2>
<summary ng-bind="products.description"></summary>
</div>
<table class="productTable">
<tbody>
<tr><td><b>Product Name</b></td><td ng-bind="product.merchantName"></td></tr>
<tr><td><b>Valid:</b></td><td>{{products.validityStart}} to {{products.valididtyEnd}}</td></tr>
<tr><td><b>Product Type:</b></td><td>Appliance</td></tr>
<tr><td><b>Testing:</b></td><td>Yes<a class="testLink" href="">Show More ></a></td></tr>
</tbody>
<tbody class="test">
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
<tr><td><b>Extra</b></td><td>Extra</td></tr>
</tbody>
</table>
</div>
</div>
jQuery (current implementation):
function init() {
jQuery(document).ready(function(){
$(document).on("click", ".productTable .testLink", function (ev) {
ev.stopImmediatePropagation();
$(this).closest('tr').find('.test').slideToggle();
$(".test").slideToggle();
});
}
Visually from Dynamic content (3 items):
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Table class="productTable"
tbody
anchor tag class="testLink"
tbody class="test"
Ending
As you can see visually there are 3 tables created each having same classes. So for the first table if the user clicks the anchor tag then the body tag right after in that specific table will be displayed with toggle. Only that one should be shown not all of them which is the current problem.
I tried many solutions however nothing is working, every implementation is making all of them toggle which is horrible.
I think something like this.
$(".productTable .testLink").on("click", function() {
$(this).parents('.productTable').children('.test').slideToggle();
});
.testLink {
color: blue;
text-decoration: underline;
}
.test {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="productTable">
<tbody>
<tr>
<td><b>Product Name</b>
</td>
<td ng-bind="product.merchantName"></td>
</tr>
<tr>
<td><b>Valid:</b>
</td>
<td>{{products.validityStart}} to {{products.valididtyEnd}}</td>
</tr>
<tr>
<td><b>Product Type:</b>
</td>
<td>Appliance</td>
</tr>
<tr>
<td><b>Testing:</b>
</td>
<td>Yes<span class="testLink">Show More ></span>
</td>
</tr>
</tbody>
<tbody class="test">
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
<tr>
<td><b>Extra</b>
</td>
<td>Extra</td>
</tr>
</tbody>
</table>
I think the problem is in this line of your jQuery $(".test").slideToggle(); as it will execute slideToggle on all .test try removing it. Also update.closest('tr'); to .closest('table'); as the .test is in the table tag not the tr
From what I make out, you are looking for JQuery's .next() method. Just for the parent tbody and call .next()
Example would be
$('.testLink').parentsUntil('tbody').next().show();

jQuery accordion menu, CSS HTML

what im trying to achieve is the following.
I have an accordion menu. Now I want to Build an accordion Menu(I call this now Top) inside an accordion Menu(I call this now Bottom).
Im doing this, to present loads of data from a database in a clean way.
Now im trying to adapt the accordion menu that I already got on this.
The data of both, top and bottom, are presented in tables. So first i builded tables inside tables.
If the users clicks on the first Element of each row, the “bottom” menu with the table should slide down.
HTML
<!-- 2016 -->
<div id="sh_details">
<div class="sh_wasserzeichen"></div>
<article>
<dl id="sh_accordion">
<dt id="sh_2016">Headline1</dt>
<dd><table>
<tr>
<th>Überschrift1</th>
<th>Überschrift2</th>
</tr>
<tr>
<td class="inhalt">Inhalt1</td>
<td>Inhalt2</td>
</tr>
<!-- Untertabelle1_1 -->
<td>
<table class="table2">
<tr>
<th>Sub_Überschrift1</th>
<th>Sub_Überschrift2</th>
</tr>
<tr>
<td>Sub_Inhalt1</td>
<td>Sub_Inhalt2</td>
</tr>
</table>
</td>
<tr>
<td class="inhalt">Inhalt3</td>
<td>Inhalt4</td>
</tr>
<!-- Untertabelle1_2 -->
<td>
<table class="table2">
<tr>
<th>Sub_Überschrift3</th>
<th>Sub_Überschrift4</th>
</tr>
<tr>
<td>Sub_Inhalt3</td>
<td>Sub_Inhalt4</td>
</tr>
</table>
</td>
</table></dd>
<dt id="sh_january">Headline2</dt>
<dd>125153226262</dd>
</dl>
</article>
</div>
CSS
/***************************************
************ Details *****************/
#sh_details {background-color:#fff;position: relative; top:0;left:0;width:100%; height: 100%; overflow:hidden;display:none;flex-direction: column;}
.table2 {display:none;}
/***************************************
************ Accordion *****************/
.sh_active {background-color:#ff6600; color:white;padding:0.7%; font-size:13px;}
article {position:absolute;color: black;width: 90%; height: auto;margin: 0 auto 0 auto;padding-top:75px;padding-left:75px;}
dt, dd {padding:0.5%;width: 50%; height:auto;float: left; margin:0;border-top:1px solid #222;}
dt {font-weight:bold;text-transform: uppercase; background-color:black; color:#ff6600; cursor:pointer;}
dt:first-child {border:none;}
dt:hover {background-color:#ff6600; color:white;padding:0.7%; font-size:13px;}
dd {background-color:#444; line-height:25px; word-spacing:3px;color:#999; display:none;}
**jQuery (only the accordion stuff) **
/*SUBTABLE*/ <<<---- not working
$(document).on('click', 'td', function (event) {
if($(this).hasClass('inhalt')) {
$(this).next('.table2').removeClass('table2');}
event.stopPropagation();
});
$('#sh_accordion dt').stop().click(function(){
<--- Working
if($(this).hasClass('sh_active')) {
$(this).removeClass('sh_active');
$(this).next().slideUp(300);
} else {
$(this).parent().children().removeClass('sh_active');
$(this).addClass('sh_active');
if($(this).next().is('dd')) {
$(this).parent().children('dd').slideUp(300);
$(this).next().slideDown(300);
}
}
});
https://jsfiddle.net/u4y2o270/1/ (dont know why the code is not working, i disabled the display:none's beacause of this)
So every "Sub..." Menu should be hidden by default. If i click on "Inhalt1", the first "bottom" menu should appear and so on.
Hide and Show the top Menu works fine (Headline1, Headline2), but not the bottom menu (table inside table)
Example: Default is this:
Headline1
Überschrift1 Überschrift2
Inhalt1 Inhalt2
Inhalt3 Inhalt4
User clicks "Inhalt1":
Headline1
Überschrift1 Überschrift2
Inhalt1 Inhalt2
Sub_Überschrift1 Sub_Überschrift2
Sub_Inhalt1 Sub_Inhalt2
Inhalt3 Inhalt4
//EDIT:
Start:
Everything is hidden, besides the Headlines (Headline1, Headline2) (this is already working, but not in the fiddle)+
It looks like this:
Headline1
Headline2
User is clicking on Headline1,
The user can only see the following:
Headline1
Überschrift1 Überschrift2
Inhalt1 Inhalt2
Inhalt3 Inhalt4
Headline2
The user is now clicking on "Inhalt1"
The user now sees this the following:
Headline1
Überschrift1 Überschrift2
Inhalt1 Inhalt2
Sub_Überschrift1 Sub_Überschrift2
Sub_Inhalt1_1 Inhalt2_2
Inhalt3 Inhalt4
Headline2
//EDIT2:
Updated the fiddle http://jsfiddle.net/u4y2o270/7/
This is what is working so far.
If the user is now under Headline1 clicking Inhalt1 the table under it should slideDown // should be showed, the table has the class .table2 which is by default on display:none to be hidden. My idea was, to find the next Item with class table2 and remove the class or slide it down. But its not working.
Same obv. for Inhalt3

jQuery dynamic insert row for expand/collapse

I have a table structure as follows;
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 1</div></td>
</tr>
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 2</div></td>
</tr>
Now on click of the icon image (chevron), I want the details row to be displayed immediately below the clicked row (It should be a tr containing child table). This should be inserted/appended dynamically on click of any of the list row.
How do I do this using jQuery? Any examples for reference would be really helpful..
the following example creates a new tr (if does not exists) containing table element under the tr where the clicked icon exists.
function createChildTable(string)
{
return $('<table>').append(
$('<tr>').append(
$('<td>').append(string)
)
);
}
$('.icon-chevron-right').click(function() {
var details = $(this).closest('tr').next('tr.details');
if (details.length) details.show();
else {
// first time clicked
details = $('<tr>').append( createChildTable('child table details') ).addClass('details');
$(this).closest('tr').after(details);
}
});
Example Link
I'd say there are two main ways to do this, and you'll have to figure out which one is best for you; it depends.
What you're talking about is ADDING a row into the DOM. This is fine in some cases, it depends on what this collapsed row is used for. If you want to be able to remove the collapsed row and add it again, it could make your life difficult if you have to reconstruct all the inner HTML via JavaScript every time.
var collapseHTML = '<tr class="collapse"><td colspan="2">This is my new row</td></tr>';
$('.icon-chevron-right').click(function() {
$('.collapse').remove(); // Deletes all rows that has class "collapse"
collapseHTML.insertAfter( $(this).closest('tr') ); // Inserts what's stored in collapseHTML after "this closest tr"
});
Then, as someone else said, you can solve this by adding those rows from the get go like so:
<tr>
<td><div class="icon-chevron-right"></div></td>
<td><div>List 1</div></td>
</tr>
<tr class="collapse">
<td colspan="2">This is my new row</td>
</tr>
Then, your css should loook something like this:
.collapse {
display: none;
}
.collapse.active {
display: block;
}
This means that when you add the active class to the collapse row, it goes from display: none; to display: block;. This you do via JavaScript/jQuery:
$('.icon-chevron-right').click(function() {
$('.collapse.active').removeClass('active'); // Removes active from all active collapsed rows
$(this).closest('tr').next().addClass('active'); // adds active class to "this closest tr's next element" (which is the collapse row)
});
Hope this helps!

Categories

Resources