Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 02-04-2013, 04:20 AM   PM User | #1
rexhvn
New Coder

 
Join Date: Oct 2011
Posts: 49
Thanks: 0
Thanked 0 Times in 0 Posts
rexhvn is an unknown quantity at this point
Need assistance modifiying predictive text.

Hi guys,

I'm hoping to get some assistance. I've found below predictive text for my search function. Currently is works fine but I want to sleightly change it but having troubles.

1. Currently, when you search say '1', it will find all results with '1' in it. However I want it to only show what word starts with the '1' and go from each letter typed into the form.

IE: "SE"
REsult - "SEARCH"
NOT: "SEARCH" & "STREET" type thing.

2. When I currently search, it always places a space after the final letter typed.

IE: "SE ARCH" - I do not want this to occur.

3. I want to have a maxmium of 7 days results shown at once as the list will be very large.

Any assistance would be greatly appreciated.

Code:
<script type="text/javascript">
(
  function()
  {

      var lookFor = [
            "1",
            "11",
            "112",
            "22",
            "221"
      ];

      var form = document.getElementById("buyresults");
      var resultsDiv = document.getElementById("predict");
      var searchField = form.search;

      // first, position the results:
      var node = searchField;
      var x = 0;
      var y = 0;
      while ( node != null )
      {
          x += node.offsetLeft;
          y += node.offsetTop;
          node = node.offsetParent;
      }
      predictDiv.style.left = (x - 152) + "px";
      predictDiv.style.top  = (y - 203) + "px";
      
      // now, attach the keyup handler to the search field:
      searchField.onkeyup = function()
      {
          var txt = this.value.toLowerCase();
          if ( txt.length == 0 ) return;

          var txtRE = new RegExp( "(" + txt + ")", "ig" );
          // now...do we have any matches?
          var top = 0;
          for ( var s = 0; s < lookFor.length; ++s )
          {
              var srch = lookFor[s];
              if ( srch.toLowerCase().indexOf(txt) >= 0 )
              {
                  srch = srch.replace( txtRE, "<span>$1</span>" );
                  var div = document.createElement("div");
                  div.innerHTML = srch;
                  div.onclick = function() {
                      searchField.value = this.innerHTML.replace(/\<\/?span\>/ig,"");
                      predictDiv.style.display = "none";
                  };
                  div.style.top = top + "px";
                  top += 20;
                  predictDiv.appendChild(div);
                  predictDiv.style.display = "block";
              }
          }
      }
      // and the keydown handler:
      searchField.onkeydown = function() 
      {
          while ( resultsDiv.firstChild != null )
          {
              resultsDiv.removeChild( resultsDiv.firstChild );          
          }
          resultsDiv.style.display = "none";
      }
     
  }
)();
</script>
rexhvn is offline   Reply With Quote
Old 02-05-2013, 03:06 AM   PM User | #2
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Well, the "only starts with..." part is easy:
Code:
        var txtRE = new RegExp( "^(" + txt + ")", "ig" );
The ^ means "starts with..."

But I don't know why you get the space in there.

Hmmm...
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-05-2013, 08:05 AM   PM User | #3
rexhvn
New Coder

 
Join Date: Oct 2011
Posts: 49
Thanks: 0
Thanked 0 Times in 0 Posts
rexhvn is an unknown quantity at this point
Quote:
Originally Posted by Old Pedant View Post
Well, the "only starts with..." part is easy:
Code:
        var txtRE = new RegExp( "^(" + txt + ")", "ig" );
The ^ means "starts with..."

But I don't know why you get the space in there.

Hmmm...
I changed this in the code however it also shows a previous 'suggestion' along with the letter search.

IE:
Code:
var lookFor = [
            "1",
            "2",
            "3",
            "4",
            "5"
      ];
Search '5'
Result: '4'
'5'

But still getting a space!!!! Could this be CSS/HTML related?

Last edited by rexhvn; 02-05-2013 at 09:12 AM..
rexhvn is offline   Reply With Quote
Old 02-05-2013, 10:25 PM   PM User | #4
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Can you show the HTML you are using and the CSS? To go with the JavaScript?

Best: Show us a live URL.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-06-2013, 12:12 AM   PM User | #5
rexhvn
New Coder

 
Join Date: Oct 2011
Posts: 49
Thanks: 0
Thanked 0 Times in 0 Posts
rexhvn is an unknown quantity at this point
Quote:
Originally Posted by Old Pedant View Post
Can you show the HTML you are using and the CSS? To go with the JavaScript?

