Simple setting off display: none / block with javascript - javascript

I have the following Code:
<table>
<tr class="odd"><td>Entry 1</td></tr>
<tr class="even clickable" onclick="showHide('sub2')"><td>> Entry 2</td></tr>
<tr class="even" id="sub2">
<td><ul><li>Information 1</li><li>Information 2</li></ul></td>
</tr>
<tr class="odd"><td>Entry 3</td></tr>
<tr class="even"><td>Entry 4</td></tr>
</table>
and the following js:
function showHide(id) {
var el = document.getElementById(id);
if( el && el.style.display == 'none')
el.style.display = 'block';
else
el.style.display = 'none';
}
with this css:
tr.odd{
background-color: #dedede;
}
tr.even{
background-color: #7ea9ff;
}
tr.clickable{
cursor: pointer;
}
tr.clickable:hover{
color: white;
}
tr[id^="sub"]{
display: none;
}
Could someone please tell me, why it doesn't work? I'm trying to show / hide onclick the row with the id="sub2"
example in jsfiddle

Open your debug console when you run your code, and you will get the message "ReferenceError: showHide is not defined".
If you place your html and javascript inside a file and run that that particular issue is resolved. It has something to do with the order with which jsfiddle processes sources.
Secondly, you are trying to get an element by id, but give it the class name - that does not make sense. By giving elements id's and using that it works.
But this is very unwieldy, and just serves to explain why it did not work. You are better off using jQuery as raphael said.
edit: replaced html with link
function showHide(id) {
var el = document.getElementById(id);
if( el && el.style.display == 'block')
el.style.display = 'none';
else
el.style.display = 'block';
}

First of all, in your JSFiddle example, the function is wrapped into a domready event. You should change the wrap of your JavaScript to No wrap - in body. This can be set up in the second dropdown in the left bar. Your function won't be accessible otherwise.
Then, the second line in your JavaScript searches for an element with an ID - but your document does not contain any ID's, it contains classes. document.getElementById can only find elements by their IDs.
I would suggest that you use jQuery for this task. With jQuery, the task can be solved like this:
HTML:
<table>
<tr class="odd"><td>Product 1</td></tr>
<tr class="trigger"><td>> Product 2</td></tr>
<tr class="even"><td> Information 1</td></tr>
<tr class="even"><td> Information 2</td></tr>
<tr class="odd"><td>Product 3</td></tr>
<tr class="even"><td>Product 4</td></tr>
</table>
JavaScript:
$(document).ready(function() {
$(".trigger").click(function() {
$(".even").toggle();
});
});
JSFiddle
jQuery Toggle Documentation

I don't know to explain to you why this is happening, but you need to check if css display property is set to none or it is empty. So this will trigger your function from the first time, otherwise it will go to "else", and then trigger on the next click.
So you need to check the following conditions:
if( el && el.style.display === 'none' || el.style.display === '')

Related

Create a function that follows a moving text on a table

