Solved

Show and hide only reflects when alert function is called

Posted on 2008-06-23
18
1,228 Views
Last Modified: 2012-06-27
Hi,
I am facing a very unusual problem.
what I am trying to achieve is to sort DataGrid at client side using Javascript. Now if the number of rows are greater, it takes a while to sort. So I placed a div which will give user the message "Please wait while the data is sorted!..".
I am simply showing and hiding the div by using the display attribute.
Whats weird is that the user only sees the div if I add an alert in the code else the user does not see it.
I am attaching the code snippet I am using.
divWait.style.display ="inline";

//alert('Hi')

Sort function ..

divWait.style.display ="none";

Open in new window

0
Comment
Question by:senderm
  • 8
  • 7
18 Comments
 
LVL 82

Expert Comment

by:hielo
ID: 21850268
Instead of:
divWait.style.display ="inline";

try:
divWait.style.display ="";

OR:
divWait.style.display ="block";
0
 

Author Comment

by:senderm
ID: 21850328
Thanks for your response.
But the problem is that my code only works if there is an alert.
Otherwise the user never sees the the Div.
0
 
LVL 82

Expert Comment

by:hielo
ID: 21850355
OK. Odd indeed. Then try putting this at the end of your sort function instead:
divWait.style.display ="none";
0
 

Author Comment

by:senderm
ID: 21850387
Please find the full code snippet
	var a; // array ref

	var ASC = false; //bool for ASC og DESC sort

	var col; // the column to be sorted

	var dgID;

	function sort(sortCol,rowStart,tableID)

	{

		document.body.style.cursor = "wait";

                ShowHide('divWait');

		dgID = tableID;

		a = new Array();

		table = document.getElementById(tableID);

		y = table.getElementsByTagName('tr').length - 1;

		// length has been reduced by 1 becuase we want to exclude the footer.

		//put all tr in an array

		

		

		for(x=rowStart;x<y;x++)

		{

			

			a.push(table.rows[x]);

		}

	

		//ensure that sorting will be done ASC if sortcolumn changes

		if(col != sortCol)

		{

		col = sortCol;

		ASC = false;

		}

		var dt1 = new Date();

		//alert(dt1);

		//just calling sort

		a.sort(Sort);

		var dt2= new Date();

		//alert(dt2);

		//just calling updateTable

		updateTable(rowStart);

		

		//changes between ASC and DESC sort order

		if(ASC)

		ASC = false;

		else

		ASC = true;

		

		ApplyStyle();

		ShowHide('divWait');

		document.body.style.cursor = 'default';
 

	}

	

	//sorts numericly or letters

	function Sort(h,l)

	{

		var Unformatted_h = fnUnformat(h.getElementsByTagName('td')[col].innerHTML)

		var Unformatted_l = fnUnformat(l.getElementsByTagName('td')[col].innerHTML)

		

		if(ASC)

		{

			if (isDate(Unformatted_h) && isDate(Unformatted_l))

			{

				var aToBeCompared = new Date(Unformatted_h);

				var bToBeCompared = new Date(Unformatted_l);

				if(aToBeCompared < bToBeCompared) sortValue=-1;

				else if(aToBeCompared > bToBeCompared) sortValue =1;

				else sortValue =0;

				return sortValue;

			}

			else if(!validNumber(Unformatted_h) || !validNumber(Unformatted_l) )

			{		  	

				if (Unformatted_h.toLowerCase() < Unformatted_l.toLowerCase()) sortValue=-1;

 				else if (Unformatted_h.toLowerCase() > Unformatted_l.toLowerCase()) sortValue=1;

  				else sortValue=0;

  				return sortValue;	

			}

			return Unformatted_h - Unformatted_l

		}

		else

		{

			if (isDate(Unformatted_h) && isDate(Unformatted_l))

			{

				var aToBeCompared = new Date(Unformatted_h);

				var bToBeCompared = new Date(Unformatted_l);

				if(aToBeCompared > bToBeCompared) sortValue=-1;

				else if(aToBeCompared < bToBeCompared) sortValue =1;

				else sortValue =0;

				return sortValue;

			}

			else if(!validNumber(Unformatted_h) || !validNumber(Unformatted_l) )

			{		  	

			if (Unformatted_h.toLowerCase() > Unformatted_l.toLowerCase()) sortValue=-1;

 			else if (Unformatted_h.toLowerCase() < Unformatted_l.toLowerCase()) sortValue=1;

  			else sortValue=0;

  			return sortValue;	

			}

			return Unformatted_l -  Unformatted_h

		}

		return 0;

	}

	

	//validates if data is number or !

	function validNumber(strValue)

	{

	var regExp  =  /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;

	return regExp.test(strValue);

	}

	

	

	//update table

	function updateTable(rowStart)

	{

		ta = table.getElementsByTagName('tr')[0];

		var headercolumns = ta.getElementsByTagName('td')

		for(var i=0;i<headercolumns.length;i++)

		{

			if(i!=col)

			{

				headercolumns[i].style.backgroundColor = "C2E4F3";

			}

			else

			{

				headercolumns[i].style.backgroundColor = "gainsboro";

			}

		}

		//var col_sorted = ta.getElementsByTagName('td')[col];

		//col_sorted.style.backgroundColor = "gainsboro";

		child = table.getElementsByTagName('tr')[table.getElementsByTagName('tr').length -1];

		// length has been reduced by 1 becuase we want to exclude the footer.

		for(x=rowStart;x<y;x++)

		{

			ta.parentNode.appendChild(a[x-rowStart]);

		}

		ta.parentNode.appendChild(child);

	}
 

