Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Close modal which has been created in another event function

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;
        }
    }
});
like image 295
user3142695 Avatar asked Sep 30 '15 22:09

user3142695


3 Answers

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');
    }
});
like image 50
Adam Avatar answered Nov 03 '22 01:11

Adam


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.

like image 33
JeremyK Avatar answered Nov 03 '22 00:11

JeremyK


Make sure the second package has a dependency on the first:

api.use('first-package')

Only exports from dependencies are available.

Relevant Meteor docs

like image 21
Gaelan Avatar answered Nov 03 '22 00:11

Gaelan