0

I am trying to update and display a list of names each time the user submits a new name. For example, (first time: "Jim” is displayed, second time: “Jim Bob” is displayed, third time: “Jim Bob Joe” is displayed, etc.) It is required to use closure. I can get the pre-loaded input value, but I guess there is something wrong with my loop and I don't get any further input. Any ideas?

Enter a name and I will add it to the list:

        <input type="text" id="newName" value="Doug"/> 
        <button onclick="closureExample()">closureExample()</button>    
        <p id="nameList">Abe,Bill,Charlie</p>
        <script>
            var addName = (function () {
                var names = ['Abe', 'Bill', 'Charlie'];
                var name = document.getElementById("newName").value;
                var text;
                for (var i = 0; i < names.length; i++) {
                    text += names[i];
                }
                return function () {return text;}
            })();

            function closureExample(){                  
                document.getElementById("nameList").innerHTML = addName();                  
            }   
        </script>   

4 Answers4

1

You can have the names array inside the closure so its not global and add your click listener inside it which can add names to the array and print them.

    <input type="text" id="newName" value="Doug"/> 
    <button id="add_name_btn">closureExample()</button>    
    <p id="nameList"></p>
    <script>
        (function(){
            var names = [];
            document.getElementById("add_name_btn").addEventListener('click', function() {
                names.push(document.getElementById("newName").value);
                document.getElementById('nameList').innerHTML = names.join(' ');
            });
        })();
    </script> 
  • YES, this works! And I was even trying to use push and join in an earlier version, just way wrong. Thanks for your help! –  Sep 28 '15 at 02:56
0
    <input type="text" id="newName" value="Doug"/> 
<button onclick="closureExample()">closureExample()</button>    
<p id="nameList">Abe,Bill,Charlie</p>
<script>
    var addName = (function () {
        var names = ['Abe', 'Bill', 'Charlie'];
        var name = document.getElementById("newName").value;
        var text;
        for (var i = 0; i < names.length; i++) {
            text += names[i];
        }
        return  text;
    })();

    function closureExample(){                  
        document.getElementById("nameList").innerHTML = addName();                  
    }   
</script>   

I changed Code return text. please , check this working.

uma
  • 1,477
  • 3
  • 32
  • 63
  • That isn't using a closure. The IIFE runs once and returns a string. *closureExample* then calls *addName*, which is a string and can't be called. – RobG Sep 28 '15 at 02:50
0
<input type="text" id="newName" value="Doug"/> 
<button onclick="closureExample()">closureExample()</button>    
<p id="nameList">Abe,Bill,Charlie</p>
<script>
function closureExample(){
    var names = document.getElementById("nameList").innerHTML.split(','),
        name = document.getElementById("newName").value;
    names.push(name);
    document.getElementById("nameList").innerHTML = names.toString();                 
}
</script>

Here is a JS fiddle for you: http://jsfiddle.net/passtet/kche2sx9/

PassTeT
  • 517
  • 5
  • 8
0

You're close.

var addName = (function () {
  var names = ['Abe', 'Bill', 'Charlie'];
  var name = document.getElementById("newName").value;
  var text;
  for (var i = 0; i < names.length; i++) {
    text += names[i];
  }
  return function () {return text;}
})();

In the above, the returned function has a closure to the variables in the outer execution context, including text, however the value of text is not modified so returns the same value every time (which is the value assigned the first time the function runs).

What you want to do is update the value of text, then return it (note that text isn't necessary, you can update names instead and use join to return a string):

  return function(newName) {

    // Add the new name to text
    text += newName;

    // return a string of the concatenated names
    return text;

    /* 
    ** this could be done instead
    // Update the names array
    names.push(newName);

    // Return the concatenated values in the names array
    return names.join(', ')
    */
  }

When the button is clicked, pass the new name to the function:

function closureExample() {
  document.getElementById("nameList").innerHTML = addName(document.getElementById('newName').value);
}
RobG
  • 142,382
  • 31
  • 172
  • 209