function fnUnformat(amount)

{

	while(amount.lastIndexOf(",") != -1)

		{

			amount = amount.replace(",","");

		}

	if(amount.lastIndexOf("$") != -1)

		{

			amount = amount.replace("$","");

		}

	if(amount.lastIndexOf(" %") != -1)

	{

		amount = amount.replace(" %","");

	}

	//This is done to check if the currency is negative ($100) should be -100.	

	if(amount.lastIndexOf("(") != -1)

		{

			amount = amount.replace("(","-");

		}

	if(amount.lastIndexOf(")") != -1)

		{

			amount = amount.replace(")","");

		}			

	return amount;	
 

}
 

function ApplyStyle()

{

	var style_class = true;

	var tab = document.getElementById(dgID); 

	var ta = tab.getElementsByTagName('tr');

	var count = ta.length;

	// length has been reduced by 1(in the for loop) becuase we want to exclude the footer.
 

	for(i=1;i<count-1;i++)

	{

			

			if(i%2 == 0)

			{

			ta[i].style.backgroundColor = "#E7F7FF" ;

			style_class = false;

			}

			else

			{

			ta[i].style.backgroundColor = "#F3FBFF" ;

			style_class = true;

			}
 

	}

}
 
 

//*****************************************************************************

// Function to determine whether it's a IETF recognized date string

//*****************************************************************************

function isDate(x)

{

	var xDate;

	xDate = new Date(x);

	if (xDate.toString() == 'NaN' || xDate.toString() == 'Invalid Date')

		return false;

	else

		return true;

}
 

/*******************************************************************************************

Name		:	fnHideElm	

Description	:	This functions hides a particular element on the page.

Parameters	:	elm	: The element.

********************************************************************************************/  

function fnHideElm(elm)

{

	if(document.getElementById(elm) != null)

	{

	

		document.getElementById(elm).style.display = "none";

	}

}
 

/*******************************************************************************************

Name		:	fnShowElm

Description	:	This functions hides a particular element on the page.

Parameters	:	elm	: The elementt.

********************************************************************************************/  

function fnShowElm(elm)

{

	if(document.getElementById(elm) != null)

	{

		document.getElementById(elm).style.display = "inline";

	}

}
 
 

function ShowHide(_ControlId)

{

   var div = document.getElementById(_ControlId);

   if ( div.style.display == 'none' )

     {

      div.style.display = 'block'

      }

   else

    {

      div.style.display = 'none'

    }

    window.event.returnValue = false;

}

Open in new window

0
 
LVL 82

Expert Comment

by:hielo
ID: 21850420
Try changing this:
window.event.returnValue = false;

to:
return true;
0
 
LVL 19

Expert Comment

