I am trying to make a re-useable confirm modal in Meteor. I have the modal working in the sense it opens and displays the content. The idea is I can use this anywhere and it will return a value if the user clicks confirm then I can run any server side method I choose. The confirm template js is simple and looks like this:
Template.confirm.events({
'click .confirm': function() {
// I want to let the template that opened the modal know the user has confirmed. How do I pass this information?
},
'click .cancel': function() {
//Close the modal
}
});
I know there are solutions e.g sweet alerts but I am using Zurb Foundation for my UI and want to keep everything within this framework for consistency and control. Can anyone help point me in the right direction?
Many thanks in advance.
There's no standard way to go about this, but I'd suggest passing the modal a reactiveVar that you observe outside the modal and trigger your server-side method when the reactiveVar changes to the value you want. Some skeleton code might look like:
html
{{> confirm triggerVar=myReactiveVar}}
modal js
Template.confirm.events({
'click .confirm': function() {
this.triggerVar.set(true);
},
'click .cancel': function() {
this.triggerVar.set(false);
}
});
in your controller js
Template.someTemplate.onCreated(function() {
this.myReactiveVar = new ReactiveVar();
})
Template.someTemplate.onRendered(function() {
// observe changes on your fancy reactiveVar
this.autorun(() => {
if (this.myReactiveVar.get() === true) {
// fire whatever server-side action you want
}
})
})
Related
I have a few different modals on a page, and it all works as it should, but if a user makes some input on form fields in a modal and then accidentally clicks outside of the modal (which closes it), they loose their changes, since if the user clicks the same button they pressed to open the modal, the data they entered will be overwritten with data pulled from the database.
So I'd like to have a function for "reopen last closed modal" that simply shows the modal again in it's last used state - with whatever data was in it.
Essentially like a Ctrl-Z for accidentally closing a modal.
It's really simple if you know the ID of the modal. Such as:
$('#myModal1').modal('show'); });
But because I have several different modals available on a page, and I don't want to have a bunch of "restore" buttons, I need to be able to detect the ID of the last closed modal.
If there's not a simpler way, I could capture the ID each time a modal is closed, and then use that ID if the modal needs to be reopened without changing its data. Something like this:
$('#myModal1').on('hidden.bs.modal', function (e) {
var LastModal = '#myModal1';
})
$('#myModal2').on('hidden.bs.modal', function (e) {
var LastModal = '#myModal2';
})
function reOpen() {
$(LastModal).modal('show');
}
But I'm guessing there's a way that's simpler and doesn't require me to state all my modals ID's in JS/jQuery. Any ideas?
I've made a few tweaks, and this is working well for me now, with essentially no other hassle than a few short lines of code in my script file.
var LastModal;
$('.modal').on('hidden.bs.modal', (e) => {LastModal = $(e.target).attr('id'); })
function reOpen() { $('#'+LastModal).modal('show');}
Just use the style class "modal" for your modals, and to call the "reOpen", just have something like:
<span onclick='reOpen();'>Reopen</span>
Thanks #marekful for your suggestion!
Also, if you want to access this (or any other function) by pressing Ctrl+Z, you can add this:
// press Ctrl+Z to restore modal
$(document).keydown(function(evt){
if (evt.keyCode==90 && (evt.ctrlKey)){
evt.preventDefault();
reOpen();
}
});
The scenario I'm trying to solve is to disable that the escape-button closes the dialog AFTER the modal has been instaniated (the dialog is set to a loading state). So in other words after I have instaniated my modal like this:
(this.$el).modal("show");
The user presses a submit button and the dialog is set to a loading state and I want to disable the escape-button since the user should not be able to close the dialog in this state.
I have tried this:
(this.$el).modal({ keyboard: false });
But it does not work, it seems that Bootstrap only reads those options when it instaniates the modal dialog...
So my question is if it is possible to get a hold of the actual bootstrap modal-instance to be able to change the options-object? According to the documentation it should be possible (or have I misunderstood the docs?), but I cannot figure out how.
Here is what it says in the documentation (http://getbootstrap.com/javascript/):
If you'd like to get a particular plugin instance, retrieve it directly from an element:
$('[rel="popover"]').data('popover').
Any ideas?
Ok, I figured out how to get ahold of the modal dialog instance after some experimentation:
var bootstrapModalInstance = this.$el.data("bs.modal");
And then I could set the options on the instance like this:
bootstrapModalInstance.options.keyboard = !this.model.isSyncing;
Sadly enough, this did not solve the problem since the escape-key-event-listener is setup during the modal instaniation like this:
From bootstrap.js
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) { // The event listener is setup on initalization
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide() // !!! Does not check the instance options.keyboard flag status, so I had to add && this.options.keyboard here
}, this))
} else if (!this.isShown) {
this.$element.off('keydown.dismiss.bs.modal')
}
}
And as I wrote in the code comment above adding the instance options.keyboard check in the event listener solved the issue.
I have an emberjs web app where one of my views is a search page to query a database of records. I have the ability to filter by date and am using JQuery's datepicker.
The problem I am having is that if a user opens the datepicker and then hits either the browser back or forward button it stays active on the screen until a user clicks away. To clarify the process is as below:
Navigate to search page
Click select date
Datepicker appears
User clicks the browsers back button
Previous page loads BUT with datepicker still lingering around
Does anyone have any suggestions of how to hide or destroy the datepicker when a browsers back button is pressed?
Thanks!!
EDIT----------------------------
Current code:
Formal.Route.Search = Ember.Route.extend({
deactivate: function () {
console.log("hi");
$("ui-datepicker-div").datepicker("destroy");
},
Put the removal logic at View instead Route. Lets assume your template name is "search", then
App.SearchView=Ember.View.extend({
didInsertElement:function(){
$("#ui-datepicker-div").datepicker();
},
willDestroyElement:function()){
$("#ui-datepicker-div").datepicker("destroy");
}
});
Note: I assumed your selector is ID, if it is css class then use $(".ui-datepicker-div")
If you would like to write datepicker as component which can be used across the application then do watch the Screencast here http://eviltrout.com/2014/06/03/jquery-component.html
P.S. If you still could not figure out, please show your code in http://jsbin.com/
Thank you all very much for your help!
I resolved the issue with the following:
Formal.View.Datepicker = Ember.TextField.extend({
destroyDatepicker: function () {
this.$().datepicker("hide");
},
});
For some reason "destroy" was not doing the trick but "hide" does. If anyone has any insight into why this is I'd love to hear.
I am using Angular Bootstrap to display a Modal (the one presented here), which works perfectly. However, default behavior of this Angular extension is that the modal is reconstructed (and a new instance of its controller will be creatred) whenever it is closed and then opened again.
Since I have some pretty advanced stuff going on inside the Modal, I would like the modal to just be hidden when it is closed, so that its state remains. I have searched around a bit, but unfortunately could not find a simple and effective answer.
Just hiding it would be an option, but this then has to happen whenever the modal is closed, so also when it closes because the backdrop is clicked. And I want the same animation as when the modal is opened in the normal way.
Why don't you abstract the modal state into its own service? That way, whenever the modal controller is created, it uses the service to setup the view state on initialisation.
Eg. create a service
.factory('ModalStateService', function(){
var state = {
someValue: 'something'
};
return {
getState: function() { return state; }
};
});
Then in your controller:
.controller('ModalCtrl', function($scope, ModalStateService){
$scope.viewState = ModalStateService.getState();
});
Then in your modal content view for example:
<span>{{viewState.someValue}}</span>
If you were then to set someValue inside your modal, say through an input, the service state would be updated. Then when you create and destroy your modal, the state will persist.
As you might already know Angular initializes a controller when the associated view is added to the DOM. So the plugin author might have decided to add and remove the view element so that he does not have to worry about clearing the 'scope'each time user opens and closes the modal.
For example, we have a login box in the modal and if the scope is not cleared, it will keep the filled in details even the next time we show it.
An easy hack to solve your problem will be to wrap the originl modal in a custom directive, reneder it. And just change the display property of your custom modal to show and hide the modal ;)
in a single page web app, if I create jquery ui dialog on the fly like this:
$("<div>hello</div>").dialog({
buttons : {
"cancel" : function() {
$(this).dialog("close");
}
}
});
Do I need to do any special clean up after each closing? Do I need to call dialog's "destroy"?
You should call destroy if you plan to completely re-create the dialog each time it's opened, as would happen it the code above is called more than once.
If the dialog only gets opened once, it doesn't matter.