Kevin Whitaker
Kevin Whitaker

Reputation: 13425

Backbone.js: trigger an event on a view after the render

Is there a way to bind an event to occur after the render is finished in a backbone view?

I'm trying to attach a jQuery Date Range Picker to an input which is appended to the DOM after a link is clicked, but if I do it during the render, the range picker appears in the wrong place (because the input hasn't been given a DOM position yet). So, I need to wait until after the input has been rendered before I attach the date picker. Coffeescript is below.

@makeDateRangePicker is a function that inits the date picker

class window.ClientDestinationPricingFieldsView extends ModelSaverView
  template: (json) ->
    _.template(jQuery("#special-pricing-timeframe-template").html()) json

  render: ->
    jQuery(@el).html @template(@model.toJSON())
    @makeDateRangePicker jQuery(@el).find("input[name=date_range]")
    this

Upvotes: 1

Views: 2620

Answers (4)

Khaja Minhajuddin
Khaja Minhajuddin

Reputation: 6741

One way to do this is to trigger a custom event from the parent view after rendering is complete. $('body').trigger('my-rendering-is-done') (a better way would be to trigger it on the view which is being rendered from the calling code). And have a listener in your view which uses the makeDateRangePicker.

Upvotes: 0

Sơn Trần-Nguyễn
Sơn Trần-Nguyễn

Reputation: 2228

I would try this:

class window.ClientDestinationPricingFieldsView extends ModelSaverView
  events:
    'click input[name=date_range]': 'makeDateRangePicker'

  template: (json) ->
    _.template(jQuery("#special-pricing-timeframe-template").html()) json

  render: ->
    jQuery(@el).html @template(@model.toJSON())
    this

You would have to modify @makeDateRangePicker to take an event element instead.

Upvotes: 2

Linus Thiel
Linus Thiel

Reputation: 39223

Edit: So, my last stab at a solution was not.

What you're saying is that after your call to jQuery(@el).html, the expected html is not there? That sounds very weird. I think it might be as simple as that you need to quote your attribute value:

jQuery(@el).find("input[name='date_range']")

Note the ' single-quote around date_range.

Edit: Sorry, after verifying that it actually seems to work without quotes. I've been bitten by something similar before. Anyway, if the question is correct as it is now (after it's been updated with info about adding the input on a click event), then you should call makeDateRangePicker right after you append the element, right?

Upvotes: 1

mu is too short
mu is too short

Reputation: 434665

You can usually use setTimeout with a timeout of zero for this sort of thing. setTimeout(..., 0) essentially queues up a function to be called once the browser has control again. Something like this:

render: ->
  jQuery(@el).html @template(@model.toJSON())
  setTimeout
    => @makeDateRangePicker jQuery(@el).find("input[name=date_range]")
    0
  @

I often use this trick with Google Maps to make it positioned and sized properly.

Upvotes: 1

Related Questions