www.webdeveloper.com
Results 1 to 9 of 9

Thread: Javascript have an order?

  1. #1
    Join Date
    Feb 2009
    Posts
    8

    Unhappy Javascript have an order?

    Hi. I am doing some major hair pulling over something.
    I have this div in every page of our site, hidden by default, that is a transparent layer of the whole page with a loading gif in the middle. I use it for forms since we have so many people hit submit over and over, so, onsubmit, I show the div, let the page do it's thing, then hide it again (or another page is presented).
    Works great on form pages, where they submit to themselves or another page.
    However, I have another page that's sort of an application (multiple tabs/divs), so it saves each field via ajax.
    Basically, you click on one of the tabs on the page to be presented with that information. There is an "edit" button that when clicked hides all static fields and shows their relevant input fields. There is a save that then switches all these back one at a time, saving the edited field value as it goes. This function, like my others, shows/hides the div at beginning and end:
    Code:
    function saveTabFields(tname){
    	document.getElementById('loader').style.display='';
    	var myDiv = document.getElementById(tname);
    	var inputArr = myDiv.getElementsByTagName("input");
    	var selectArr = myDiv.getElementsByTagName("select");
    	for(i=0; i<inputArr.length; i++){
    		if(inputArr[i].type!='radio' && inputArr[i].type!='checkbox' && inputArr[i].type!='hidden'){
    			if(document.getElementById('l2on').value=='0' && inputArr[i].name.substring(0,3)!="l2-")
    				saveEdit(inputArr[i].name,inputArr[i].name,document.getElementById(inputArr[i].name+"mod").value,document.getElementById(inputArr[i].name+"id").value,document.getElementById(inputArr[i].name+"call").value);
    			else if(document.getElementById('l2on').value=='1')
    				saveEdit(inputArr[i].name,inputArr[i].name,document.getElementById(inputArr[i].name+"mod").value,document.getElementById(inputArr[i].name+"id").value,document.getElementById(inputArr[i].name+"call").value);
    			if(in_array(inputArr[i].name,liquidAssets) || in_array(inputArr[i].name,nonLiquidAssets)){
    				updateAssets(inputArr[i].name);
    			}
    		}
    		if (navigator.appVersion.indexOf("Linux")==-1 && navigator.appVersion.indexOf("X11")==-1)
    			pausecomp(20);
    	}
    	for(i=0; i<selectArr.length; i++){
    		if (navigator.appVersion.indexOf("Linux")==-1 && navigator.appVersion.indexOf("X11")==-1)
    			pausecomp(100);
    		//alert(selectArr[i].name,selectArr[i].name,document.getElementById(selectArr[i].name+"mod").value,document.getElementById(selectArr[i].name+"id").value,document.getElementById(selectArr[i].name+"call").value);
    		if(document.getElementById('l2on').value=='0' && selectArr[i].name.substring(0,3)!="l2-")
    			saveEdit(selectArr[i].name,selectArr[i].name,document.getElementById(selectArr[i].name+"mod").value,document.getElementById(selectArr[i].name+"id").value,document.getElementById(selectArr[i].name+"call").value);
    		else if(document.getElementById('l2on').value=='1')
    			saveEdit(selectArr[i].name,selectArr[i].name,document.getElementById(selectArr[i].name+"mod").value,document.getElementById(selectArr[i].name+"id").value,document.getElementById(selectArr[i].name+"call").value);
    	}
    	if(tname == 't6' || tname == 't9'){
    		updateExpenses();
    		updateProposedExpenses();
    	}
    	document.getElementById('loader').style.display='none';
    }
    So basically, on save, show the 'loader' div, save each input via ajax, then hide the 'loader' div.
    Here's the problem, no matter how I do this (I've tried adding some sleep code between showing the loader and the rest, calling only he show loader line in this function and putting the rest in a function I then call using a setTimout, etc) it seems that everything in this function is called BEFORE the first line! The div always comes up, but it just flashes up after all the fields are saved and swapped back to static, as if the first line to show the div was just before the last line to hide it.
    Any suggestions? I think I've tried everything!

  2. #2
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    It's hard to tell with the code you've provided. Is the saveEdit() function initiating an AJAX call? Unless you specify it, AJAX calls are asynchronous, meaning your scripts continue to execute as the AJAX call is made. Can we see the code for the other functions used in the saveTabFields() function?

  3. #3
    Join Date
    Feb 2009
    Posts
    8

    No problem

    Sure, here is the rest, the ones I did not put in are long but simply take a couple fields and calculate another. To me it would seem even if AJAX is asynchronous that it just means when ajax is done the REMAINING code keeps executing, but since I show the "loader" div before any ajax is called, should that not still happen first? Thanks again:

    Code:
    var httpObject = getHTTPObject();
    // Get the HTTP Object
    function getHTTPObject(){
    	if (window.ActiveXObject) 
    		return new ActiveXObject("Microsoft.XMLHTTP");
    	else if (window.XMLHttpRequest) 
    		return new XMLHttpRequest();
    	else {
    		alert("Your browser does not support AJAX.");
    		return null;
    	}
    }
    
    //Function to swap input field and static field visibility after ajax saves field
    function updateCLValues(field,element){
    	document.getElementById(element+"s").innerHTML = document.getElementById(field).value;
    	if(document.getElementById(field).type!='radio' && document.getElementById(field).type!='checkbox' && document.getElementById(field).type!='hidden'){
    		if(document.getElementById(element+"e").style.display == "none"){
    			document.getElementById(element+"s").style.display = "none";
    			document.getElementById(element+"e").style.display = "inline";
    		} else {
    			document.getElementById(element+"e").style.display = "none";
    			document.getElementById(element+"s").style.display = "inline";
    		}
    	}
    }
    
    //Ajax function to save new field value
    function saveEdit(field,element,module,rid,call){
    	if (httpObject != null) {
    		//alert ("/crmPortal/clVEProcessor.php?module="+module+"&id="+rid+"&field="+field+"&value="+document.getElementById(field).value);
    		httpObject.open("GET", "/crmPortal/clVEProcessor.php?module="+module+"&id="+rid+"&field="+field+"&value="+document.getElementById(field).value+"&function="+call+"&oppid=<?=$loan->id?>&primid=<?=$borrower->id?>", true);
    		httpObject.send(null);
    		httpObject.onreadystatechange = updateCLValues(field,element);
    	}
    }

  4. #4
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Ah, ok. When the saveTabFields() is called, it should show the "loading..." DIV. Now the trick is to hide the loading DIV after all the AJAX calls have completed. You can't start all the AJAX calls at once. You've got to do them one at a time. The saveTabFields() function starts one AJAX call. When that one finishes, the onreadystatechange function calls the second AJAX call. When that finishes, the onreadystatechange function calls the third ... and so forth until all the fields have been saved.

  5. #5
    Join Date
    Feb 2009
    Posts
    8

    Weird

    Thanks, but before you posted that I tried simplifying it by taking everything out and simply doing the following:
    Code:
    function saveTabFields(tname){
    	document.getElementById('loader').style.display='';
    	//The pausecomp function directly inserted for simplicity and testing
    	var date = new Date();
    	var curDate = null;
    	
    	do { curDate = new Date(); }
    	while(curDate-date < 2000);
    	//END inserting pausecomp
    	document.getElementById('loader').style.display='none';
    }
    This makes it even stranger. This should effectively show the loader div for 2 seconds then hide it again, right? No such luck, the same thing happens, only now it happens so fast you don't even see the loader div flash, just nothing. But if I comment all this too and just make the loader div show, that works! Am I just missing something totally simple?

  6. #6
    Join Date
    Feb 2009
    Posts
    8

    Solved

    At least solved for my needs.
    Apparently it did have something to do with what you mentioned, it's just that the pausecomp function I was using is apparently not working, so no matter what it was going directly from the show to hide lines since the ajax in between was asynchronous as you said.
    I had tried using setTimeout before in many other places, but I just tried it in another place I had not before now and I can get the effect I want, I used a setTimeout on the final line that re-hides the div!
    Thanks for all your help, any idea why the pausecomp code was not doing what I wanted it to do?

  7. #7
    Join Date
    Jan 2009
    Posts
    3,346
    Why don't you just call a function to hide the div after the last ajax call is finished?

  8. #8
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Quote Originally Posted by criterion9 View Post
    Why don't you just call a function to hide the div after the last ajax call is finished?
    Because AJAX calls do not finish in the same order they were instantiated if they are asynchronous.

  9. #9
    Join Date
    Jan 2009
    Posts
    3,346
    You would know how many calls you have made and thus when the last open connection is closed so it would work.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles