Javascript/J-Query dynamically resizing grid squares - javascript

what I'm asking about may be a bit too specific to be realistic, but what I'm looking for is a way to have a table/grid in a webpage that is composed of colour-coded cells. Upon clicking a cell, it expands to reveal the previously hidden contents of the cell. Ideally this would be accompanied by some sort of jquery-esque smooth animation.
I'm not asking necessarily for a complete solution here, but rather where I would need to start looking in order to be able to create something along these lines.
What I'm thinking is something that looks like this before you click on a cell:
And this afterwards:
Thanks in advance,
Kez

Use Javascript
Try this
<td id="name1" onclick="myfunction()"><div id="content"></div></td>
Java script
<script type="text/javascript">
function myfunction()
{
$("#content").html("Cell Content Become Visible ");
}
</script>

Thanks for the tips, guys, I actually managed to get pretty much exactly what I wanted using your advice. In particular the event.target property came in useful. Thanks, Izzluca.
I have created a JSfiddle showing my solution.
I gave a class ("tlight") to every cell I wanted to be able to resize, and used the following jquery code:
$(document).ready(function () {
$('.tlight').bind('click', resizeAll);
function resizeAll() {
$('.tlight').animate({
height: 50,
width: 50
}, "slow");
$(event.target).animate({
height: 100,
width: 100
}, "slow");
};
});
Kez

Not sure I am getting the problem...
It looks like you have to add a listener for the click event, on every td or maybe, ligther, on the tbody of the table: checking the "event.target" property you could be able to get to the td that raised the event (I am assuming you are working with an HTML table).
For the content, you could store it directly inside the cell itself, maybe inside a div wrapper; you can set the css property overflow on the wrapper, showing the content as much as you want (you should have to specify the height/width of the wrapper and "overflow:hidden;" on it, if I recall correctly). The cell will resize accordingly with its content.
At the click handler, you can change the overflow property to "overflow:visible;": in that case, all the content will be shown (or just change the height/width to show more of it).
If you don't set any fixed height for the table's cells, the row will get the height of the highest cell, so you don't have to fix the row's height when you explode the cell's content.
PS: Maybe interesting: using "table-layout:fixed;" you should be able to assign a percentage height to the rows, like:
table {
height: 300px;
}
.row1: {
height: 50%;
}
.row2: {
height: 50%;
}

Related

Angular Fixed Table Header Glitch

