1

I cannot get a nested variable value to populate outside a nested function within a button's click event function even though I believe I am using a global variable.

What am I doing wrong to pull value into a console log outside the nested function?

I am creating a shopping cart utilizing jquery pop-up with ajax and php. I am able to add items to the cart as well as add a name & email input field.

When I go to console log in Chrome for the focusout event for the fields they show the values but when trying to use a Checkout button, I am not able to pass the data within the Checkout click outside of a nested function even with a global variable.

--JS--

   var formname;
$(document).ready(function() {
...
    $(document).on('click', '#check_out_cart', function(){            

          $('#cart-popover').popover({
                html : true,
                container: 'body',
                content:function(){
                  return $('#popover_content_wrapper').html();
                }
          });      

           $(document).on('click', '#cart-popover', function(){    
                  $('input#namef').focus();                   
          });

            $('input#namef').on('focusout', function(){                  
                    formname= $('input#namef').val();                         
                    console.log(formname);
            });

            var scart_add = $("input[name='scart_add']").val();
            console.log("Scart value is "+scart_add);
            console.log("Name is "+formname);
            ...

    });
});

--HTML--

 <div class="container">
              <nav class="navbar navbar-default" role="navigation">
                <div class="container-fluid">
                  <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Menu</span>
                    <span class="glyphicon glyphicon-menu-hamburger"></span>
                    </button>                    
                  </div>

                  <div id="navbar-cart" class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                      <li>
                        <a id="cart-popover" class="btn" data-placement="bottom" title="Shopping Cart">
                          <span class="glyphicon glyphicon-shopping-cart-2x"></span>
                          <span class="badge"></span>
                          <span class="total_price">$ 0.00</span>
                        </a>
                      </li>
                    </ul>
                  </div>                  
                </div>
              </nav>    
<div id="popover_content_wrapper" style="display: none">
              <span id="cart_details"></span>
              <div>
                <form method="POST">
                  Name:&nbsp;<input type="text" id="namef" >&nbsp;&nbsp;
                  Email:&nbsp;<input type="text" id="emailf" >&nbsp;&nbsp;
                  <input type="hidden" name="scart_add" value="1" /><br><br>
</div>
<div align="right">                  
               <button type="button" class="btn btn-primary" id="check_out_cart">
                  <span class="glyphicon glyphicon-shopping-cart"></span> Check out
                  </button>
                  <button type="button" class="btn btn-default" id="clear_cart">
                  <span class="glyphicon glyphicon-trash"></span> Clear
                  </button>                
</div>
</form>            
</div>
</div>
<div id="display_item">
</div>
...
</div>

I am expecting the value from the input#namef text to appear in the console.log ...formname variable but it just shows as "".

2
  • Can you provide any snippets ?, Its really very weird you are calling focusout in click Commented Sep 6, 2019 at 13:16
  • As a general rule you should not be nesting event handlers. What exactly are you trying to achieve? Commented Sep 6, 2019 at 13:16

3 Answers 3

1

The event for focusout isn't added to the input until you click the button: Also, I don't know if it is how you copied and pasted your HTML and Javascript, but it was throwing errors when I put it into a fiddle.

Move this outside of the button click handler as Rory pointed out:

var formname;
$(document).ready(function() {
        //Now focusout handler is added on DOM Ready instead of when you click the button
        $('input#namef').on('focusout', function(){                  
               formname= $('input#namef').val();                         
               console.log(formname);
         });

         $(document).on('click', '#check_out_cart', function(){            

            var scart_add = $("input[name='scart_add']").val();
            console.log("Scart value is "+scart_add);
            console.log("Name is "+formname);

         });
});

Here is a working fiddle: https://jsfiddle.net/hqgv7zsa/

Sign up to request clarification or add additional context in comments.

1 Comment

This works if I remove the style="display: none" from the div but the shopping cart is initially not visible until the #cart-popover button is click to put it into a modal/pop-up. (See above for more context after edit)... The popover function is part of a bootstrap JS
0

This is a race condition, of sorts.

  • On document.ready event, you are setting a click event handler
  • Inside the click handler, you are setting the focusout event handler
  • Since the click handler is still executing, immediately, the code runs to show value of scart and formname.

At that time, formname is still empty because the current function (click event handler) is still executing, and the focusout event, even if it fires, will fire after that code is executed.


You should move the focusout handler declaration code outside of the click handler code, which will then set both handlers on document.ready() event.

Here's a breakdown of what's happening and when:

var formname; 
$(document).ready(function() {

This fires when DOM is loaded (document.ready event)

    $(document).on('click', '#check_out_cart', function(){            

This fires when user clicks on some element with ID check_out_cart

        $('input#namef').on('focusout', function(){ 

This event handler is only being set once user clicks on cart, but it is not yet executed!

                formname= $('input#namef').val();                         
                console.log(formname);
        });

This code fires once the event handler has been set for focusout, but still has not executed. Even if a focusout event is fired, it will only execute when the current function exits.

        var scart_add = $("input[name='scart_add']").val();
        console.log("Scart value is "+scart_add);

Correctly, you will see that formname is empty at this point.

        console.log("Name is "+formname);
        ...
    });
});

Hope this explains the flow you're seeing;

Quick fix as in Ryan Wilson's answer, move the focusout handler declaration to the scope of the document.ready handler, outside the click handler.

Comments

0

Using the solution from Unable to fetch values from an input element in Bootstrap's popover, I was able to adjust my JS code to fetch the values with a .find within the .popover-content class that was added by the popover JS.

    var formname; 
    var formemail;       
$(document).ready(function() {
          //shopping cart

          /*load functions*/
          load_product();
          load_cart_data();

          $('#cart-popover').popover({
                html : true,
                container: 'body',
                content:function(){                  
                  return $('#popover_content_wrapper').html();
                }
          });

          $(document).on('click', '#cart-popover', function(){    
                  $('input#namef').focus();                   
          });

          $(document).on('focusout', '#namef', function(){
                formname = $('.popover-content').find('#namef').val();                
          });

          $(document).on('focusout', '#emailf', function(){                
                formemail = $('.popover-content').find('#emailf').val();
          });

           $(document).on('click', '#check_out_cart', function(){
                  var scart_add = $("input[name='scart_add']").val();
                  var nameval = $("input#namef").val();
                  alert("Scart value is "+scart_add);
                  alert("Name is "+formname);            
                  alert("Email is "+formemail); 

          });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.