Adding a row to jquery-datatable using slideDown()? - javascript

In my view, I have two divs, one responsible for adding an entry to my database, and one responsible for showing all of my database table rows when the page loads. The div responsible for displaying the contents of my table uses the Datatables jQuery plugin, which makes my life easier as far as displaying this content goes.
Both of these divs work just fine, separately. However, I would like to integrate them together such that when I add an entry using my first div, the database is updated, and this entry is then appended to my Datatable in my second div, without reloading the entire page.
I'm aware that this process alone is easy enough using the Datatables API, simply by using the row.add() and draw() functions, this can be done, and is demonstrated here.
While this is a potential solution, I'm not completely satisfied with it, because the rest of my page utilizes jQuery's slideDown() for neat-looking animations, and I was hoping that I could apply this animation to adding another row to my Datatable. If you look at their example, it simply inserts the row, but it would look better if I could make that row slide down from the table.
Is this something that could be done without spending too much time on it? Or should I just stick with using the Datatables API and give up on trying to animate it? I've already tried using jQuery to append a new row manually, but it looks terrible because I don't think I can reload the plugin to adopt the change into the Datatable.
Could someone please point me in the right direction? Thanks!

I think I've solved It!
DEMO
I've observed When click on #addRow button takes place, It adds a <tr> with class .odd or .even
Depending on the number of that row ie, 1,3,5... are odd 2,4,6... are even.
So I've added CSS to make smooth transitions for height of tr, setting height of td ultimately will affect the height of tr. So here is my CSS:
.odd td{
height:0px;
transition:all ease 1s;
padding:5px;
}
.even td{
height:0px;
transition:all ease 1s;
padding:5px;
}
Now When the click event on #addRow button occurs, We just need to animate the last tr to specific height, to achieve slideDown effect.
That row can be either .odd or .even depending on the counter variable which is incremented each time when row is added.
So that's what I Do in JQuery.
Here is My JQuery:
$(document).ready(function() {
var t = $('#example').DataTable();
var counter = 1;
$('#addRow').on( 'click', function () {
var tr=t.row;
tr.add( [
counter +'.1',
counter +'.2',
counter +'.3',
counter +'.4',
counter +'.5'
] ).draw();
var cls= counter%2!=0 ? ".odd" : ".even"; //class of latest row added (odd or even) %2 will do it.
$(cls).last().animate({
"height":"50px"
},1000); // Acheive slideDown();
counter++; //Increment Counter Now.
} );
// Automatically add a first row of data
$('#addRow').click();
});
This will serve you as a starting step.
Also Note that: slideDown() isn't supported on <tr>. Setting height manually using css to 0px also fails. So I request you to use fadeIn() instead of changing height using animate.
Hope it helps. Cheers :)!

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

My JavaScript slider work fine in the beginning and then it get corrupted

