ATMartin / simple-modal-tutorial

3 stars 0 forks source link

click inside modal closes it #2

Open brianally opened 9 years ago

brianally commented 9 years ago

A form inside the modal, for example, will be useless because any click inside the modal will close it immediately. For any practical use besides a simple "click LITERALLY anywhere to close" msg popup, you need to remove the modal frame from within the background.

{{#if enabled}}
  <div {{action 'toggleModal'}} class="modal-background"></div>
  <div class="modal-frame">
      <div class="modal-title">
        {{title}}
      </div>
      <div class="modal-body">
        {{yield}}
      </div>
    </div>
{{/if}}

At least, I couldn't find any other practical way to stop the child's click from bubbling.

Thanks for the tut. The "expose" bit was exactly what i needed.

ATMartin commented 9 years ago

Hey @brianally - thanks for the catch!

Ember actually offers a modifier on the {{action}} helper: bubbles = false. This prevents actions from moving up the DOM tree to parent nodes. It works well for this method, but {{action}} doesn't seem to work without a function. :headscratch:

I was able to stub out an empty function on the component, and then add that as the action on the modal-frame div with bubbles=false to allow form components or links inside the modal to function as intended. A simple form I tested out worked just fine.

Here's the tl;dr:

controllers/simple-modal.js

...
actions: {
    toggleModal: function() { ... },
    preserveModal: function() {
        // This is a dead-end stub - nothing to see here!
    }
}
...

templates/components/simple-modal.hbs

...
<div {{action 'toggleModal'}} class="modal-background">
    <div {{action 'preserveModal' bubbles=false}} class="modal-frame">
...

All that said, your solution works just as well! I'd be more inclined to use your method in a real situation as it feels more stable. I'm certain there's a less hacky "Ember Way" to go about prevent propagation for nested elements but I couldn't find it in the docs. It looks like Views may have been used for this kind of control in the past, but they're now deprecated. Maybe I'm expected to implement the modal-frame as another component entirely? Components all the way down? /shrug

Thanks so much for catching this. I'll leave the issue open for anyone else who runs across this need, but it was really my original intent for the modal to disappear after clicking anywhere. This is just intended to be a good start. :)

brianally commented 9 years ago

@ATMartin That is a very clever approach. I knew about bubbles=false but that's to stop bubbling up from an action, not up to it. It never occurred to me to just add a dummy action to the frame. Brilliant!

I do think it's simpler to just put the frame outside the background in this case, although i like having a template that's a single nested DOM branch. It seems tidier.

In any case, this little hack could come in handy in other situations. Chapeau, monsieur!