Add div programmatically to a refreshing table - javascript

I am currently working on my own ColumnResizer for a table. I know that there are some PlugIns that are doing exactly this, but I would love to write my own one.
To create a resizable column I am appending a div to each th-Element of the table programmatically like this:
jQuery.each($("#table > table > thead > tr > th"), function() {
if(this.id !== ""){
var div = createDiv($(this).outerHeight());
$(this).append($(div));
$(this).css('position','relative');
this.width = $(this).outerWidth()
console.log(div)
}
});
The function "createDiv()" looks like this:
function createDiv(tableHeight){
var div = document.createElement('div');
$(div).css('top','0');
$(div).css('right','0');
$(div).css('width','2px');
$(div).css('position','absolute');
$(div).css('cursor','col-resize');
$(div).css('userSelect','none');
$(div).css('height',tableHeight + 'px');
return div;
}
This is working fine then entering the page.
The problem is that the table can be multi-paged. So you can switch between pages of the same table. Each page switch is refreshing the table and here is the problem: After such a refresh I cant append the div to the th-elements .... Its just not working. I am calling exactly the same methods when the table is being refreshed. I also added a timeOut because I thought that the table isnt finished loading yet but it also didnt help.
I already tried to add
$(document).ready()
but it also didnt work.
One funny thing is that then I am adding an
alert("test")
to the refreshTable() function, the divs are there after closing the alert.
Does any one know how to solve this problem?

Related

Refresh div during JQuery update

I have a html file with many div. Beside this I have a JQuery file too which run an AJAX request in every 30 seconds. In my JQuery If a condition met and the jQuery reloded 3 times I want to update my div-s. I tried to add a div, but it does not appear just when I reload my whole page. If I set to remove my div and not add, the JQuery removes my div, so it is very odd for me, because just the .add or .append or .html do not working. furthermore I set a class with invisibility too, and I also set that when the condition met the jQuery file remove the invisibility class, but the div do not want to appear. I am trying to create a sample code.
My html
<div class="row">
<div id="myclass" class= "invisible" >
<div <p> Please appear for me!<p></div>
</div>
</div>
My JQuery:
if (condition) {
$('#myclass').removeClass('invisible');
if (n >= 2) {
$('#myclass').addClass('invisible');
}
}
The main point is, If the conditions met the class not removes just When I reload my page. In the jQuery file the n is equal with the times when the AJAX reloaded with setInterval. My question is why my div not appear just when I reload my whole page? Also why remove without reload?
Thank you in advance the answers!
removeClass and addClass perfectly work. at first, you can check if you jQuery works, just try to write you script (with ".append",".html",".insertAfter") directly in browser console, else you can add some console.log in your code, when you change invisibility like:
console.log('removeClass');
$('#myclass').removeClass('invisible');
if (n >= 2) {
console.log('addClass');
$('#myclass').addClass('invisible');
}
for update some div content, you can use simple function for it. like -
call self page in get request, and replace div content.
function reloadMyDiv(selector){
var element = $(selector);
if(element.length===1){
$.get(window.location.href,{},function(response){
var new_page = $('<div></div>').append(response);
var new_element = new_page.find(selector);
if(new_element.length===1){
element.html( new_element.html() );
console.log('update');
}else{
console.log('need contains only one element, '+new_element.length+' found!');
}
});
}else{
console.log('need contains only one element, '+element.length+' found!')
}
};
and if you more _ not use your interval, is good practice for clear it.
var n = 0;
var myInterval = setInterval(function(){ myFunction() },30*1000);
function myFunction(){
n+=1;
//do, what you want to do
if(n>2){
clearInterval(myInterval);
}
}

XPage partial refresh with a script block

I'm trying to make my Data View look and feel a bit better, by adding some client side functionality.
In this case I made a script, that let's the user hover over a row and it shows it's detail.
The structure looks something like this:
The script block contains some basic jquery:
function x$(idTag){
idTag = idTag.replace(/:/gi, "\\:");
return("#"+idTag);
}
var dataView = x$('#{id:dataView1}');
var detail;
$(dataView + ' > table > tbody > tr').mouseenter(function (e) {
detail = $(this).attr('id').replace(':_row', '_detail');
detail = x$(detail);
$(detail).show();
});
$(dataView + ' > table > tbody > tr').mouseleave(function () {
$(detail).hide();
});
Everything works fine, until I click on one of the row expand/collapse buttons, at which point the script code stops working.
My guess is it has something to do with the partial refresh, that happens when I expand or collapse a level in the data view, and it doesn't reload the script block or reloads it wrong.
If I turn off partial refresh it keeps working afterward, but of course a full page refresh just to expand or collapse a row is too slow and not realistically usable
Any ideas?
The jQuery code only runs on the items it can see on the page - you need to change the selection criteria so that it runs as a delegated event. In this case whenever you move the mouseevent over the data view it will detect the selector which triggered the event and if that matches then it will run accordingly. This way it will run on all rows regardless of whether they were "on the page" before or after the partialRefresh.
http://api.jquery.com/on/
Try this instead
$(dataView).on ('mouseenter', 'table > tbody > tr', function (e) {
detail = $(this).attr('id').replace(':_row', '_detail');
detail = x$(detail);
$(detail).show();
});
$(dataView).on('mouseleave', 'table > tbody > tr', function () {
$(detail).hide();
});
Code not tested as I don't have your environment :)
Thanks to another source got a quick hack to help here.
Placed both the dataView and scriptBlock in a panel and then set the refreshID of the dataView to the panel's ID.

jcarousel images disappear after scroll event

