SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member
    Join Date
    Feb 2004
    Location
    Baltimore
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Very simple focus() problem

    Hi all,
    This is a simple DOM focus() problem, but I just can't get this script functioning. I need this to work with Firefox and Netscape, as my IE function works as designed.

    I have a date validation function, which I've pared down to just give you the part which is giving me trouble:

    <script>
    function validateDate(dt){
    obj = document.getElementById(dt.id);
    obj.focus();
    }
    </script>

    <form action=index.php method=post>

    <input type=text name=date1 id=date1
    onBlur="if(this.value.length > 0){validateDate(this);}">

    <input type=text name=date2 id=date2
    onBlur="if(this.value.length > 0){validateDate(this);}">

    <input class=field3 type=submit value="View Records">

    </form>

    I expect when I enter data into date1 or date2, then tab away, the focus will be returned to either date1 or date2. However, focus gets transferred to the next form element. What am I doing wrong here?

    Thanks!

  2. #2
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    obj = document.getElementById(dt.id);

    That is redundant. You are passing an html element reference to the surrounding function, which is then stored in the variable dt. You then take that reference and get its id: dt.id. Then you use the id in the getElementById() function to get a reference to the html element. But, the html reference is what you started with!

    I'm not sure why focus() won't work in FF, but the good news is that you don't want it to work. Think about what happens when two elements call your onblur event handler. First, the user types something into the first input, and then clicks on the second input. That causes the first input to lose focus and the second input to gain focus. So, the onblur event for the first element fires, and the focus is put back on the first element. But, in so doing that, the second element which had the focus now loses its focus causing its onblur event to fire, which puts the focus back on the second element, and so on, and so on, which means you get caught in an infinite loop. onblur is notorious for causing infinite loops like that.
    Last edited by 7stud; Feb 17, 2005 at 22:06.

  3. #3
    SitePoint Member
    Join Date
    Feb 2004
    Location
    Baltimore
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The javascript function I posted is not the real function I'm using, just a pared down one to focus on the issue I'm having. I realize what I posted would cause a user to never be able to get out of the textbox.

    It seems like dt.focus(); should work, and it does in Internet Explorer. But it doesn't work in FF or Netscape. I have no idea why. That's why I was messing around with document.getElementByID(dt.id);

    Do I have to do something like: document.dt.focus() or document.all[dt].focus()? Nothing seems to work.

  4. #4
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    <!DOCTYPE html
      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" 
      xml:lang="en" lang="en">
    <head>
    <title>html and javascript</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <meta http-equiv="Content-Style-Type" content="text/css" /> 
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    
    <style type="text/css">
    <!-- 
    
    
    
    -->
    </style>
    <script type="text/javascript" language="javascript">
    <!-- Hide from browsers without javascript
    
    window.onload=function()
    {
    	document.getElementById("tb0").focus();
    	document.getElementById("b0").onclick=function()
    	{
    		document.getElementById("tb2").focus();
    	};
    };
    
    // End hiding -->
    </script>
    </head>
    <body>
    
    <input type="text" id="tb0" />
    <input type="text" id="tb1" />
    <input type="text" id="tb2" />
    <input type="button" id="b0" name="b0" value="a button" />
    
    </body>
    </html>

  5. #5
    SitePoint Member
    Join Date
    Feb 2004
    Location
    Baltimore
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the code 7stud. However, it looks like what I'm trying to do simply isn't allowed in Netscape and Firefox. Here's your modified code
    Code:
    <!DOCTYPE html
      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" 
      xml:lang="en" lang="en">
    <head>
    <title>html and javascript</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <meta http-equiv="Content-Style-Type" content="text/css" /> 
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    
    <style type="text/css">
    <!-- 
    
    
    
    -->
    </style>
    <script type="text/javascript" language="javascript">
    <!-- Hide from browsers without javascript
    
    function focusIt(name)
    {
    	document.getElementById(name).focus();
    };
    
    
    // End hiding -->
    </script>
    </head>
    <body>
    
    <input type="text" id="tb0" />
    <input type="text" id="tb1" onBlur="focusIt('tb1')" />
    <input type="text" id="tb2" />
    <input type="button" id="b0" name="b0" value="a button"/>
    
    </body>
    </html>
    This should keep focus in tb1 once it gets focus. This will work in IE (and subsequently make your browser window unusable), but it will not work in Firefox or Netscape.

    here's the actual validateDate() function I'm using, now that I've given up on making those two browsers re-focus:
    Code:
    /**
     * DHTML date validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
     */
    
    N   = (document.layers) ? true:false;                 // netscape 4
    I   = (document.all) ? true:false;                    // ie4+
    DOM = ((document.getElementById)&&(!I))?true:false;   // ns6 etc.
    
    // Declaring valid date character, minimum year and maximum year
    var dtCh= "/";
    var minYear=2000;
    var theYear = new Date();
    var maxYear=theYear.getFullYear();
    var today=theYear.getDate();
    var todayMonth=theYear.getMonth();
    
    function isInteger(s){
    	var i;
        for (i = 0; i < s.length; i++){   
            // Check that current character is number.
            var c = s.charAt(i);
            if (((c < "0") || (c > "9"))) return false;
        }
        // All characters are numbers.
        return true;
    }
    
    function stripCharsInBag(s, bag){
    	var i;
        var returnString = "";
        // Search through string's characters one by one.
        // If character is not in bag, append to returnString.
        for (i = 0; i < s.length; i++){   
            var c = s.charAt(i);
            if (bag.indexOf(c) == -1) returnString += c;
        }
        return returnString;
    }
    
    function daysInFebruary (year){
    	// February has 29 days in any year evenly divisible by four,
        // EXCEPT for centurial years which are not also divisible by 400.
        return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
    }
    function DaysArray(n) {
    	var data = new Array();
    	for (var i = 1; i <= n; i++) {
    		data[i] = 31
    		if (i==4 || i==6 || i==9 || i==11) {data[i] = 30}
    		if (i==2) {data[i] = 29}
       } 
       return data
    }
    
    
    function isDate(dtStr){
    	var daysInMonth = DaysArray(12)
    	var pos1=dtStr.indexOf(dtCh)
    	var pos2=dtStr.indexOf(dtCh,pos1+1)
    	var strMonth=dtStr.substring(0,pos1)
    	var strDay=dtStr.substring(pos1+1,pos2)
    	var strYear=dtStr.substring(pos2+1)
    	strYr=strYear
    	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
    	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
    	for (var i = 1; i <= 3; i++) {
    		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
    	}
    	month=parseInt(strMonth)
    	day=parseInt(strDay)
    	year=parseInt(strYr)
    	if (pos1==-1 || pos2==-1){
    		alert("The date format should be : mm/dd/yyyy")
    		return false
    	}
    	if (strMonth.length<1 || month<1 || month>12 || (year == maxYear && month > (todayMonth + 1))){
    		alert("Please enter a valid month")
    		return false
    	}
    	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month] || (day > today && year == maxYear && month == (todayMonth+1))){
    		alert("Please enter a valid day")
    		return false
    	}
    	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
    		alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
    		return false
    	}
    	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
    		alert("Please enter a valid date")
    		return false
    	}	
    } 
    
    function validateDate(dt){
    	if (isDate(dt.value)==false){
    		if(I){
    			dt.focus();		
    		}
    		else if(N){
    			dt.value = '';
    		}	
    		else if(DOM){
    			dt.value = '';
    		}
    	}	
     }

  6. #6
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it's pretty clear that the way you want to use onblur will lock up your webpage, but there is no reason why you shouldn't be able to use onblur to put the focus some other element:
    Code:
    <script type="text/javascript" language="javascript">
    <!-- Hide from browsers without javascript
    
    window.onload=function()
    {
    	document.getElementById("tb0").onblur = function()
    	{
    		document.getElementById("tb2").focus();
    	}
    };
    
    // End hiding -->
    </script>
    </head>
    <body>
    
    <form action="" method="">
    
    <input type="text" id="tb0" />
    <input type="text" id="tb1" />
    <input type="text" id="tb2" />
    <input type="button" id="b0" name="b0" value="a button"/>
    
    </form>
    
    </body>
    </html>
    ...but it won't work in FF for some reason. Maybe it's a bug.


Bookmarks

Posting Permissions

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