My JavaScript slider worked fine in the beginning and then it get corrupted after time, sometimes it takes one minutes, sometimes it takes five.
Actually I don't know if it is a conflict or what, could you please help me guys?
you can check it out here: http://test-code.bugs3.com/
When looking at the code it seems you do not yet have much web development skills. That is fine, and thereby I will go through each step of improving your webpage, as I want you to become a great developer too.
First, lets start with some CSS things. Instead of setting the padding for every side, you can also set it on all sides without needing four lines. Simply using padding:0; is enough in this case. For the margin, when you want the left and right sides to be auto, and the top and bottom 0px, you can 'chain' them in one property: margin:top right bottom left;, like a clock. Even shorter is margin:top&bottom left&right;, which in your case is margin:0 auto; <-- the top and bottom have 0 margin and the sides have auto margin. (btw if something is 0 you don't need to add a unit to it).
For a border I found this:
border: solid;
border-width: thick;
border-color: #E6E6E6;
You can also put that together by using border:thick solid #E6E6E6;
Now for the javascript. The problem that it is slow is because it uses a lot of timers and intervals to do things, and the timers do not get cleared well. My opacity is currently at -850. Instead of improving the code I suggest we rewrite it. You have written the same code over and over again for every picture, where only some variable names differ. What if we just write that code once? Would be a lot faster. And we could add as many pictures as we want.
To be able to instantly get a list of all the picture elements, I add a class to them: class="sliderPicture". Now when I want the list I can call document.getElementsByClassName('sliderPicture'); and there we have our array (I removed the ID's as we won't need em). We also need a variable to keep track of at which picture we are right now. I will elaborate on this later.
As we do not want the animation to be done by using javascript but just by using CSS, we are going to add some css code to the sliderPicture class:
.sliderPicture {
opacity:0; /*We want all images to be transparent, as we override this value when we want to display the picture*/
position:absolute; /*this puts all the pictures in the same place behind eachother, so that we do not need to display:none; and display:block; them*/
transition:2s opacity; /*this means, every time the opacity of the element changes, do not directly set it to that opacity but fade to it in 2 seconds*/
}
Now we create a class which will show the images. The script then only needs to add/remove the class:
.showPicture{
opacity:1;
}
Now on to the javascript code. It is pretty short, and I hope the comments explain good enough:
var images = document.getElementsByClassName('sliderPicture'); //this contains an array of all the images.
var imageTime = 3000; //the time in ms for when the pictures should change
var i = 0; //the picture we are at
setInterval(function(){
if(images[i].classList.contains('showPicture')) images[i].classList.remove('showPicture'); //if the element contains the class showPicture, remove it. (we first check for it to not generate errors when removing something that might not be there (it should, but never create any room for errors))
i++; //increment the image where we are at
if(i >= images.length) i=0; //if we are at the end of our array. Picture 2 of the array is the last picture, so, as we increment it above, our i value should be 3 then. The length of our array is also 3, so when i=length of the array we set it back to 0 to display the image
images[i].classList.add('showPicture'); //here we add the class so the element gets opacity 1
}, imageTime);
as we want the first picture to directly show up we just add showPicture to its class.
I also see nice buttons on the bottom. I think you want them to automatically switch to the picture. I can help you with automatically generating buttons to not have to bother about adding them manually.
Furthermore, if this slider is to display many different images, you can also write a little script to add the images from an array containing the url's. Then you don't need to add <img class="sliderPicture" src="..." /> every time, but let the javascript generate that for you (including generating the buttons.
All this code is combined in this jsfiddle.
If you have a question, any at all, feel free to ask them. I hope you enjoyed reading this answer and have a better understanding on how to combine css and javacript to generate nice webpages.
old:
this looks like a problem with all the intervals and clearing of things. your code does even look like it can be made much simpeler, as you are using timers to fade things, instead of css. For this fading you can use transitions. For the condition code, you'd better use an array and take the next item from it (or 0 if there is no next item).

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

Changing contents of a Div to cycle through ADs or Content or Whatever

I have a website that I am developing and I have multiple Divs on the main page. I have a div on the right side of the page labeled right_bar2 and I want it to change every 5-10 seconds. The entire div will just be an image that is a link. Basically I assumed the easiest way to do this would be to have a div with a bunch of hidden div's in it and then maybe some javascript that unhides one div at a time and then hides it again and unhides another. However I am unsure the best way to do it. I have looked at a bunch of example and can't get it to work 100% correctly.
Thanks for any advice ;)
JsFiddle examples would be great!
I tried something like this http://jsfiddle.net/VENLh/4/ but in my rails environment/setup, it breaks multiple things, so I'd like something cleaner and easier.
I cleaned it up a bit in this fiddle, but if you said the original breaks multiple things in your original environment, this might not fix them. What specifically did it break?
What I cleaned up was to avoid the need to keep a manual count of the DIVs for the JS or to worry about their IDs. The code is pretty simple:
$(function() {
var $divs = $('div', '#container'),
total = $divs.length,
counter = 0,
showDiv = function() {
$divs.stop().hide();
$($divs[counter]).show('fast');
counter = (conter + 1) % total;
setTimeout(showDiv, 3000);
};
$divs.hide();
showDiv();
});
​I didn't perform one optimization that should probably be done. You probably should cache the results of the jQuery selectors on each DIV. It would be easy to do with a jQuery map statement, but I didn't want to muddy the waters here.
The only problem I can see in this case is if you are going to use heavy image, it may take some time to load. As the image will start getting loaded when you show it first time. So for this I would say you should keep the opacity 0 and load the image at the time of pageload.
And also to remove the delay you are having where one div is getting hidden and other is getting visible can be removed by using opacity. reduce opacity of one from 100 to 0% and for other increase from 0 to 100%.

"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