I have an autocomplete text input that triggers a slider using jcarousel to scroll to the image of the selected person. The problem is, if you search once, it works, but searching again makes all the images disappear.
Here is the code that controls the input:
jQuery('#team_select2').change(function() {
var idx = $('#team_select2').val();
if(idx == '')
{
carousel.scroll(1);
$('.details').hide();
return false;
}
carousel.scroll(idx);
$('.details').hide();
$('#'+idx+'_details').show();
});
You can see it breaking in action if you go to http://welchhornsby.com/new-team-page/ and try searching for two of the people in the list.
Anyone have any idea why it would be breaking like that?
Found the answer right after posting this. Just changed the 4th to last row from carousel.scroll(idx); to carousel.scroll(idx*1);

Scrollable DIV scrolls to top when TD is clicked

I have an interesting problem that I cannot seem to find an answer for on Google. I have a scrollable div that a simple table in it. There are 'heading' rows ('.sl-bucket') that when clicked the script shows the associated rows below that, hiding other shown rows. In Chrome and IE, there is no issues. In Firefox on a fresh load, when you click the first element, it scrolls the div back to the top. Everything else works great after that.
Any thoughts on how I could fix this?
Here is the example jsFiddle.
Here is my javscript:
$(window).on('click', '.sl-bucket', function() {
var bucket = $(this).attr('rel');
if ($('.sl-'+bucket).is(':visible') == false) {
$('.sl-unitRow:visible').hide();
$('.sl-'+bucket).show();
} else {
$('.sl-'+bucket).hide();
}
return false;
});
Working for me by using
$('.sl-'+bucket).css("display", "block");
instead of
$('.sl-'+bucket).show();

How do I make this jquery animation delay work properly?

I have an html table that I am trying to add some animation to with jQuery. I am very close to what I want but have one outstanding issue. I will try to describe what I am doing with as cut-down a version of the table and scripts as possible.
The table is defined as follows;
<table>
<tbody class="group">
<tr>First</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
<tbody class="group">
<tr>Second</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
<tbody class="group">
<tr>Third</tr>
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
</tbody>
</table>
The effect I want is for all of the <tr class='slide'> rows to be hidden once the page is loaded and then to slideDown into view when the mouse pointer enters the row above. I want the .slide row to remain in view as long as the mouse pointer remains in either the row above or the .slide row (contained within the <tbody> tags). I then want the .slide row to slideUp out of view when the mouse leaves either of the rows within the <tbody> tags. I have managed to do this successfully with the following code.
<script>
$(function() {
hideRows();
setupEventHandlers();
});
function hideRows() {
$("div.hidden").each(function() {
$(this).hide();
});
};
//The hideRows function is much more complicated in my actual page
//as I have to calculate the div height prior to hiding so it animates
//correctly. That's why I don't just set display:none; in the stylesheet.
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
$(this).slideDown();
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
$(this).slideUp();
});
});
};
//note that I have to animate the div rather than the tr
//as slidedown and slideup don't work on table rows
</script>
While this works it has the problem that if you run the mouse over multiple rows it sets up an enormous jiggly mess that can run for a long time until all of the animations finish. What I want to do is add a timeout so the animation doesn't start for a second or so after entering the <tbody>. If the mouse leaves the <tbody> before the animation is triggered it should be cancelled. When the mouse pointer leaves a <tbody> the slideUp effect should also be delayed by the same amount - My hope with this last requirement is that if you move down from one <tbody> to the next the slideDown and slideUp effects will occur at the same time so it just appears that the title row between them is moving up (I hope this makes some sort of sense). I have tried several ways of doing this but have been unsuccessful. My best effort is as follows;
var timer;
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
div = $(this);
timer = setTimeout("div.slideDown();",1000);
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
clearTimeout(timer);
div = $(this);
setTimeout("div.slideUp();",1000);
});
});
};
This almost works. If I quickly enter then leave a row, no animation occurs. If I enter a row and wait 1 second the next row slides down as planned. If I then exit the row to the side then the hidden row slides up 1 second later as planned. But, if I enter the row below things go wrong. The new row slides into view as expected after 1 second but the old row persists. My assumption is that my timer variable is being unintentionally destroyed. I tried being a bit more specific about the process by having an array of timers and assigning a specific one for each row but this made no difference. Javascript is not my strong suit as you may be able to tell.
Try using the hoverIntent plugin instead of attempting to simulate "delayed hovering" with mouseenter and mouseleave. I almost always use hoverIntent instead of plain hover.
OK, I finally solved this (and learned a lot too).
The code as provided works if I replace div with div2 in the mouseleave part of the code. Using the same variable name for up and down resulted in the animation not occurring. The only problem is that if I moused over numerous rows quickly I would still get unexpected results as this one variable name gets overused and abused.
My solution is to provide each .slide row with a unique id like so;
<tr class='slide'><div class='hidden'>Surprise!</div></tr>
I then use this id to generate a dynamic variable name using eval and reference this in a string in setTimeout. My final code looks like this.
var timer;
function setupEventHandlers() {
$('.group').mouseenter(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
id = this.id;
eval("divdown_" + id + " = $(this);");
downstring = "divdown_" + id + ".slideDown();";
timer = setTimeout(downstring,1000);
});
});
$('.group').mouseleave(function() {
var tr = $(this).children('tr.slide');
tr.find("div.hidden").each(function() {
clearTimeout(timer);
id = this.id;
eval("divup_" + id + " = $(this);");
upstring = "divup_" + id + ".slideUp();";
setTimeout(upstring,1000);
});
});
};
and works beautifully (in firefox at least, I'm too scared to try IE yet - I'm going to the gym instead).

Categories

Resources