Reputation: 17332
On my first event I will open a mbox dialog. mbox is a kind of extention for bootbox, which is for showing a modal. I need mbox to use another template as modal content.
So in the modal will be loaded with the content of createElement-Template. If the user has done some input changes the modal should be closed. Therefore there is the function modal("hide")
.
But as bbox
is been set in the first template-event and the closing of the modal will be done in the second template-event, I got problems to close the modal.
events
Template.main.events({
'submit form': function(event, template) {
event.preventDefault();
var bbox = mbox.dialog({
title: 'title',
message: Template.createElement
});
}
});
Template.createElement.events({
'change input': function(event, template) {
bbox.modal('hide');
}
});
UPDATE
The above problem works with a global var. Thanks for to Adam for that.
But not I would like to destroy a modal in a meteor package, which was created by another package. I tried to use a global var and I tried to use api.export()
. But still it doesn't work. I also tried to work with Sessions.
package-graph/lib/client/graph.js
var bbox;
CanvasManager = {
onShowAddToolTip (element) {
bbox = mbox.dialog({ // <-- Create Modal
title: "Title",
message: Template.search, // <-- Loading Template search with just one input field with typeahead
});
},
}
CanvasManger.create(...);
package-graph/lib/package.js
api.export('bbox');
The second package provide a typeahead-searchbox (sergeyt:typeahead
). By creating the modal in the first package, the Template will be loaded in the modal (helloludger:mbox
). Now the user can search via typeahead and select an item. After the selection the modal should be destroyed by `modal('hide').
package-search/lib/client/events.js
Template.searchMain.onRendered(function() {
Meteor.typeahead.inject();
});
package-search/lib/client/helper.js
Template.search.helpers({ // <-- getting the data for the input typeahead
searchData: function() {
return [
{
name: 'cat1',
valueKey: 'title',
displayKey: 'title',
header: '<h3 class="category-name">Category</h3>',
template: 'searchResults',
local: function() {
return Collection.find().fetch();
}
}
]
},
selected: function(event, suggestion) { // <-- by selecting an item, I can process the data and remove the modal
// do something
bbox.modal('hide'); // <!-- destroy modal
return;
}
}
});
Upvotes: 8
Views: 345
Reputation: 1160
If you're going to hack around with global variables, you can also hack around with your mbox
.
mbox.myModal = mbox.dialog({
title: 'title',
message: Template.createElement
});
and then in package-search/lib/client/helper.js
Template.search.helpers({
...
selected: function(event, suggestion) {
mbox.myModal && mbox.myModal.modal('hide');
mbox.myModal = null;
return;
}
}
});
Ideally though, you would create your own third independent module to communicate between your two packages, and inject that into both packages. That way they are not coupled and can both share state.
In this shared module, you only really need a setter and getter function that holds your modal instance. I'm not familiar with meteor so I'm not sure how you are going to do that, but judging by what you've already written, it should be possible.
Add a comment if you want to work through it.
Upvotes: 0
Reputation: 3240
Don't do this - it violates software engineering principles.
The reason you have struggled to find a solution is a strong hint that this is not a good way to structure your app.
You want packageMBox to embed packageTypeAhead, implying that packageMBox depends on packageTypeAhead.
And you want packageTypeAhead to reach into packageMBox and control it, requiring (thanks Gaelan) that packageTypeAhead depend on packageMBox.
This is bidirectional coupling, and even if you find a way to make it work, what did you achieve? You have two packages, neither of which can be used (or even tested properly) independently.
So the solution is: Combine the two packages into one package.
'Package for everything' is a good way to structure your app, but it is important to consider how and where you split functionality so you do not create more problems than you started with.
Upvotes: 2
Reputation: 1149
Make sure the second package has a dependency on the first:
api.use('first-package')
Only exports from dependencies are available.
Upvotes: 1
Reputation: 55613
Make bbox
a global variable:
var bbox;
Template.main.events({
'submit form': function(event, template) {
event.preventDefault();
bbox = mbox.dialog({
title: 'title',
message: Template.createElement
});
}
});
Template.createElement.events({
'change input': function(event, template) {
bbox && bbox.modal('hide');
}
});
Upvotes: 8