I found a function to move data between table cells but the functions never seem to stick to whatever tag is "attached" to the cell itself. I'm not sure if I was using ids wrong. I need help finding a way to "attach" a function to a tag that moves between cells.
Can you help me create a button to move a tag (unit 1) upwards and downwards through a table such that it stops at the end of the table?
Original code attached here
//Send to the "bottom"
function sendOS() {
var node = document.getElementById("r1c1").lastChild;
document.getElementById("r1c3").appendChild(node);
/*
var node = document.getElementById("r1c3").lastChild;
document.getElementById("r1c2").appendChild(node);
*/
}
//Send to the "top"
function sendTop() {
var node = document.getElementById("r1c2").lastChild;
document.getElementById("r1c1").appendChild(node);
}
table,
th,
td {
border: 1px solid black;
width: 32px;
height: 32px;
}
<table>
<tr id="row1">
<td id="r1c1">Unit1</th>
<td id="r1c2">Unit2</th>
<td id="r1c3">Unit3</th>
</tr>
<tr id="row2">
<td id="r2c1">r1c2</td>
<td id="r2c2">r2c2</td>
<td id="r2c2">r2c3</td>
</tr>
<tr id="row3">
<td id="r2c2">r3c1</td>
<td id="r2c2">r3c2</td>
<td id="r2c2">r3c3</td>
</tr>
</table>
<!--Table ends -->
<!-------------------------------------------------------------->
<button onclick="sendOS()">move to the other side</button>
<button onclick="sendTop()">move to the right</button>
I can't help you with creating all that. You should try it out for yourself, you'll learn a lot more.
But I can help you with the code you provided.
A lot of your id attributes are the same. Every id on the page should be unique.
Change your HTML structure slightly by adding a <span> around the texts inside your cells (<td><span id="target-1">Text</span></td>). That way you can select elements inside your cells and move those around. Using lastChild to get the TextNode is not the right approach.
The functions should check if there is a cell next to it in the direction you want to move the text. If there is, move the text. If not, then do nothing.
Below I've made a small demonstration on how this might work. Here target is the element that we move. It's the <span id="target">Foo</span> element in the HTML.
When clicking either button, the code will go one element up from the target element with parentElement, that will be the <td> our target is in.
It then tries to access the previous or next <td> in the row (depending on the direction). If a neighbouring <td> is found, it will append the element.
The advantage of this approach is that you always have a reference to the element that you are moving.
const target = document.querySelector('#target');
const buttonLeft = document.querySelector('.js-target-move-left');
const buttonRight = document.querySelector('.js-target-move-right');
function targetMoveLeft() {
const previousCell = target.parentElement.previousElementSibling;
if (previousCell) {
previousCell.append(target);
}
}
function targetMoveRight() {
const nextCell = target.parentElement.nextElementSibling;
if (nextCell) {
nextCell.append(target);
}
}
buttonLeft.addEventListener('click', targetMoveLeft);
buttonRight.addEventListener('click', targetMoveRight);
<table>
<tbody>
<tr>
<td><span id="target">Foo</span></td>
<td><span>Bar</span></td>
<td><span>Baz</span></td>
</tbody>
</table>
<button class="js-target-move-left">Left</button>
<button class="js-target-move-right">Right</button>
I hope this will at least push you in the right direction. Good luck with implementing the other features.

Display html result at each round of javascript for loop