by:Albert Van Halen
ID: 21850476
Probably your sort function is very quick.
What if you comment out divWait.style.display ="none"; and see if the waiting div gets displayed...
0
 

Author Comment

by:senderm
ID: 21850564
I hope my sort function was real quick ;-)
changing it to true did not work.
Well the only purpose to show this is because at times it takes more than 3-4 seconds which on the web is quite substantial.
If I comment out hiding the div, the div does get displayed.
What I am wondering is that why does the div gets displayed if I interrupt my code with alert and not otherwise.
Any ideas?
Also another question of interest here might be if Array.Sort function is synchronous or asynchronous?

Thanks again for following up.
0
 
LVL 82

Expert Comment

by:hielo
ID: 21850586
>>What I am wondering is that why does the div gets displayed if I interrupt my code with alert and not otherwise.
Exactly because of that, You "interrupt" the execution. The javascript waits for you to dismiss the alert box before continuing. IF your data set is too small so that the sort is almost instantaneous, you will not notice the change in the div display.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:senderm
ID: 21850620
But my data set is not small. As I wrote in my earlier comment that it takes more than 3-4 seconds to sort.
0
 
LVL 82

Expert Comment

by:hielo
ID: 21851241
After some testing, it turns out that immediately after the first ShowHide is executed, the script engine gets to this line:
a.sort(Sort);

before the browser gets a chance to update the display. Once it is busy sorting, the browser does not bother to update the display until after the sort is done. I've seen this behaviour before, but not with array sorting - with document.write statements while querying a db, but the concept is practically the same.
To "solve" the problem you will need to first call ShowHide outside of
function sort(sortCol,rowStart,tableID), then wait for 10 milliseconds or so before calling function sort(sortCol,rowStart,tableID). On the code you posted, I don't see where you are calling the function on line 6, but where ever you are calling it from, it should now be:
ShowHide('divWait');
setTimeout("sort('','','')",10);//provide the appropriate parameters to sort()
ShowHide('divWait');

You will also need to get rid of ShowHide() from within the sort() function.
0
 

Author Comment

by:senderm
ID: 21855917
Hi,
Thanks alot!
But it seems like it's just not one of my days. I tried and tried to settimeout for 10 miliiseconds to 5 seconds, but it just does not display the div.
For your reference, I updated the code to the attached snippet.
Also the function is sort is called from onclick of the headers of the table.

function sort(sortCol,rowStart,tableID)

	{

		//alert(tableID);

		document.body.style.cursor = "wait";

		fnShowElm('divWait');

		//alert("sortTable('"+ sortCol +"','" + rowStart +"','" + tableID +"')");

	    setTimeout("sortTable('"+ sortCol +"','" + rowStart +"','" + tableID +"')",3000	);

		fnHideElm('divWait');

		document.body.style.cursor = 'default';

	}

	

	function sortTable(sortCol,rowStart,tableID)

	{

			

		dgID = tableID;

		a = new Array();

		//alert(tableID);

		table = document.getElementById(tableID);

		y = table.getElementsByTagName('tr').length - 1;

		// length has been reduced by 1 becuase we want to exclude the footer.

		//put all tr in an array

		for(x=rowStart;x<y;x++)

		{

			

			a.push(table.rows[x]);

		}

	

		//ensure that sorting will be done ASC if sortcolumn changes

		if(col != sortCol)

		{

		col = sortCol;

		ASC = false;

		}

		

		//just calling sort

		a.sort(Sort);

	

		//just calling updateTable

		updateTable(rowStart);

		

		//changes between ASC and DESC sort order

		if(ASC)

		ASC = false;

		else

		ASC = true;

		

		ApplyStyle();

		//IsSortingDone = true;

		

	}

	

	

Open in new window

0
 
LVL 82

Expert Comment

by:hielo
ID: 21856889
On what you posted, move lines 8 and 9 to the end of sortTable(). setTimeout is asynchrnously, that's why those two lines execute immediately.
0
 

Author Comment

by:senderm
ID: 21857042
Doesn't work.
I worked around a solution which is not the best. I am opening a modal dialog window which shows a progress bar.
Thanks for looking into this.
0
 
LVL 82

Expert Comment

