skip to Main Content

Aspiring developer and first time posting a question to StackOverflow.
Researched the topic but couldn’t find an exact answer to my question.

  1. Background:

    • Modifying this static shopping cart, to accept dynamically created list item.
      https://tutorialzine.com/2014/04/responsive-shopping-cart-layout-twitter-bootstrap-3

    • Trying to insert a new item to the shopping cart via span tag, span tag information will be dynamically provided by another function.

    • For testing purpose I’m using a button to insert the new item to the shopping list.

    • The shopping cart has popover event to “Modify / Delete” individual items lists

  2. Question: I can’t figure out the exact JavaScript / jQuery command to attach the popover event. All static items in the list have the popover event automatically attached but the dynamically created items do not.

    • I tried using the addEventListener(); but the jQuery doesn’t get attached properly.

    • My initial assumption was if the dynamically created list items had the same “class” as the static items that the popoever event would be automatically applied to them as well.

    • Tried these solutions but didn’t work out for me, the popover event doesn’t get attached properly.

    a. Event binding on dynamically created elements?
    Event binding on dynamically created elements?

    b. Attach event to dynamically created chosen select using jQuery
    Attach event to dynamically created chosen select using jQuery

    c. Attaching events after DOM manipulation using JQuery ajax
    Attaching events after DOM manipulation using JQuery ajax

  3. Here’s the HTML and JavaScript:

var qrcodelist = document.getElementById('qrdemo_list');

function myFunction() {
// HTML for testing when device is not connected: comment out when device is connected
var x = document.getElementsByClassName("decode-value-offline")[0].innerHTML;

// Qty and Price text values
var qty_text = 1;
var price_text = '$150';

// Create li 
var entry_li = document.createElement('li');
entry_li.setAttribute("class", "row");

// Create quantity span					
var qty_span = document.createElement('span');
qty_span.setAttribute("class", "quantity");
qty_span.appendChild(document.createTextNode(qty_text));

// Create price span					
var price_span = document.createElement('span');
price_span.setAttribute("class", "price");
price_span.appendChild(document.createTextNode(price_text));

// Create pop btn span
var popbtn_span = document.createElement('span');
popbtn_span.setAttribute("class", "popbtn");
popbtn_span.setAttribute("data-original-title", "");
popbtn_span.setAttribute("title", "");
//popbtn_span.addEventListener( );

// Create a tag inside pop btn
var popbtn_a_span = document.createElement('a');
popbtn_a_span.setAttribute("class", "arrow");
popbtn_span.appendChild(popbtn_a_span);

// Create item span and text node					
var item_span = document.createElement('span');
item_span.setAttribute("class", "itemName");

// Append span to li
entry_li.appendChild(qty_span);
entry_li.appendChild(item_span);
entry_li.appendChild(popbtn_span);
entry_li.appendChild(price_span);

// Create text node and insert qr-code result to li span
item_span.appendChild(document.createTextNode(x));

// Get list node and insert 
var list_node = document.getElementById("qrdemo_list").lastChild;
// alert(list_node);
qrdemo_list.insertBefore(entry_li, qrdemo_list.childNodes[3]);

// Write x to console log
console.log(x);
}

// Popover JavaScript 
$(function() {
  var pop = $('.popbtn');
  var row = $('.row:not(:first):not(:last)');


  pop.popover({
    trigger: 'manual',
    html: true,
    container: 'body',
    placement: 'bottom',
    animation: false,
    content: function() {
      return $('#popover').html();
    }
  });


  pop.on('click', function(e) {
    pop.popover('toggle');
    pop.not(this).popover('hide');
  });

  $(window).on('resize', function() {
    pop.popover('hide');
  });

  row.on('touchend', function(e) {
    $(this).find('.popbtn').popover('toggle');
    row.not(this).find('.popbtn').popover('hide');
    return false;
  });

});
<!-- Shopping Cart List HTML -->

<div class="col-md-7 col-sm-12 text-left">
  <ul id="qrdemo_list">
    <li class="row list-inline columnCaptions">
      <span>QTY</span>
      <span>ITEM</span>
      <span>Price</span>
    </li>
    <li class="row">
      <span class="quantity">1</span>
      <span class="itemName">Birthday Cake</span>
      <span class="popbtn"><a class="arrow"></a></span>
      <span class="price">$49.95</span>
    </li>
    <li class="row">
      <span class="quantity">50</span>
      <span class="itemName">Party Cups</span>
      <span class="popbtn"><a class="arrow"></a></span>
      <span class="price">$5.00</span>
    </li>
    <li class="row">
      <span class="quantity">20</span>
      <span class="itemName">Beer kegs</span>
      <span class="popbtn"><a class="arrow"></a></span>
      <span class="price">$919.99</span>
    </li>
    <li class="row">
      <span class="quantity">18</span>
      <span class="itemName">Pound of beef</span>
      <span class="popbtn"><a class="arrow"></a></span>
      <span class="price">$269.45</span>
    </li>
    <li class="row">
      <span class="quantity">1</span>
      <span class="itemName">Bullet-proof vest</span>
      <span class="popbtn" data-parent="#asd" data-toggle="collapse" data-target="#demo"><a class="arrow"></a></span>
      <span class="price">$450.00</span>
    </li>
    <li class="row totals">
      <span class="itemName">Total:</span>
      <span class="price">$1694.43</span>
      <span class="order"> <a class="text-center">ORDER</a></span>
    </li>
    <li class="row">
      <!-- QR Code Images -->
      <span class="itemName"><img src="img/AppleQRCode.png" width="100" height="100"></span>
      <span class="price"><img src="img/OrangeQRCode.png" width="100" height="100"></span>
    </li>
    <li class="row">
      <!-- device offline testing span -->
      <span class="decode-value-offline">Unknown</span>
    </li>
    <li class="row totals">
      <!-- Button to insert qr-code result to list -->
      <span class="order"><a class="text-center" onclick="myFunction()">Insert</a></span>
      <span class="itemName">Insert QR Code Result</span>
    </li>
  </ul>
</div>

<!-- Popover HTML -->

<!-- The popover content -->

<div id="popover" style="display: none">
  <a href="#"><span class="glyphicon glyphicon-pencil"></span></a>
  <a href="#"><span class="glyphicon glyphicon-remove"></span></a>
</div>

<!-- JavaScript includes -->

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/customjs.js"></script>

Appreciate the great support in advance and please contact me if additional information is needed for clarification.

2

Answers


  1. You need to delegate jquery function to the HTML elements created dynamically like this:

    Change your following line

    var pop = $('.popbtn');
    var row = $('.row:not(:first):not(:last)');
    

    like given here:

    var pop = $(document).find('.popbtn');
    var row = $(document).find('.row:not(:first):not(:last)');
    
    Login or Signup to reply.
  2. JSFiddle of Fix: https://jsfiddle.net/0phz61w7/

    The issue is that you need to delegate the event. Please do the following:

    Change:

    pop.on('click', function(e) {
        pop.popover('toggle');
        pop.not(this).popover('hide');
    });
    

    To:

    $(document).on('click', '.popbtn', function(e) {
        pop.popover('toggle');
        pop.not(this).popover('hide');
    });
    

    Also, you need to remove the } from line 54, just after console.log(x);. That is throwing an error.

    The above modification works, but in the code provided, .popbtn is not visible because the node is empty. So in the jsfiddle provided, I added a CSS rule to include the text POPBTN. Click that and an alert I added to the click event fires.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search