This has got to be answered already, but I can't find it.
[EDIT: very similar solution here:
Fade in each li one by one, however do have a look at WaldemarIce's solution below which also takes care of infinite looping very nicely]
I want consecutive rows of a table to be shown with fade in and fade out, one at a time, while all the other rows are hidden. I am using jQuery, see code below.
What I want to happen is for each row to fade in and out, one after the other.
What happens is that all the rows fade in and out together, simultaneously. How do I separate the events?
$(document).ready(function(){
for(i=0;i<3;i++){
var eqvar = "tr:eq(" + i + ")";
var thisrow = $("table#hidden").find(eqvar);
$(thisrow).fadeIn(2000);
$(thisrow).fadeOut(2000);
}
});
.hide{
display:none;
}
<table id="hidden"><tbody>
<tr class="hide"><td>Row 1</td></tr>
<tr class="hide"><td>Row 2</td></tr>
<tr class="hide"><td>Row 3</td></tr>
</tbody></table>
Example of code showing each row of the table, one at time, in infinite loop:
$(document).ready(function(){
function present () {
$('#hidden tr')
.each(function (idx) {
$(this).delay(idx * 1300).fadeIn(250).delay(800).fadeOut(250)
})
.promise().then(present)
}
present()
})
.hide {
display: none;
}
<table id="hidden">
<tbody>
<tr class="hide"><td>Row 1</td></tr>
<tr class="hide"><td>Row 2</td></tr>
<tr class="hide"><td>Row 3</td></tr>
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
you can use like this:
$(document).ready(function(){
$("table#hidden tr").each(function(i,v){
setTimeout(function(){
var thisrow = $(v);
$(thisrow).fadeIn(2000);
$(thisrow).fadeOut(2000);
}, 4000 * i);
});
});

HostListner with particular element in the template Angular4?

My requirement is I want to fix the table header after certain scroll to up,while the table body is scrolling.
My app.html is below.
<table class="table table-fixed-ok" #scroller [class.fixed]="fixed">
<thead >
<tr class="row-hor-heading">
<th colspan="3" scope="row"><span class="bank-name">
{{offer.name}}</span>
</tr>
</thead>
<tbody>
<tr class="row-2-data bg-white">
</tr>
</tbody>
</table>
So i want to listen the scroll of this table only(app.html contains many more other div.i want this div scroll to be listened.)
My app.ts section is below
#HostListener('window:scroll', ['$event'])
onWindowScroll(event: Event) {
debugger;
let num = this.el.nativeElement.querySelector('.table-fixed-ok').scrollTop;
if ( num >50 ) {
this.fixed = true;
}else if (this.fixed && num < 5) {
this.fixed = false;
}
}
But this is not working as i needed.While printing the num variable always giving 0.And also it is triggering whole whole body scrolling.How to solve this.Please give me a solution.
There is no way to specify an element for #HostListener(), but you can just apply the event binding to the element directly like:
<div (scroll)="myScrollHandler($event)"

Appending a table to another table in the DOM. Targeting with no class or id available

I am currently attempting to append a specific , via jquery, to another table. Here's the HTML, and the two elements involved in the move.
<div id="content_area">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr><td></td></tr>
<tr>
<td></td> <-- TD needing to move -->
</tr>
</tbody>
</table> <-- Needs to move-->
<table width="100%" cellspacing="0" cellpadding="5" border="0">
<tbody>
<tr>
<td width="190" valign="top">
<table width="100%"></table>
<-- Move Above TD Here -->
</td>
</tr>
</tbody>
</table>
</div>
Although I'm hardly experienced with jquery/javascript, I have used the following method in the past to append a div to another div.
$(".target").appendTo($(".destination"));
This method I have used in the past required that the elements have some sort of unique identification. Since this is not possible with the current site I am developing (The software has locked down the HTML), how can I target these two tables in order to make the append?
You can view the issue at the following page:
http://xlevj.jyetp.servertrust.com/Pro-Audio-Equipment-s/1824.htm
It's pretty obvious to see on that page what I'm trying to accomplish with the move. Thanks for any help!
Try this:
//Find the td we want to move.
var tdToMove = $('#divWaitModal + table > tbody > tr:nth-child(2) td');
//Find the td we want to insert into after.
var tdToInsertAfter = $('#divWaitModal + table + table tr:first-child td:first-child');
//Detach the td to move.
tdToMove.detach();
//Insert it at the proper place.
tdToInsertAfter.after(tdToMove);
Just use child number of the node and target trough that :
$('body table:first-child').appendTo( $('table:eq(1) td:eq(0)') );
In words it takes the first table and it's appending it to second table > first cell. You can use :eq( number ) where number starts from 0, or first-child selector in some cases ..
This CSS might accomplish what you're after:
#content_area {
overflow: hidden;
}
#content_area table {
display: inline;
float: left;
}
If you want to target the elements, you can use the #content_area as a selector:
var $tables = $('#content_area>table');
var $table1 = $(tables[0]);
var $table2 = $(tables[1]);

Hide JS element without div or class