by:hielo
ID: 21857310
attached are the two functions as they should be. If it does not work, most likely the parameters are probably references (as opposed to values) that are last when you pass them via the setTimeout function. Do you have a public url for this?
	function sort(sortCol,rowStart,tableID)

	{

		document.body.style.cursor = "wait";

          ShowHide('divWait');

		setTimeout("hielo('"+sortCol+"','"+rowStart+"','"+tableID+"')", 1000);

	}
 

	function hielo()

	{

		dgID = tableID;

		a = new Array();

		table = document.getElementById(tableID);

		y = table.getElementsByTagName('tr').length - 1;

		// length has been reduced by 1 becuase we want to exclude the footer.

		//put all tr in an array

		

		

		for(x=rowStart;x<y;x++)

		{

			

			a.push(table.rows[x]);

		}

	

		//ensure that sorting will be done ASC if sortcolumn changes

		if(col != sortCol)

		{

		col = sortCol;

		ASC = false;

		}

		var dt1 = new Date();

		//alert(dt1);

		//just calling sort

		a.sort(Sort);

		var dt2= new Date();

		//alert(dt2);

		//just calling updateTable

		updateTable(rowStart);

		

		//changes between ASC and DESC sort order

		if(ASC)

		ASC = false;

		else

		ASC = true;

		

		ApplyStyle();

		ShowHide('divWait');

		document.body.style.cursor = 'default';

 

	}

Open in new window

0
 

Author Comment

by:senderm
ID: 21857483
Do you mean to say that it won't work if the value are references?
I am sorry, the URL is not public.
0
 
LVL 82

Accepted Solution

by:
hielo earned 500 total points
ID: 21857689
>>Do you mean to say that it won't work if the value are references
Correct. References are NOT strings. This:
setTimeout("hielo('"+sortCol+"','"+rowStart+"','"+tableID+"')", 1000);

is equivalent to:
hielo('somevalue', 'somevalue', 'somevalue');

all of the 'somevalue' parameters are now string objects, not the original references. What you can do is store the references in global variables.
		window.hielo_sortCol = null;

		window.hielo_rowStart=null;

		window.hielo_tableID = null;

	function sort(sortCol,rowStart,tableID)

	{

		hielo_sortCol = sortCol;

		hielo_rowStart=rowStart;

		hielo_tableID = tableID;

		document.body.style.cursor = "wait";

          ShowHide('divWait');

		setTimeout("hielo()", 1000);

	}

 

	function hielo()

	{

		sortCol  = hielo_sortCol;

		rowStart = hielo_rowStart;

		tableID  = hielo_tableID;
 

		dgID = tableID;

		a = new Array();

		table = document.getElementById(tableID);

		y = table.getElementsByTagName('tr').length - 1;

		// length has been reduced by 1 becuase we want to exclude the footer.

		//put all tr in an array

		

		

		for(x=rowStart;x<y;x++)

		{

			

			a.push(table.rows[x]);

		}

	

		//ensure that sorting will be done ASC if sortcolumn changes

		if(col != sortCol)

		{

		col = sortCol;

		ASC = false;

		}

		var dt1 = new Date();

		//alert(dt1);

		//just calling sort

		a.sort(Sort);

		var dt2= new Date();

		//alert(dt2);

		//just calling updateTable

		updateTable(rowStart);

		

		//changes between ASC and DESC sort order

		if(ASC)

		ASC = false;

		else

		ASC = true;

		

		ApplyStyle();

		ShowHide('divWait');

		document.body.style.cursor = 'default';

 

	} 

Open in new window

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Developer tools in browsers have been around for a while, yet they are still heavily underused by developers. Developers still fix html or CSS then refresh page to see effect, or they put alert or debugger in JavaScript and then try again and again …
It’s a strangely common occurrence that when you send someone their login details for a system, they can’t get in. This article will help you understand why it happens, and what you can do about it.
This video teaches viewers how to create their own website using cPanel and Wordpress. Tutorial walks users through how to set up their own domain name from tools like Domain Registrar, Hosting Account, and Wordpress. More specifically, the order in…
Use Wufoo, an online form creation tool, to make powerful forms. Learn how to choose which pages of your form are visible to your users based on their inputs. The page rules feature provides you with an opportunity to create if:then statements for y…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now