Best: Show us a live URL.
The website itself is not live etc... but I will get some code up soon.


Bascially to give an idea, i'm using a toggle that shows the search function then the javascript showing suggestions. So the <div> is revealed prior which may have an affect because when I used the this code on on it's own, it works fine.
rexhvn is offline   Reply With Quote
Old 02-06-2013, 12:17 AM   PM User | #6
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Never mind. I built a page of my own.

You had several small mistakes. And several pieces of unneeded code.

Try the below full page of code.

Try entering "n", then "no", then "not", then "noti". See the limit of 7 results, too?

Code:
<html>
<head>
<style type="text/css">
#predict {
    position: absolute;
    display: none;
    border: solid red 3px;
}
#predict div {
    cursor: pointer;
    border-bottom: solid black 1px;
}
</style>
<body>
<div id="predict"></div>
<form id="buyresults">
search: <input name="search"/>
</form>

<script type="text/javascript">
(
  function()
  {

      var lookFor = [
            "an", "and", "andiron", "andover", "andy",
            "no", "not", "note", "notable", "nothing", "notice", "noticable", "noticing", "notification", "notify", "notifying"
      ];

      var form = document.getElementById("buyresults");
      var predictDiv = document.getElementById("predict");
      var searchField = form.search;

      // first, position the results:
      var node = searchField;
      var x = 0;
      var y = 0;
      while ( node != null )
      {
          x += node.offsetLeft;
          y += node.offsetTop;
          node = node.offsetParent;
      }
      predictDiv.style.left = x + "px";
      predictDiv.style.top  = (y + 20) + "px";
      
      // now, attach the keyup handler to the search field:
      searchField.onkeyup = function()
      {
          var txt = this.value; 
          if ( txt.length == 0 ) return;

          var txtRE = new RegExp( "(^" + txt + ")", "i" );
          // now...do we have any matches?
          var cnt = 0;
          for ( var s = 0; s < lookFor.length; ++s )
          {
              var srch = lookFor[s];
              if ( txtRE.test(srch) ) 
              {
                  var div = document.createElement("div");
                  div.innerHTML = srch.replace( txtRE, "$1" );
                  div.onclick = choose;
                  predictDiv.appendChild(div);
                  predictDiv.style.display = "block";
                  if ( ++cnt >= 7 ) return; // max of 7 results displayed
              }
          }
      }
      function choose( )
      {
          searchField.value = this.innerHTML; 
          predictDiv.style.display = "none";
          searchField.focus();
      };

      // and the keydown handler:
      searchField.onkeydown = function() 
      {
          while ( predictDiv.firstChild != null )
          {
              predictDiv.removeChild( predictDiv.firstChild );          
          }
          predictDiv.style.display = "none";
      }
     
  }
)();
</script>
</body>
</html>
I have no idea why you had that <span> in there inside the inner <div>s. It was adding nothing useful that I could see. Nor could I see why you were using top and applying it to the inner <div>s. No need for that, either, it would seem. And no need to convert to lower case; that's what the "i" in the RegExp is for. Finally, it was a HUGE mistake to use "ig" instead of just "i". It meant that you would not pick up some "lookfor" values that you want to pick up.

(If you *want* to find those "lookfor" values any place in the typed-so-far text, then we have to make some MAJOR changes to the code.)
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-06-2013, 12:31 AM   PM User | #7
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
One flaw in all this: If the user types, say "NOT" and then clicks on "notable", he indeed *gets* "notable", instead of "NOTable". Clearly the code should at least preserve the case of the first character typed in, no? Or do you care?

It's not hard to fix.

In my "choose" function, replace the first line with this:
Code:
         searchField.value += this.innerHTML.substring(searchField.value.length);
But that pointed up another flaw to me!

If I hold down the SHIFT key, type in "NOT", and then release the SHIFT key to use the mouse to select (example) "notable", I get the list of 7 choices *REPEATED*.

That's because the onkeyup was triggered by the SHIFT key being release but there was no corresponding onkeydown.

The obvious answer is to remove the onkeydown event handler and move the clearing of predictdiv to the beginning of onkeyup. It makes no noticeable difference in how it all works except to clean up the SHIFT bug.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-06-2013, 12:33 AM   PM User | #8
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Here, both modifications (and a spelling error--mine--corrected):
Code:
<html>
<head>
<style type="text/css">
#predict {
    position: absolute;
    display: none;
    border: solid red 3px;
}
#predict div {
    cursor: pointer;
    border-bottom: solid black 1px;
}
</style>
<body>
<div id="predict"></div>
<form id="buyresults">
search: <input name="search"/>
</form>

