How can I hide the table cells contents dynamically using plain javascript? - javascript

I am creating a table in plain JavaScript, and filling it up using onClick listener event in two ways - either clicking on a external button, or clicking on one of the cells itself.I am not able to hide the contents of my table cells dynamically i.e.I want to hide them when rendering values in them, which I want to unhide/display later-on on some other event.
I have already tried conventional methods available viz.
td {display: none;}, and td {visibilty: hidden}
I have also tried inline CSS style method to hide the cell contents, but all these methods blank the table itself i.e. oblivate the cell borders themselves.
<body>
<div class="container-fluid">
<table id="myelement">
<tr>
<td> </td>
... .... ...
<td> </td>
</tr>
</table>
</div>
</body>
<script>
...
for(let i=0;i<mycount;i++){
for(var t=0;t< Math.floor(Math.random()*td.length);t++){
td[n[i]].firstChild.nodeValue='X';
}
}
...
</script>
All the techniques available blank the table itself i.e. oblivate the cell borders themselves.

There are a number of ways to do this, and some other ways might be better depending on the content of your table cells. But assuming it's just text, one way you could hide the cell contents would be to make the fontSize of the cell equal to 0. See this example:
hide.addEventListener("click", function(event) {
document.getElementById("table").rows[1].cells[1].style.fontSize = 0;
});
show.addEventListener("click", function(event) {
document.getElementById("table").rows[1].cells[1].style.fontSize = null;
});
table, td, th {
border: 1px solid black;
}
<table id="table">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
<button id="hide">Hide Cell "Smith"</button>
<button id="show">Show Cell "Smith"</button>

Related

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>

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();

Breaking a table up if too long

I have a table inside of a div with a set height. The rows are horizontal:
<div height="600px">
<table>
<tr>
<td>
<td>
</tr>
.
.
</table>
</div>
The problem is that the content in the table is dynamic so sometimes the table will outgrow the div and keep on extending downwards. Is there a way to make the rows grow horizontally instead of vertically once it reaches the edge of the div?
Add this property to your div:
overflow:auto;
You can also specify horizontal or vertical scroll, like this:
overflow-y:auto;
overflow-x:auto;
Hope this help you.
This works in jsfiddle (couldn't figure out how to save) http://jsfiddle.net/
you had invalid html by the way (<th><td>)
<div style="height:30px; background-color:red; overflow-y:scroll">
<table>
<tr>
<th>1</th>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</table>
</div>
I solved it with the following jQuery function:
$("table").each(function() {
var tableRows = $(this).find('tr');
if(tableRows.length > 12) {
var firstRows = [];
tableRows.each(function(index) {
if(index < 12)
firstRows.push($(this));
else {
var content = $(this).html();
firstRows[index%12].append(content);
$(this).remove();
}
});
}
});

Tinymce double click insert new paragraph

If I have 2 tables directly under each other with margin-bottom, is it impossible to place the cursor in this gap by creating a temporary paragraph.
E.g I want to insert a new table between the other 2. This is impossible without altering the HTML directly.
Is it possible to use the double click so that it works similar to MS word and creates a blank paragraph in this area you click, this would then get replace by the table etc similar to how the trailing plugin works.
I currently use the 'trailing' plugin which fixes this similar issue at the bottom of the page.
Also I am using the jquery version of tinymce, if that makes it any easier to fix this.
Example HTML inside tinymce editor;
<table style="margin: 15px 0; width: 100%;">
<thead>
<tr>
<th scope="col">
Product Name</th>
<th scope="col">
Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Large product</td>
<td>Find out more</td>
</tr>
<tr>
<td>Large product</td>
<td>Find out more</td>
</tr>
</tbody>
</table>
<table style="margin: 15px 0; width: 100%;">
<thead>
<tr>
<th scope="col">
Product Name</th>
<th scope="col">
Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Large product</td>
<td>Find out more</td>
</tr>
<tr>
<td>Large product</td>
<td>Find out more</td>
</tr>
</tbody>
</table>
Also created a jsFiddle with example: http://fiddle.tinymce.com/Sicaab/2 I want to be able to insert extra content (paragraph,another table, list etc) between the 2 tables without editing the HTML.
The mouse position won't help you, because you do not know if the editor content has been scrolled or not.
First, i will show you how to work with the onDblClick.
Here is a helpfull function to get the paragraph of an editor html element (in case there are no html elements that are not stacked under(or better in) a paragraph.
function table_of_click(node)
{
while (node)
{
if (node.nodeName == 'BODY') { return null; }
if (node.nodeName == 'TABLE') { return node; }
else { node = node.parentNode; }
}
return null;
};
Here is the necessary call to catch the double click event.
Be aware that this solution will add a paragraph just before the paragraph you clicked in.
I assume your tables are in a paragraph each?
ed.onDblClick.add(function(ed, evt){
// get tableof click event
var table = table_of_click(evt.target);
// if the click has not been inside a table return (nothing to do)
if (!table) return;
$(table).before("<p id='new_p'><br></p>");
ed.selection.select( $(ed.getBody()).find('#new_p').get(0) );
$('.new_p:first').remove();
evt.preventDefault();
evt.stopPropagation();
return false;
});
There is a way to get the caret (text cursor) position into the text
Caret position in textarea, in characters from the start
this is just a function getCaret(element);
now we need to capture the tinymce container's body inside the iframe content_ifr
the iframe: document.getElementById("content_ifr")
the tinymce's body: ...contentDocument.getElementById("tinymce")
using jquery we listen to the dblclick event:
.dblclick(function(event){})
find the caret and inject a <p> element on its position.
html.substr(0,position)+"<p></p>"+html.substr(position)
that is, all the text from the start to position, the p element and the text from the position to the end.
The whole code will look like this:
var editor = document.getElementById("content_ifr").contentDocument.getElementById("tinymce");
$(editor).dblclick(function(event){
var position = getCaret(this);
this.innerHTML = this.innerHTML.substr(0,position)+"<p></p>"+this.innerHTML.substr(position);
}
this should do the job ;)

Categories

Resources