I am trying to hide the toolbar of a SSRS report.
There is a specific reason why I need to use JS( The report will be included in the CRM 2011 Dashboard, and I wanted to remove the toolbar from the Report. Since the report parameters did not work, I imported Report Control solution and I am editing the viewer, which uses JS ). The viewer is a Html page that embeds the Report as an IFrame.
The generated Html code is:
<table id="reportViewer_fixedTable" cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;height:100%;">
<tbody>
<tr style="background-color:#C4DDFF;"> … </tr>
<tr id="ParametersRowreportViewer" style="display:none;"> … </tr>
<tr style="height:6px;font-size:2pt;display:none;"> … </tr>
<tr>
The toolbar is in the 4th tr, and selecting it directly and trying to hide it did not work.
navCorrectorDiv = report.contentWindow.document.getElementById('reportViewer_Toolbar');
if (navCorrectorDiv != null) {
navCorrectorDiv.style.display = "none";
}
I should select the table reportViewer_fixedTable, that I can do, then select the tbody element and then the fourth tr.
Is there a way to do it? Possibily without jQuery.
Case: No Iframe
Select the element
As jQuery selector:
var selected;
selected = jQuery('#reportViewer_fixedTable');
…
selected = jQuery('#reportViewer_fixedTable tbody');
…
selected = jQuery('#reportViewer_fixedTable tr:nth-child(4)');
Hide selected with:
selected.css('display', 'none');
or with modern browsers without jQuery:
var selected;
selected = document.querySelector('#reportViewer_fixedTable');
…
selected = document.querySelector('#reportViewer_fixedTable tbody');
…
selected = document.querySelector('#reportViewer_fixedTable tr:nth-child(4)');
And hide:
selected.style.display = 'none';
Case: Content in Iframe
The iframe can be problematic, because it might be sandboxed or the content might come from a different domain. This can lead into a XSS-violation which, in your case, might be unfixable.
Anyway, here we go:
//Select the first iframe (which might not be the right one in your case);
var elem = document.querySelector('iframe');
//And put it's body in a variable. We use the querySelector from the body
//of the iframe.
var ibody = elem.contentWindow.document.body;
var table = ibody.querySelector('#reportViewer_fixedTable');
var tbody = ibody.querySelector('#reportViewer_fixedTable tbody');
var fourthtr = ibody.querySelector('#reportViewer_fixedTable tr:nth-child(4)');
table.style.display = 'none';
tbody.style.display = 'none';
fourthtr.style.display = 'none';
I guess you can do it by trying to find the nth Chid
Consider this approach :
HTML :
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<table id="reportViewer_fixedTable" cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;height:100%;">
<tbody>
<tr style="background-color:#C4DDFF;"> <td>1</td> </tr>
<tr id="ParametersRowreportViewer" style="display:none;"><td>2</td> </tr>
<tr style="height:6px;font-size:2pt;display:none;"> <td>3</td> </tr>
<tr><td>FourthTR</td></tr>
</tbody>
</table>
</body>
</html>
JS:
$(function(){
console.log( $('#reportViewer_fixedTable tbody tr:nth-child(4) td:nth-child(1)').text());
$('#reportViewer_fixedTable tbody tr:nth-child(4) td:nth-child(1)').addClass('FourthTR');
$('.FourthTR').hide();
});
So , what we are trying to do is that, we are grabbing the 4th tr of the table and then we are grabbing the 1st child of the 4th tr. Once that is done, we are , on the fly, gonna add a class to it say FourthTR and then hide the class using jQuery.hide(). Voila, you are done.
See the working example here: http://jsbin.com/ACam/1/edit . As always, remember to run with js .
I don't think you need to use JavaScript for this
If you have access to ReportControl solution and server-side code of ReportViewer.aspx.cs, you can set property
reportViewer.ShowToolBar = false
in that code.
Alternatively, if you have access to and can modify viewer page markup (ReportViewer.aspx), you can set it declaratively: by adding ShowToolBar="false" to ReportViewer control declaration:
<rsweb:ReportViewer ID="reportViewer" runat="server" ... ShowToolBar="false">
</rsweb:ReportViewer>
If this is not an option, you can amend URL you're passing to IFrame hosting ReportViewer, by adding rc:Toolbar=false parameter
http://localhost/ReportServer/Pages/ReportViewer.aspx?%2fMyReport%2fBEA&rs:Command=Render&rc:Toolbar=false

Categories