<script type="text/javascript">
(
  function()
  {

      var lookFor = [
            "an", "and", "andiron", "andover", "andy",
            "no", "not", "notable", "note", "nothing", "notice", "noticeable", "noticing", "notification", "notify", "notifying"
      ];

      var form = document.getElementById("buyresults");
      var predictDiv = document.getElementById("predict");
      var searchField = form.search;

      // first, position the results:
      var node = searchField;
      var x = 0;
      var y = 0;
      while ( node != null )
      {
          x += node.offsetLeft;
          y += node.offsetTop;
          node = node.offsetParent;
      }
      predictDiv.style.left = x + "px";
      predictDiv.style.top  = (y + 20) + "px";
      
      // now, attach the keyup handler to the search field:
      searchField.onkeyup = function()
      {
          while ( predictDiv.firstChild != null )
          {
              predictDiv.removeChild( predictDiv.firstChild );          
          }
          predictDiv.style.display = "none";

          var txt = this.value; 
          if ( txt.length == 0 ) return;

          var txtRE = new RegExp( "(^" + txt + ")", "i" );
          // now...do we have any matches?
          var cnt = 0;
          for ( var s = 0; s < lookFor.length; ++s )
          {
              var srch = lookFor[s];
              if ( txtRE.test(srch) ) 
              {
                  var div = document.createElement("div");
                  div.innerHTML = srch.replace( txtRE, "$1" );
                  div.onclick = choose;
                  predictDiv.appendChild(div);
                  predictDiv.style.display = "block";
                  if ( ++cnt >= 7 ) return; // max of 7 results displayed
              }
          }
      }
      function choose( )
      {
          searchField.value += this.innerHTML.substring(searchField.value.length); 
          predictDiv.style.display = "none";
          searchField.focus();
      };

  }
)();
</script>
</body>
</html>
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-07-2013, 11:30 AM   PM User | #9
rexhvn
New Coder

 
Join Date: Oct 2011
Posts: 49
Thanks: 0
Thanked 0 Times in 0 Posts
rexhvn is an unknown quantity at this point
Much better thank you! You really know your stuff!!!

Is there anyway I can select a 'suggestion' (predictDiv) by using the down Arrow on the keyboard instead of always using the mouse?
rexhvn is offline   Reply With Quote
Old 02-07-2013, 09:07 PM   PM User | #10
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Quote:
Originally Posted by rexhvn View Post
Is there anyway I can select a 'suggestion' (predictDiv) by using the down Arrow on the keyboard instead of always using the mouse?
Yes, but it's a bit more coding. You have to be sure there really is some available predictive text, for example.

Is it important? (I guess the answer is "probably.")
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-07-2013, 09:53 PM   PM User | #11
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Try this out. Works in CHROME. Untested in other browsers. The big problem is that <form> field autocomplete must be disabled or you can not use the down and up arrows. You can see i have done so for <form> and the <input> field. I *THINK* that is enough for all browsers, but you need to verify.
Code:
<html>
<head>
<style type="text/css">
#predict {
    position: absolute;
    display: none;
    border: solid red 3px;
}
#predict div {
    cursor: pointer;
    border-bottom: solid black 1px;
}
</style>
<body>
<div id="predict"></div>
<form id="buyresults" autocomplete="off">
search: <input name="search" autocomplete="off" />
</form>

