Note that there are some explanatory texts on larger screens.

plurals
  1. POJavascript closure function not called on form submit
    text
    copied!<p>This has me perplexed. I have a textbox. You type something in, and press enter. Javascript creates a read-only input element in separate form. Along side the text input boxes are buttons to remove them. There is also a submit button at the bottom of that form to submit all of the read-only text inputs. </p> <p>Since clicking a button inside of a form would submit the form (and I just want to remove the parent div that contains both the button and its corresponding text input), a function is called when the form submits. This function determines which type of button (remove or submit) was pressed and acts accordingly.</p> <p>Here comes the problem. When a remove button is pressed, the function <code>destinations.enter</code> is never called. What I did to solve this was to create a global function called <code>submitDestinations</code> that replicates the functionality of <code>destinations.enter</code>. If this function is called instead, everything goes off without a hitch.</p> <p>Does anyone have an idea as to why <code>destinations.enter</code> will not run on submit, but <code>submitDestinations</code> will? I want to believe that it has something to do with closures, because the function scope appears to be the only difference between the two functions. However, this is my first time using closures, and I have only a limited understanding of them.</p> <p>Javascript:</p> <pre><code>var destinations = (function(){ var max_destinations = 7; var counter = 0; function increment(){ counter += 1; if(counter &gt; max_destinations){ throw 'Too many destinations. (Max 7)' } } function decrement(){ counter += 0; if(counter &lt; 0){ alert('Cannot have less than 0 destinations..') throw 'Too few destinations. Get out of the console!' } } return { add : function(form){ try{ var formInput = form.elements[0]; var destination = formInput.value; // Dont do anything if the input is empty if(destination == ""){ return false; }else{ // increment the destinations counter increment(); } }catch(err){ alert(err); return false; } // add the text value to a visual element var elem = document.createElement('div'); elem.setAttribute('class','destination'); // create the input var input = document.createElement('input'); input.setAttribute('id','dest'+String(counter)); input.setAttribute('class','destinationText'); input.setAttribute('style','border: none'); input.setAttribute('name','destinations'); input.setAttribute('readonly','readonly'); input.setAttribute('value',destination); // create the remove button var button = document.createElement('button'); button.setAttribute('onclick','this.form.submitted=this;');//'return destinations.remove(this);'); button.setAttribute('class','removeButton') button.setAttribute('id','but'+String(counter)) var buttonText = document.createTextNode('Remove'); button.appendChild(buttonText); // add the elements to the div elem.appendChild(input); elem.appendChild(button); var parent = document.getElementById('destinationsDiv'); parent.appendChild(elem); // clear the input box formInput.value = ''; return false; }, enter : function(form){ alert('hi') var button = form.submitted; if(button.id != 'submitBtn'){ return remove(button); }else{ return true; } return false; }, remove : function(button){ try{ decrement(); }catch(err){ // do not allow less than 0 counter alert(err); return false; } // remove the button's parent div altogether var toDelete = button.parentNode; toDelete.parentNode.removeChild(toDelete); return false; } } })(); </code></pre> <p>And the html:</p> <pre><code> &lt;div&gt; &lt;form id='hi' onsubmit="return destinations.add(this);"&gt; &lt;input type="text" value="" /&gt; &lt;/form&gt; &lt;!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);"--&gt; &lt;form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);"&gt; &lt;div id='destinationsDiv'&gt; &lt;div&gt; &lt;input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \&gt; &lt;button onclick="this.form.submitted=this;" class="removeButton" id="but1" \&gt;&lt;/button&gt; &lt;/div&gt; &lt;div&gt; &lt;input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \&gt; &lt;button onclick="this.form.submitted=this;" class="removeButton" id="but2" \&gt;&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/&gt; &lt;/form&gt; &lt;/div&gt; </code></pre> <p>Everything works fine if I add the following javascript function to the global scope and call it instead. This does the exact same thing as <code>destinations.enter</code></p> <pre><code>function submitDestinations(form){ var button = form.submitted; if(button.id != 'submitBtn'){ return destinations.remove(button); }else{ return true; } } </code></pre> <p>All I change in the html is the method that is called on submit:</p> <pre><code> &lt;div&gt; &lt;form id='hi' onsubmit="return destinations.add(this);"&gt; &lt;input type="text" value="" /&gt; &lt;/form&gt; &lt;form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);"&gt; &lt;!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);"--&gt; &lt;div id='destinationsDiv'&gt; &lt;div&gt; &lt;input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \&gt; &lt;button onclick="this.form.submitted=this;" class="removeButton" id="but1" \&gt;&lt;/button&gt; &lt;/div&gt; &lt;div&gt; &lt;input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \&gt; &lt;button onclick="this.form.submitted=this;" class="removeButton" id="but2" \&gt;&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/&gt; &lt;/form&gt; &lt;/div&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload