ember-wormhole icon indicating copy to clipboard operation
ember-wormhole copied to clipboard

jQuery selecting contents of a wormhole from inside component

Open cdl opened this issue 9 years ago • 6 comments

I'm using an ember-wormhole inside a component, and am trying to access an element that's inside the wormhole with this.$() in the component.

component/template.hbs

{{#ember-wormhole to="destination"}}
  <a class="targetme">Target anchor</a>
{{/ember-wormhole}}

component/component.js

export default Ember.Component.extend({
  _select: function() {
    // doesn't work
    this.$('.targetme').focus();
    // does work
    Ember.$('#destination .targetme').focus();
  }.on('didInsertElement')
});

As mentioned in the sample above, using this.$ doesn't work, as this.$ is scoped to the component view, ember-wormhole moves the contents out of that view, meaning the component view is essentially empty (the contents I'm wanting to access are inside the wormhole).

To circumvent this, I currently have to just do a global selection with Ember.$ in my component, and target the wormhole the contents are moved to (as seen above).

Is there a better way to do this currently, that doesn't involve a global selection with Ember.$?

cdl avatar Jul 30 '15 15:07 cdl

Likely ember-wormhole should just override .$() to do what people expect. If it is rendered in place it uses its element if it has been wormholed it should use the destinationElement.

A concern though, it could scope it to more. I was thinking it would be safer originally for ember-wormhole to move a single static element it rendered in its layout, but there are use cases where having an extra element complicates. Like moving a element-less template into the title tag.

krisselden avatar Jul 30 '15 17:07 krisselden

@krisselden What do you think about a component property to opt into such a static container?

chrislopresto avatar Jul 31 '15 02:07 chrislopresto

Could work in tandem with an override of .$()

chrislopresto avatar Jul 31 '15 02:07 chrislopresto

I think the wormhole is invoked inside the component with _select shown in @cdl's post. There's nothing wormhole can do about the $ function of things containing it... right?

raycohen avatar Jul 31 '15 02:07 raycohen

Problem restated without pod-style file names, and showing an action:

components/my-cool-form-template.hbs

<form {{action "submit" on="submit"}}>
  {{#ember-wormhole to="destination"}}
    <input class="focus-on-submit">
  {{/ember-wormhole}}

  <button>Submit!</button>
</form>

components/my-cool-form.js

Ember.Component.extend({
  layout: layout, // from my-cool-form-template.hbs
  actions: {
    submit() {
       this.$('.focus-on-submit').focus(); // not going to work
       Ember.$('#destination .focus-on-submit').focus(); // will work
    }
  }
})

raycohen avatar Jul 31 '15 02:07 raycohen

My suggestion for a better way to do this, if you want to avoid Ember.$('#destination'), is to make an event emitter and pass it into a component inside the wormhole:

components/my-cool-form.js

Ember.Component.extend(Ember.Evented, {
  layout: layout, // from my-cool-form-template.hbs
  myCoolForm: Ember.computed(function() { return this; }),
  actions: {
    submit() {
      this.trigger('focus-that-input');
    }
  }
})

components/my-cool-form-template.hbs

<form {{action "submit" on="submit"}}>
  {{#ember-wormhole to="destination"}}
    {{#wormhole-input-wrapper submitter=myCoolForm}}
      <input class="focus-on-submit">
    {{/wormhole-input-wrapper}}
  {{/ember-wormhole}}

  <button>Submit!</button>
</form>

and components/wormhole-input-wrapper.js

Ember.Component.extend(Ember.Evented, {
  didInsertElement() { // simple example, properly _super(), setup, and teardown as needed
    var submitter = this.get('submitter');
    submitter.on('focus-that-input', this, this.focusThatInput);
  },
  focusThatInput() {
    this.$('.focus-on-submit').focus(); // woohoo!
  }
})

raycohen avatar Jul 31 '15 02:07 raycohen