ember-wormhole
ember-wormhole copied to clipboard
jQuery selecting contents of a wormhole from inside component
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.$
?
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 What do you think about a component property to opt into such a static container?
Could work in tandem with an override of .$()
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?
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
}
}
})
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!
}
})