Search code examples
jqueryeventsonclicklistenerjsrender

JQuery on click listener not firing after rendering html with JsRender


I'm trying to attach an on click listener to a DOM element that is on the page after being rendered via JsRender, however seem to be experiencing some difficulty..

The markup:

    <button id="placeBid" data-attr-saleId="{{:id}}" class="btn btn-lg btn-add-to-cart"><span class="glyphicon glyphicon-shopping-cart"></span>Bid on this item</button>

The Jquery on click listener code:

  $(document).ready(function(){

  $('#placeBid').on('click','#templateContainer', function () {

          console.log('Clicked place bid')

          const saleId = $(this).attr('data-attr-saleId')
          if (!saleId) return

          $.ajax({
            url: '/sale/placeBid',
            data: {
              bidAmount: $('#amount').val(),
              hotelSale: saleId,
              currency: $('#currencies:selected').val()
            },
            method: 'POST',
            success: function (res, ts, xhr) {
              if (xhr.status == 200 && res.status == 200) {
                $.toaster({priority: 'info',message: 'Succesfully bidded on sale'})
              }else {
                //handle error
              }
            }
          })
        })
 });

html gets rendered into the templateContainer template via jsRender

 const html = template.render({viewLocalsHere});
 $('#templateContainer').html(html)

logging console.log($('#placeBid')) within the document.ready function shows that the element is being detected and there at the time of attaching the onclick handler, however clicking the button does not log Clicked place bid

What could be the problem? Thanks


Solution

  • I think you're misusing jquery's on function.

    http://api.jquery.com/on/

    When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.

    In order for your function to be called, the element with id '#placeBid' must have an element with id '#templateContainer' as its descendant. This is a delegated event. It seems you're looking for a directly bound event, so remove '#templateContainer' from your parameter, and the click handler will be bound to the button.

    $('#placeBid').on('click', function () {
        console.log('Clicked place bid')
        ...
    })