Jump to content

[SOLVED] prevent select from selecting an item during blur event


shutat

Recommended Posts

I have four select boxes that I'm switching using the arrow keys (key down event).  I'd like to be able to select an item, then cancel and move onto another select, but whenever I try it, the onchange event is triggered in the select that I blurred.  I have a common handler for all four selects during the onchange event.

 

The onfocus handler was an attempt to set the selectedIndex property to 0, but it didn't matter whether I tried it within that function or inside of the keyboard handler... neither seemed to help.

 

<select id="c_cmd" size="1" onfocus="setIdx(this.id);" onchange="doCmd(this.id);">...</select>
...
<select id="c_itm" size="1" onfocus="setIdx(this.id);" onchange="doCmd(this.id);">...</select>

 

 

switch(evt.keyCode) {
   case 37:  switch(activeSel) {
                    case 1: docu...("c_cmd").selectedIndex = 0;
                            docu...("c_itm").focus();
                            activeSel = 4;
                            break;
                    ...
                    case 4: docu...("c_itm").selectedIndex = 0;
                            docu...("c_cmd").focus();
                            activeSel = 1;
                            break;
                } break;

   case 39: ...
}

 

I tried the above and thought it was working, but if I had selected an item in the list and then decided to choose another select box, the onchange for the prior select box fires.

 

Is there a way to ensure that the select boxes that aren't desired won't fire the onchange event?  onblur doesn't seem to work either.

 

TIA

Link to comment
Share on other sites

I've read your post a few times now and am still perplexed by what you arereally doing - I suspect there is probably a better way to accomplish what you are doing by changing the functionality in your "working" functions. Posting the code for a working page would be helpful to see the problem first hand.

 

I tried building a test page to replicate what I think your problem is, but I couldn't create the problem. I have an onchange event for the select lists and I also have an onkeydown event. The onkeydown event changes the value of the select field and then changes focus to the other select list. When that happens the onchange event does not fire - it only fires when the user changes the value, not when the functins hnage the value.

 

Here is the test page which includes code that I could have used to suppress the onchange event if it was fired from changing the vlaue in code (commented out)

<html>
<head>

  <script type="text/javascript">

//  var runOnChange = true;

  function s_onchange()
  {
//    if (runOnChange)
//    {
      alert('Run on change code');
//    }
//    else
//    {
//      runOnChange = true;
//    }
  }

  function s_onkeydown(sObj)
  {
    sObj.value = (sObj.selectedIndex==1) ? 'one' : 'two';
    sObj.blur();
    if (sObj.name=='test1')
    {
        document.forms[0].test2.focus();
    }
    else
    {
        document.forms[0].test1.focus();
    }
//    runOnChange = false;
  }

  </script>
</head>

<body>
<form action="">  
  <select name="test1" onchange="s_onchange();" onkeydown="s_onkeydown(this);">
    <option value='one'>one</option>
    <option value='two'>two</option>
  </select>
  <br>
  <select name="test2" onchange="s_onchange();" onkeydown="s_onkeydown(this);">
    <option>one</option>
    <option>two</option>
  </select>
</form>
</body>
</html>

Link to comment
Share on other sites

I've read your post a few times now and am still perplexed by what you arereally doing

lol; you aren't the only one - I'm at a loss myself. :)  Thank you for the response.  I tried to create a page from what I could remember, but I don't have access to the original code at the moment.

 

I've copied and pasted your code as well and will play around with it once I log off.

 

<html>
<head>
<style type="text/css">
select { width: 100px }
</style>

<script language="javascript">

var idx = 1;

function processSel(id) {

   var docs = document.getElementById(id);
   var r_id = document.getElementById("res");

   switch(docs.id) {
      case "sel_1": switch(docs.options[docs.selectedIndex].value) {
                       case "cmd 1": r_id.innerHTML = "ID: " + docs.id + "   VALUE: " + docs.options[docs.selectedIndex].value;
                                     break;
                       case "cmd 2": r_id.innerHTML = "ID: " + docs.id + "   VALUE: " + docs.options[docs.selectedIndex].value;
                                     break;
                       case "cmd 3": r_id.innerHTML = "ID: " + docs.id + "   VALUE: " + docs.options[docs.selectedIndex].value;
                                     break;
                    } break;
      case "sel_2": //alert(docs.options[docs.selectedIndex].value);
                    break;
      case "sel_3": //alert(docs.options[docs.selectedIndex].value);
                    break;
      case "sel_4": //alert(docs.options[docs.selectedIndex].value);
                    break;
   }   
}

function keyB(evt) {

   try {

      switch(evt.keyCode) {
         case 37: switch(idx) {
                     case 1: idx = 4; 
                             document.getElementById("sel_4").focus();
                             break;
                     case 2: idx = 1;
                             document.getElementById("sel_1").focus();
                             break;
                     case 3: idx = 2;
                             document.getElementById("sel_2").focus();
                             break;
                     case 4: idx = 3;
                             document.getElementById("sel_3").focus();
                             break;
                  } break; 

         case 39: switch(idx) {
                     case 1: idx = 2; 
                             document.getElementById("sel_2").focus();
                             break;
                     case 2: idx = 3;
                             document.getElementById("sel_3").focus();
                             break;
                     case 3: idx = 4;
                             document.getElementById("sel_4").focus();
                             break;
                     case 4: idx = 1;
                             document.getElementById("sel_1").focus();
                             break;
                  } break; 
                      
      }
   }

   catch(e) { alert("oops"); }
}

