1

I have this code snippet.

        <div class="content__img-txt">
          <a class="input-group">
          <input class="input-group-field" type="text">
          <div class="input-group-button">
            <input type="submit" class="button" value="&raquo;">
          </div>
        </div>

function showLetter (field, text, delay) {
        $(field).val(text.substring(0,1));
        for(var i = 2; i <= text.length; i++)
        {
            setTimeout(function(){
                $(field).val(text.substring(0,i));
            }, delay);
        }
    }
 showLetter (".input-group-field", "Show letter for letter with a delay of 1 second", 1000);

The console says : Uncaught TypeError: Cannot read property 'length' of undefined.

How can I display text in the input field but letter for letter and not the whole text at once, after the document has fully loaded?

151RUM
  • 75
  • 1
  • 1
  • 8
  • You mind showing us some of your html markup? – Aer0 Mar 08 '16 at 13:27
  • It goes well on my Chrome . But the text showed together. – yaochiqkl Mar 08 '16 at 13:29
  • Are you sure that console message points to that code? Your primary problem seems to be that your text is going to show together because by the time your timeouts execute `i` is going to be the length of the string see [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Patrick Evans Mar 08 '16 at 13:36

5 Answers5

2

Guess you need a closure to ensure setTimeout have their own loop, and you need to increase delay like following :

function showLetter(field, text, delay) {
  $(field).val(text.substring(0, 1));
  for (var i = 2; i <= text.length; i++) {
    (function(i) {
       setTimeout(function() {
          $(field).val(text.substring(0, i));
       }, (delay=delay+100));
    })(i)

  }
}
showLetter(".input-group-field", "Show letter for letter with a delay of 1 second", 1000);

DEMO

Norlihazmey Ghazali
  • 9,000
  • 1
  • 23
  • 40
  • Thank you so much !!! Even the other suggestions!!! Just add a little piece of code and noobs like me are happy ;) – 151RUM Mar 08 '16 at 13:54
  • @ Norlihazmey Ghazali. Just to add one more question because this is way to hard for me to achieve. Is it now possible to replace the first text, lets say 4 seconds after it has fully show up with a new string. Sorry my english is bad ^^ – 151RUM Mar 08 '16 at 14:01
  • Do you mean like this : https://jsfiddle.net/norlihazmeyGhazali/pdntzpyp/ --> First text of value will change to other string – Norlihazmey Ghazali Mar 08 '16 at 14:22
  • I mean to change the whole sentence, not only the first word. Lets say i prepare 5 setences and after the first is loaded like we did before, we fire the second one after 3 second, and so on... :) – 151RUM Mar 08 '16 at 14:30
  • You are the man !!!!!!!!!!! Thanks so much :) I hope someday i can code like this and understand it :P – 151RUM Mar 08 '16 at 14:52
  • No worries mate.. someday you could, and you're welcome. – Norlihazmey Ghazali Mar 08 '16 at 14:53
  • Norlihazmey, sorry for the late reply but i wanted to try it on my own...(unfortunately failed)...i just want the incoming text sentences to infinite loop. so after the last one it should start again with the first, so the field is always in action :) after this, i have one more issue but i will try this by my own first ;) regards! – 151RUM Mar 08 '16 at 15:32
  • Answer Update. Just clicked on DEMO link – Norlihazmey Ghazali Mar 08 '16 at 23:21
  • Hey Norlihazmey, i couldnt figure it out on my own...maybe you can help me again. When the user clicks in the input field the current running text should stop an be deleted so the user can type his own search words in the input field. When the user clicks anywhere outside the input field, the text should start running again from index [0] or better, the last displayed index. You get me mate? ^^ – 151RUM Mar 10 '16 at 08:42
  • Answer Updated. Just clicked on DEMO link – Norlihazmey Ghazali Mar 10 '16 at 09:35
  • 400 thumps up bro *** (Y) -- now i just have to finish this project today with a last challlenge!!! every suggestion which is displayed in the input field should also be clickable (on the text itself or a button) and link to another site... this will be so hard but lets see if its possible ^^ – 151RUM Mar 10 '16 at 10:35
0

You should use setInterval instead.

function showLetter(field, text, delay) {
  $(field).val(text.substring(0, 1));
  var interval = setInterval(function() {
    var len = ($(field).val().length || 0) +1;
    $(field).val(text.substring(0, len));
    
    if(len === text.length)
      window.clearInterval(interval);
  }, delay);
}
showLetter(".input-group-field", "Show letter for letter with a delay of 1 second", 100);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="content__img-txt" style="float:left;margin-top:20px;">
  <a class="input-group">
    <input class="input-group-field" type="text">
    <div class="input-group-button">
      <input type="submit" class="button" value="&raquo;">
    </div>
</div>
Rajesh
  • 24,354
  • 5
  • 48
  • 79
0

Recursive function!

function showLetter (field, text, position, delay) {
  if (position >= text.length) {
      return false;
  }
  var current = text.substring(0,position);
  setTimeout(function(){
    $(field).val(current+text[position]);
  }, delay);
  return showLetter(field,text,position+1,delay+1000)
}
showLetter (".input-group-field", "Show letter for letter with a delay of 1 second", 0, 1000);

Such fun!

In case you're wondering why your code doesn't work, it's because the for loop keeps running and increasing i, so by the time setTimeout hits, i == text.length and it gives you the whole string.

DEMO

vcanales
  • 1,818
  • 16
  • 20
0

I've made some example, I hope it helps you.

$(document).ready(function() {
  
  var TIME_OUT = 1000;
  
  var showTextWithDelay = function(element, text) {
    
    var lengthOfSubtext = 0;
    var printer = setInterval(function() {
      
      if (lengthOfSubtext >= text.length) {
        clearInterval(printer);  
      }
      
      var subtext = text.substring (0, lengthOfSubtext);
      element.val(subtext);
      lengthOfSubtext++;
      
     }, TIME_OUT);
     
  };
                   
  
  var inputElement = $('#field');
  var text = "This is an example!";


  showTextWithDelay(inputElement, text);
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>


<input type="text" id="field">
rjsandim
  • 39
  • 5
0

To add one more to the mix ;) recursion with a local function:

function showLetter(field, text, delay) {
  var ind = 1;
  var shownext = () => { 
    $(field).val(text.substring(0,ind));     
    if(ind++ < text.length) setTimeout(shownext,delay);
  };
  shownext();
}

Fiddle

Me.Name
  • 12,259
  • 3
  • 31
  • 48