This is a continuation of my previous post found here.
The fixed headers work fine but I'm having a problem on initial load.
When the table first loads it looks like this:
But then once I click on of the column heads to sort it by that value everything snaps into place and ends up looking like this:
Like I said in my previous post, I'm using the anguFixedHeaderTable plugin. The headers stick fine but I'm just getting this glitch. I can provide details on all the resources I use in this project if that helps to debug the problem. I can provide more info but I just don't know what to provide at this point.
Additionally, when I click on the column to sort the list the table flickers in that it expands to full size before coming back to a height of 300px with a scroll bar. If I click it a few more times it sorts without any table flickers. If I click on a new column header to sort by that it again flickers once but a few more clicks of the same header results in a smooth and clean ordering. Any idea what's causing this flicker?
Edit 1:
Based on Code Wizard's advice I took the working code from the demo and put it into the github .js file. Here's what I have now:
function tableDataLoaded() {
// first cell in the tbody exists when data is loaded but doesn't have a width
// until after the table is transformed
return $elem.find("tbody").is(':visible');
/*var firstCell = elem.querySelector('tbody tr:first-child td:first-child');
return firstCell && !firstCell.style.width;*/
}
This actually works perfectly on first load. The only problem is I have two tables that the user can switch between with a click of a button. Those tables are controlled with a simple ng-show expression to detect which view the user selected. So when the table first loads, the look exactly like they should in both views. But then if you keep toggling back and forth the columns start messing up again. Until you click the column to sort it, then it snaps back into place.
Edit 2:
I tried going the css route and I mostly got it working. Only problem is the columns are slightly misaligned. The main issue is that the columns widths aren't dynamic. Here's a plunker to reproduce my issue. As you can see, the first row's first column content spills into the adjacent column. I want the columns to be dynamic and aligned
Since i dont have your code i can only try to help you out by pointing out some issues that might cause this problem.
When HTML engine render out tables it has to loop over all the cells and to calculate the max width of each cell in order to find the max width per table column.
The anguFixedHeaderTable use this code:
function tableDataLoaded() {
// first cell in the tbody exists when data is loaded but doesn't have a width
// until after the table is transformed
var firstCell = elem.querySelector('tbody tr:first-child td:first-child');
return firstCell && !firstCell.style.width;
}
And this function is fired here:
// wait for data to load and then transform the table
$scope.$watch(tableDataLoaded, function(isTableDataLoaded) {
if (isTableDataLoaded) {
transformTable();
}
});
If the table is not loaded yet when this code is executed the table will "fix" its width and it will use the default width which the HTML engine set to it.
What i suggest to do in order to fix it is to load the table and only After its loaded (to be sure that the function is called after the table was loaded) is to use java script code which will append the directive to the table of to re-write this module to fix this issue.
Updates after playing with the code and trying to fix the problem.
Note
On the demo site the code is different than the one in GitHub
Demo code:
- http://pointblankdevelopment.com.au/plnks/angularjs-fixed-header-scrollable-table-directive/app.js
GitHub code
- https://github.com/cornflourblue/angu-fixed-header-table/blob/master/angu-fixed-header-table.js
And the difference is this:
# The working code in the demo
$scope.$watch(function () { return $elem.find("tbody").is(':visible') },
# The "buggy" code on git hub
// wait for data to load and then transform the table
$scope.$watch(tableDataLoaded,
function(isTableDataLoaded) {
if (isTableDataLoaded) {
transformTable();
}
}
);
Grab the code from the demo and it will work as expected.
Good Luck.
have you try adding width:100%; in table and tr ?
table,tr {
width:100%;
}
Demo here
Your issue is mostly fixed, and I think you just need to apply fixes from CSS to complete it. How about we wrap the first column like this:
table tr th:first-child, table tr td:first-child{
word-wrap: break-word;
white-space: inherit!important;
}
Preview on Plunker
The TDs in your table are already responsive, we just need to modify to make the content is not overflow by applying the wrap in every th, td that you might think it would happen.
The above code I applied it to the first child, but you can customize to entire table.
Try adding this CSS:
.table {
width: 100%;
height: 200px;
}
Please see this modified CodePen: CodePen for fixed Header & Footer

Set a group of <span>'s position based on the lowest <span> in a table jQuery

EDIT 3 Can I get some more jQuery suggestions please? I've tried so many different CSS options, but Mozilla doesn't seem to want to cooperate, I would like to do something that I know will work...
So I have this 2 row table and I am trying to get the Picture caption to all be at the same height while leaving the picture centered in the <td>, and I am thinking that the best way to do this is using jQuery and the offset() function. However, I am not really sure about where to get started with this and looping through each <td> in the table.
EDIT: Trying to keep the images centered in the <td> so vertical-align: bottom unfortunately won't work...
EDIT 2: I also use 2 different styling sheets... one for IE and then one for everything else... the IE is fine, because I can set position: relative to my <td> and everything still works... the styling sheet for everything else it doesn't work for because in Firefox if I set it to position relative it ends up stacking all of the captions one on top of each other and places it in lala land. So, is there a way to include in a jQuery script if browser != IE then...?
I guess here is my mental process in how I want to try and go about doing this...
Outline:
For each <tr> go through every <td>...in each <td> get the lowest y position of the span
When there are no more <td>'s in the <tr> go through the row 1 more time and set all of the spans y position equal to the lowest y position found earlier.
Then go to the next row.
Fiddle: http://jsfiddle.net/58u4g/14/
I am a bit ashamed to be putting a fiddle up here without any jQuery code in it especially when I am asking for it, but I have yet to try looping in jQuery, especially looping through the rows of a table... Still doing some research on it, but I figured I would see what all of your thoughts were.
Thanks in advance for all the help!
Something like this is probably what you're looking for. I'm sure there are ways to do it with CSS, so don't give up on that yet.
Basically I'm capturing the height of the tallest image in the group and changing all of the images heights to that size. Alternatively, you could make a wrapper around the image and change the height of that, so you don't distort the image dimensions.
EDIT: This finds the offset of each span in a row and sets them all equal. See if that works for you (test in chrome/ff)
$('tr').each(function() {
var height = 0;
var $tr = $(this);
$tr.find('a span').each(function() {
$(this).offset().top > height ? height = $(this).offset().top : '';
}).promise().done(function() {
$tr.find('a span').each(function() {
$(this).offset({ top: height });
});
});
});
Try it here: http://jsfiddle.net/58u4g/28/
I recommend following for a neater display:
#posiflex_directory td {
width: 215px;
padding: 5px;
border: solid 1px;
**vertical-align:top**
}
And your spans arent acting like absolute. To fix it:
#posiflex_directory a {
color: inherit;
height: 175px;
position: relative;
float:left;
}
You will see that all spans will be at the bottom as you want.

Why does jQuery slideToggle() function acts strangely for me in my table?