<script type="text/javascript">
(
  function()
  {

      var lookFor = [
            "an", "and", "andiron", "andover", "andy",
            "no", "not", "notable", "note", "nothing", "notice", "noticeable", "noticing", "notification", "notify", "notifying"
      ];

      var form = document.getElementById("buyresults");
      var predictDiv = document.getElementById("predict");
      var searchField = form.search;
      var curLine = -1;
      var curText = searchField.value;

      // first, position the results:
      var node = searchField;
      var x = 0;
      var y = 0;
      while ( node != null )
      {
          x += node.offsetLeft;
          y += node.offsetTop;
          node = node.offsetParent;
      }
      predictDiv.style.left = x + "px";
      predictDiv.style.top  = (y + 20) + "px";
      
      // now, attach the keyup handler to the search field:
      searchField.onkeyup = function(evt)
      {
          if ( evt == null ) evt = window.event;
          if ( evt.keyCode == 40 || evt.keyCode == 38 ) { return false; }

          while ( predictDiv.firstChild != null )
          {
              predictDiv.removeChild( predictDiv.firstChild );          
          }
          predictDiv.style.display = "none";
          curLine = -1;

          curText = this.value; 
          if ( curText.length == 0 ) return;

          var txtRE = new RegExp( "(^" + curText + ")", "i" );
          // now...do we have any matches?
          var cnt = 0;
          for ( var s = 0; s < lookFor.length; ++s )
          {
              var srch = lookFor[s];
              if ( txtRE.test(srch) ) 
              {
                  var div = document.createElement("div");
                  div.innerHTML = srch.replace( txtRE, "$1" );
                  div.onclick = choose;
                  predictDiv.appendChild(div);
                  predictDiv.style.display = "block";
                  if ( ++cnt >= 7 ) return; // max of 7 results displayed
              }
          }
      }
      searchField.onkeydown = function(evt)
      {
          if ( evt == null ) evt = window.event;
          if ( evt.keyCode == 40 || evt.keyCode == 38 )
          {
               var divs = predictDiv.getElementsByTagName("div");
               for ( var d = 0; divs !=null && d < divs.length; ++d )
               {
                   divs[d].style.backgroundColor = "transparent";
               }
               curLine += ( evt.keyCode - 39 );
               if ( curLine < 0 || divs == null || divs.length == 0 ) 
               { 
                   this.value = curText;
                   curLine = -1; 
                   return false; 
               }
               if ( curLine >= divs.length ) { curLine = divs.length - 1; }
               var div = divs[curLine];
               div.style.backgroundColor = "#dddddd";
               this.value = div.innerHTML;               
               return false;
          }
      }
      function choose( )
      {
          searchField.value += this.innerHTML.substring(searchField.value.length); 
          predictDiv.style.display = "none";
          searchField.focus();
      };

  }
)();
</script>
</body>
</html>
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.

Last edited by Old Pedant; 02-07-2013 at 10:06 PM..
Old Pedant is offline   Reply With Quote
Old 02-07-2013, 10:11 PM   PM User | #12
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Here's a cute trick, kind of an accidental happy effect:

Type in "n".
Then use the down arrow to select "not".
Then click on the RIGHT ARROW.

Isn't that great! And then type the letter "i".

If your "prediction" words are alphabetical (as I made mine) you could go through quite long lists of words with few keystrokes, even with the limit of 7 showing as it is now.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-08-2013, 03:58 AM   PM User | #13
rexhvn
New Coder

 
Join Date: Oct 2011
Posts: 49
Thanks: 0
Thanked 0 Times in 0 Posts
rexhvn is an unknown quantity at this point
I already have 'autocomplete="off"' - is there a reason why the results when selected by the mouse (onclick) the result will then appear in the searchField, however when selected by the arrow (using return on keyboard) it doesn't?

Thank you for all your assistance!!! It is much appreciated.

Last edited by rexhvn; 02-08-2013 at 04:01 AM..
rexhvn is offline   Reply With Quote
Old 02-08-2013, 06:26 AM   PM User | #14
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
??? I only tested this in Chrome. It worked as I described there.

Let me try it in MSIE 9 and FF.

Works correctly in FF.
Works correctly in MSIE 9.

What browser are you using that it doesn't work in?

OH! Wait! You said "using return on keyboard"!!! You can *NOT* do that!

The ENTER key is treated as a <form> submit!

The focus in this thing NEVER leaves the <input> field when you use the up and down arrow keys! It may *look* like it does, but it doesn't. So with the focus still on the <input> field, hitting ENTER acts as a submit of the <form>.

To accept the choice made by the arrow keys, you can do any of the following:
-- type another regular key.
(Example: Type "n". Use the up and down arrow keys to select "nothing". Type SPACE, I, S, SPACE, S, I, M, P, L, E)
-- type the right arrow key. That accepts the choice and, if the choice starts other choices, shows those other choices..
(Example: Type "n". Use the up and down arrow keys to select "not". Type the right arrow key. Look at the new selections.)
-- type the TAB key.
(Need to add another field to the <form> I show to see this. Type "n", use up and down arrow keys to choose any word, hit the TAB key. The cursor moves to the next <form> field.)

If you WANT to SUPPRESS the ENTER key, then we have to write code to do so.

But that would be true in any case, if you did not want the ENTER key to force a submit of the <form>.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 02-08-2013, 06:29 AM   PM User | #15
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,187
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Hmmm...just played with the TAB key. Okay, need to add to the onkeydown handler to have it accept the word and clear the list on TAB.

And could easily do the same with ENTER and then in onkeyup just ignore it.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 03:24 PM.


Advertisement
Log in to turn off these ads.