Modal defined on route (should be usable using {{#link-to}} )

I tried most of the modal techniques discussed previously here. I want modal to appear when I transition to a route. So when I use {{#link-to}} for that particular route it should display it on modal and should return back to previous route on close.

Can this be done? Is there a jsbin - I can refer to?

1 Like

what’s your use case exactly?

I want to enable login whenever user tries to edit/delete a record if not logged in. I’m using this library(GitHub - simplabs/ember-simple-auth: A library for implementing authentication/authorization in Ember.js applications.) where routes created with auth mixin Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin, {}); will redirect to login route.

Perhaps, I’m not fully understanding but it sounds like all you need is a nested route within a resource.

this.resource('foo', { path: 'foo'}, function () {
      this.route('modal');
});

You’d have an unnamed {{outlet}} on the FooIndex template and just add some CSS styling to position the ModalView.

I can JSfiddle it if want you want is when you go to /foo/modal it opens a modal window on top of /foo

@jasonmit Yup. that is wat I’m looking for. JSBIN will be really very helpful (preferably twitter boostrap modal). Thanks in advance.

I’ve been working on something somewhat similar. It’s a route-based implementation using Bootstrap modals. Here’s a JS Bin.

Disclaimer: I’m new to Ember, so I’m still learning “best-practices.” Feedback is always welcome.

1 Like

I have it as a view. IMO the route shouldn’t know anything as to how a view is displayed, but we could still re-use it form multiple places.

Directly from a view

<div> Some markup</div>
{{#modal-view}}
some content
{{/modal-view}}

Have a view that inherits from it so it gets modal behavior. Then your route simply renders listEditView as usual, but it will show up as a modal.

App.ListsEditView = App.ModalView.extend()

No need for outlet since all the magic is done via CSS, but we could use them.

The ModalView code is simple:

    ModalView = Ember.View.extend {
  actions:
    close: ->
      view = @
      @$('.modal').one "transitionend", ->
        view.controller.send('close')
      @$('.modal, .modal-backdrop').removeClass('in')
  didInsertElement: ->
    view = @
    @$('.modal, .modal-backdrop').addClass('in')
    @$('.modal-backdrop').on 'click', ->
      view.send 'close'
  layoutName: 'modal_layout'
}

App.ModalView = ModalView

The layout is simple as well

.modal-backdrop.fade &nbsp;
.modal.fade
  div class=loading
    = yield

Then your view (list Edit View), simply defines content within some divs used by bootstrap

.modal-header
  button.close click="close target=view" type="button" &times;
  h3 Modify List

.modal-body
  = partial 'lists/form'
  p.small.faded Created {{time datetime=created_at}}
  p.small.faded Last modified {{time datetime=updated_at}}

.modal-footer
  input.btn click="close target=view" type="button" value="Close" disabled=loading
  input.btn.pull-left click=delete type="button"  value="Delete list" disabled=loading
  input.btn.btn-primary click=save type="button" value="Save List" disabled=loading

I considered adding a header and footer property to the modal-view, that worked fine, so the divs and close button were always defined in the layout, however, I found that I was frequently overriding those sections with more complex content so I moved the responsibility to actual view as shown above.

Then in your controller, you need to implement a close and a done action. The first is an opportunity to do something when we’re closing the modal (e.g. cancel the current action). done simply returns to the previous route. Since this is a common task, we have a mixin with those two. Also in the hook we store the currentPath before navigating so we know how to go back.

ModalMixin = Ember.Mixin.create {
  actions: {
    done: ->
      @router.transitionTo @get('returnTo')
    close: ->
      @done()  # usually overriden when mixed to cancel/rollback changes
  }

  beforeModel: ->
    @set 'returnTo', @controllerFor('application').get('currentPath')
}

App.ModalRouteMixin = ModalRouteMixin

Hope this helps.

1 Like

@MiguelMadero Thanks. Sample code looks good, I will try putting it into my app and see if it fits the bill. My only issue with other modal implementation was I was unable to bind communicate after I performed some action in my controller.

Example: I hit “save” on the modal window. It triggers controller/actions/save. Now if the save is successfull, close the modal or display error on modal. How do I do that?

1 Like

Hi the JSBin looks good but can anyone tried clicking the back button??? its showing up the modal again. is that the best practice. I am looking for similar kind of solution where when a modal is in display the back button should either be disabled so that the parent view could not be changed while displaying the modal or else when the back button is pressed the modal need to be closed. I am ver new to ember and i struck in this.

1 Like

@hind3nbug Do you have any idea why there is no slide animation on the modal on enter and exit?

I´ve tried to animate but so far without any luck.

Thanks

@bob_ludvigsen It is possible via css for sure. just google it