</script>
</head>
<body onkeydown="keyB(event)">
<div id="res">.</div>
<form name="f">
<select id="sel_1" size="1" onchange="processSel(this.id);" onblur="this.selectedIndex=0;">
<option value="-- sel1">-- sel1</option>
<option value="cmd 1">cmd 1</option>
<option value="cmd 2">cmd 2</option>
<option value="cmd 3">cmd 3</option>
</select>

<select id="sel_2" size="1" onchange="processSel(this.id);" onblur="this.selectedIndex=0;">
<option value="-- sel2">-- sel2</option>
<option value="cmd 1">cmd 1</option>
</select>

<select id="sel_3" size="1" onchange="processSel(this.id);" onblur="this.selectedIndex=0;">
<option value="-- sel3">-- sel3</option>
</select>

<select id="sel_4" size="1" onchange="processSel(this.id);" onblur="this.selectedIndex=0;">
<option value="-- sel4">-- sel4</option>
</select>
</form>
</body>
</html>

 

The above is similar to what I was doing, but I changed a few things to try and replicate what the problem was.  Select an item, other than index 0 in the first select, and then use the left and right arrow keys alone.

 

IE6, at least, doesn't seem to be affected, but in Firefox 3 and Opera 9.6, if you use the left and right arrow keys, the value above the select *should* change. 

 

I want to be able to cycle through any of the four selects, choose an item in any of the selects, yet be able to "cancel" any choice by moving to another select.  A "choice" should be made only if the mouse onclick event is triggered or the enter key is pressed, or at least that's what I'm trying to make it do.

 

Any ideas?

TIA

Link to comment
Share on other sites

OK, I think I am starting to understand. I ran the code above and see the same results in IE7 and FF3. Don't have access to IE at the moment. I see the same results in IE6 and FF3. If I select a value in the first field text is displayed above it. But, when I use left/right arrow keys the field is reset to the 0 index and the text remains.

 

It would really help if you list the steps you would take and the resulting action you want to occur. But, I think I'm starting to understand. Should only 1 select field have a value and no others? I think adding the keydown event to the body and using a global variable to track the current field will run into problems as well.

 

Try this:

<html>
<head>
<style type="text/css">
select { width: 100px }
</style>

<script language="javascript">

function processSel(fieldObj)
{
   if(fieldObj.selectedIndex==0)
   {
      var resultHTML = '.';
   }
   else
   {
      var resultHTML = 'ID: ' + fieldObj.id + '   VALUE: ' + fieldObj.options[fieldObj.selectedIndex].value;
   }

   divID = 'res' + fieldObj.id.substr(4);
   document.getElementById(divID).innerHTML = resultHTML;
   return;
}

function blurThis(fieldObj)
{
   fieldObj.selectedIndex = 0;
   processSel(fieldObj);
   return;
}

function keyB(evt, fieldObj) {

   try {

      if (evt.keyCode==37 || evt.keyCode==39)
      {
          var index = parseInt(fieldObj.id.substr(4));
          index = (evt.keyCode==37) ? (index-1) : (index+1) ;
          if (index==0) { index = 4; }
          if (index==5) { index = 1; }

          document.getElementById('sel_'+index).focus();
      }
   }

   catch(e) { alert("oops"); }

   return;
}


</script>
</head>
<body>
<div id="res1">.</div>
<div id="res2">.</div>
<div id="res3">.</div>
<div id="res4">.</div>

<form name="f" id="f">
<select id="sel_1" size="1" onchange="processSel(this);" onblur="blurThis(this);" onkeydown="keyB(event, this);">
<option value="-- sel1">-- sel1</option>
<option value="cmd 1">cmd 1</option>
<option value="cmd 2">cmd 2</option>
<option value="cmd 3">cmd 3</option>
</select>

<select id="sel_2" size="1" onchange="processSel(this);" onblur="blurThis(this);" onkeydown="keyB(event, this);">
<option value="-- sel2">-- sel2</option>
<option value="cmd 1">cmd 1</option>
<option value="cmd 2">cmd 2</option>
<option value="cmd 3">cmd 3</option>
</select>

<select id="sel_3" size="1" onchange="processSel(this);" onblur="blurThis(this);" onkeydown="keyB(event, this);">
<option value="-- sel3">-- sel3</option>
<option value="cmd 1">cmd 1</option>
<option value="cmd 2">cmd 2</option>
<option value="cmd 3">cmd 3</option>
</select>

<select id="sel_4" size="1" onchange="processSel(this);" onblur="blurThis(this);" onkeydown="keyB(event, this);">
<option value="-- sel4">-- sel4</option>
<option value="cmd 1">cmd 1</option>
<option value="cmd 2">cmd 2</option>
<option value="cmd 3">cmd 3</option>
</select>
</form>
</body>
</html>

Link to comment
Share on other sites

It would really help if you list the steps you would take and the resulting action you want to occur. But, I think I'm starting to understand. Should only 1 select field have a value and no others? I think adding the keydown event to the body and using a global variable to track the current field will run into problems as well.

 

I'm working a game actually, where each of the selects will represent commands the player can take.  The first select is static, but the others will be filled once conditions are met.  The first item in each select is just a moniker of sorts to show what each of the commands are, so element 0 wouldn't ever be acted upon. 

 

Thanks a lot for the great tips; I was looking for a way to compact my version of the switch that you did within your version of the keyB function, and your method is nice and clean.  I think your select handler is going to help out a lot too.

 

I'm going to go ahead and marked this as solved; I really appreciate your help!  Thank you. 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.