awkward / backbone.modal

A plugin for Backbone.js that simplifies creating modals for your application.
http://awkward.github.io/backbone.modal/
Other
362 stars 71 forks source link

Ability to provide arguments in constructor #65

Closed alfredo-cp closed 7 years ago

alfredo-cp commented 9 years ago

I'm trying to create a layer up to Backbone.Modal so I can use a Base Modal object whenever I require a new modal.

This doesn't work. Is there any way to achieve this?

var Modal = Backbone.Modal.extend({
    template: _.template('<h1>Modal Title</h1><div class="my-container"></div>'),
    viewContainer: '.my-container'
});

var modalView = new Modal({
    views: {
      'click .whatever': {
        view: _.template('<h2>View</h2>')
      }
    }
});

or even better

var Modal = Backbone.Modal.extend({
    cancelEl: '.cancel-button'
});

var modalView = new Modal({
  template: _.template('<div>Modal HTML</div>')
});
tylerjharden commented 9 years ago

@alfredo-cp This is my current example of a modal with a single Input element, the way you do this is by creating a "Modal Model" to handle the attributes of your modal's view, as is typical MVC.

The SingleInputModal constructor:

var SingleInputModal = Backbone.Modal.extend({
        template: Handlebars.compile($('#modal-single-input').html()),
        submitEl: '.bbm-button-submit',
        cancelEl: '.bbm-button-cancel',
        submit: function() {
            this.model.get('onSubmit').apply(this, arguments);
        },
        onShow: function() {
            if (this.$("input")[0]) {
                this.$("input").first().focus();
            }
            this.model.get("onShow").apply(this, arguments);
        },
        onRender: function() {
            if (this.$(".fg-input")[0]) {
                this.$(".fg-input").floatingLabel();
            }
            this.model.get("onRender").apply(this, arguments);
        }
    });

ModalModel class:

var ModalModel = Backbone.Model.extend({
        defaults: function() {
            return {
                onSubmit: function() {},
                onConfirm: function() {},
                onCancel: function() {},
                onShow: function() {},
                onRender: function() {},
                cancelBtnText: 'Cancel',
                submitBtnText: 'Submit',
                prevBtnText: "Previous",
                nextBtnText: "Next"
            };
        }
    });

An example of an implementation of the SingleInputModal:

app.commands.setHandler("modal:adRename", function(ad) {
            modalsLayout.modals.show(new SingleInputModal({
                model: new ModalModel({
                    submitBtnText: 'Save',
                    message: 'Enter a new name for your creative',
                    placeholderText: 'my ad name',
                    title: 'Rename Creative',
                    onShow: function() {
                        console.log(this);
                        // Set input to ad's current name
                        this.$el.find('input').first().val(ad.name);
                    },
                    onSubmit: function() {
                        var view = this,
                            model = view.model,
                            newData = view.$el.find('input').first().val();
                        app.module('adBrowser.cards').collection.get(ad.ad_id).save("name", newData);
                        app.execute("adBrowser:selectedAdsUpdated");
                    }
                })
            }));
        });

So ignoring the domain specific code for the project I am working on, if you just pass in a model as a model to the Modal constructor, you can then access everything transparently from the model, which is the expected behavior from your post. Hope this helps!

jimf commented 7 years ago

Closing due to age and lack of activity, but feel free to reopen if you still need assistance.