I'm making a prototype in HTML and I want to make a table, which will display more table rows when a user clicks on a button. I want to use the slideToggle function or something smooth.
It works, showing the content, but there is some lag or something strange going on. I have applied somewhat the same function on other objects (not in tables) and there it have worked out nicely.
This is my script:
$(document).ready(function() {
$('#show-more-rows').click(function() {
$('#tr-button').slideToggle();
$('.hidden-row').slideToggle();
});
$('#show-less-rows').click(function() {
$('#tr-button').slideToggle();
$('.hidden-row').slideToggle();
});
);
Here is a jsFiddle for my table.
Any help and tips will be appreciated!
jQuery's slide animation doesn't support table rows. Just split up the table in two tables (the one visible and the one that will be expanded) and wrap the second one in a div. Now you can slideToggle() this div.
Here's your fix: http://jsfiddle.net/5SYBe/12/
The problem is that you are using it on tr elements, which cannot be re-sized to less than their contents.. (that is the way tables work)
So the animation tries to animate their height from 0 to full but it fails so you see them at full size from the start.
The same goes on with the hiding. While the animation lasts (which does nothing visually) you see it and at the end where the elements gets hidden you get the final state..

Expanding a div in td on click

I have a table having td with two div's.Now, On clicking a div should expand second div and the td should also get expanded.Again on clicking the div the td should come to normal width
mixing table layout (deprecated) with div box model can result in really strange stuff...
You'll probably not want that, but anyway:
You will need JavaScript to change the second Div's dimensions, and from what I understand you want an easing animation as well. I propose taking a look at mootools or scriptaculous, if that is so.
Please allow me to break down the literal meaning of your terrible post, so you can appreciate just how frustrating it is to try to answer these spur-of-the-moment/last-ditch-effort creations.
I have a table having td with two div's
<table>
<tbody>
<tr><td><td><div></div><div></div></td></tr></tr>
</tbody>
</table>
Notice how this code is rather bland, uninformative, and probably not an accurate representation of what you're dealing with? That's because it's all that you've provided. Next time maybe try including and link to your page, a jsFiddle, or maybe even just a more precise explanation.
Now, On clicking a div should expand second div and the td should also
get expanded.
Expand what? How much? What about the row height or column width? Does the table need to stay the same size? How about any shred of direction here. If all else fails, before and after pics drawn in MSpaint are fine.
Again on clicking the div the td should come to normal width
Although this really isn't an English sentence I think I get the gist. However, this "width" information is probably part of the unspoken meaning of "expand" we talked about earlier. Bottom line: provide some html; get a concise answer.
Try this
var oldWidth = 200;
var newWidth = 200;
$("td div:first").click(function(){
if(!$(this).next("div").is(":visible")){
$(this).next("div").show('slow');
$(this).closest("td").width(newWidth);
}
else{
$(this).next("div").hide('slow');
$(this).closest("td").width(oldWidth);
}
});

"Disabling" an HTML table with Javascript

I've seen this done in a lot of sites recently, but can't seem to track one down. Essentially I want to "disable" an entire panel (that's in the form on an HTML table) when a button is clicked.
By disable I mean I don't want the form elements within the table to be usable and I want the table to sort of fade out.
I've been able to accomplish this by putting a "veil" over the table with an absolutely positioned div that has a white background with a low opacity (so you can see the table behind it, but can't click anything because the div is in front of it). This also adds the faded effect that I want. However, when I set the height of the veil to 100% it only goes to the size of my screen (not including the scrolling), so if a user scrolls up or down, they see the edge of the veil and that's not pretty.
I'm assuming this is typically done in a different fashion. Does anyone have some suggestions as a better way to accomplish this?
You could try javascript like:
function disable(table_id)
{
var inputs=document.getElementById(table_id).getElementsByTagName('input');
for(var i=0; i<inputs.length; ++i)
inputs[i].disabled=true;
}
Try the below with Jquery
$("#freez").click(function(){
$('#tbl1').find('input, textarea, button, select').attr('disabled','disabled');
});
$("#unfreez").click(function(){
$('#tbl1').find('input, textarea, button, select').removeAttr("disabled");
});
Disabling the inner elements of an HTML table can also be done using pointer-events CSS style as shown below:
table[disabled], table[disabled] input { pointer-events: none }
At any desired point in our JavaScript code, we can add disabled attribute to the parent table which will bring the CSS styling into effect:
let gameTable = document.getElementById('gameBoard');
gameTable.setAttribute('disabled', true);
Another way to do it would be using the opacity property.
function disablePanel(id) {
var panel = document.getElementById(id);
var inputs = panel.querySelectorAll('input, button'); //anything else can go in here
for (var i=0; i<inputs.length; i++) {
inputs[i].disabled = true;
}
panel.style.opacity = 0.3; //or any other value
}
Can't you just find out the height of the area in pixels with JavaScript? And then set the veil's height to that number?
I don't have the exact code in my head but offsetHeight might do the trick
Somebody please correct me if I am wrong, but I have seen Javascript and some derivate Javascript libraries that have a lot of options for accomplishing for what you would like to do. I have used the jQuery library to do some similar effects.
One thing to think about is what exactly you are trying to disable. Essentially tables are not interactive so disabling a table would not accomplish much. If it is the form elements within the table you want to disable. You can accomplish this using JavaScript.
Along with using JavaScript for disabling the form elements, you can also use it to change properties of the non interactive elements.
An example of this would be using JavaScript to change the color of the font and borders and other non interactive elements in the table to give the "look" of being disabled. Of course you still need to use JavaScript to disable the form elements.

Categories