Durandal Modal Won't Close - modal-dialog

Modals are turning out to be more difficult than I thought :/
Got the modal loading up a view / view modal properly, clicking the save button saves the information (I do get a 'Should be Empty : []' from Q.js but apparently this isn't a problem?) the problem I am having is probably related to promises but if it is I can't find it.
Parent's view model -
var createNew = function () {
app.showModal(tfcreate).then(function (modalResult) {
if (!modalResult) { return false; }
var templateId = modalResult;
router.replaceLocation('#/templateformedit/' + templateId);
});
};
Modal's view model -
var cancel = function () {
this.modal.close(false);
};
var save = function () {
isSaving(true);
setRevisionInfo();
datacontext.saveChanges()
.then(alertMe)
.fail(initFailed)
.fin(complete);
function setRevisionInfo() {
templateForm().revisionLevel(1);
templateForm().createdById(shell.currentUser().id());
templateForm().lastRevisedId(shell.currentUser().id());
var nowDT = moment().format('LL');
templateForm().lastRevisedDT(nowDT);
templateForm().createdDT(nowDT);
}
function alertMe() {
return console.log('done'); // <<< This is firing ok
}
function complete() {
isSaving(false);
this.modal.close(templateForm().id()); // <<< Breakpoint reaches here just fine
}
};
If I press the cancel button which is bound back to cancel() it closes just fine, if I click the save button it hits save(), saves the object properly, and reaches all breakpoints but never closes. If after I save I press cancel it closes just fine again. I have tried calling cancel() during the complete() function and it reaches the statement, but again does not close. Any ideas???
Note : I can call router.replaceLocation from the modal and it will change the view just fine but the modal persists to the next view.
Edit : I added another button 'close' that is disabled until isSaving is finished and hasChanges is false and that lets me close it and everything just fine, but that shouldn't be necessary, right?

Per request:
Are you sure that this in complete() is still your vm context? Try var self=this; at the top of save() and in complete() self.modal.close(...)

Related

Ionic: How to override back button function?

I need to override the back button function for both buttons:
the back icon on top left corner of nav-bar
the hardware back button (for example in android)
but only for one specific view, not globally. How can i do that?
It is possible to override the back button functionality for both buttons from within your controller. Here is the code for that:
// run this function when either hard or soft back button is pressed
var doCustomBack = function() {
console.log("custom BACK");
};
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
var oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
doCustomBack();
};
var deregisterSoftBack = function() {
$rootScope.$ionicGoBack = oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
// cancel custom back behaviour
$scope.$on('$destroy', function() {
deregisterHardBack();
deregisterSoftBack();
});
Make sure to inject $rootScope into the controller.
For more details and a proper explanation, see my full answer at related question:
Ionic override all BACK button behaviour for specific controller
This code is for android button, while the button on the navigation bar is a bit more simple:
Android button :
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name=="home"){
alert("button back");
}
}, 100);
Ionic button :
You can edit your topic and see how you have defined your menus and your views?

How execute code every time that I view a page

I'm searching the mode to execute a code (in my case the retrieve of data to visualize from server) every time I view a page (every time the page is called by splitApp.toDetail or splitApp.backDetail). How can i do it?
P.S. The onBeforeRendering and onAfterRendering execute only the first time.
There is a solution for you. There is a event called routeMatched when navigation is triggered every time. You can attach the event in the detail page.
onInit : function () {
this._oRouter = sap.ui.core.UIComponent.getRouterFor(this);
this._oRouter.attachRouteMatched(this.handleRouteMatched, this);
},
handleRouteMatched : function (evt) {
//Check whether is the detail page is matched.
if (evt.getParameter("name") !== "detail") {
return;
//You code here to run every time when your detail page is called.
}
I´m using onBeforeShow in my target views for that.
onBeforeShow : function(evt) {
// gets called everytime the user
// navigates to this view
},
This is a function which is fired by a NavContainer on its children in case of navigation. It´s documented in the NavContainerChild.
If routing is used, another version of Allen's code:
onInit : function () {
this._oRouter = sap.ui.core.UIComponent.getRouterFor(this);
this._oRouter.getRoute("detail").attachMatched(this.handleRouteMatched, this);
},
handleRouteMatched : function (evt) {
//You code here to run every time when your detail page is called.
}

Closing Durandal modal

I have a Hottowel application and a Durandal modal dialog for creating a new entity. In it's viewmodel I have create and cancel functions, which both call close on success. The problem is that modal doesn't close when I call close from another function. It does close when I call it directly.
The code:
var close = function () {
dialog.close(this);
};
var cancel = function () {
datacontext.cancelChanges();
close();
};
var create = function () {
return datacontext.saveChanges()
.then(close);
};
What do you mean it doesn't work when you call it from another function? Are you sure that your context is still the same when you are calling it?
var close = function () {
var self = this;
dialog.close(self);
};
Try to update your close function to this and if it still isn't closing then could you please explain where you are calling it that it isn't closing from? From inside the same view model, from another view model, which function, etc...

TinyMCE4 How to toggle selfcreated Buttons

I have created a Button with the Tiny Method addButton().
How is it possible to toggle the State of the Button ?
In my first simple case I have a Button with Fullscreen
(Different Functionality than the built-in function)
and want to hide it after getting the Fullscreen State
and replace it with an "End Fullscreen" Button.
But I have not found the right way to show or hide them.
I know that the button will get an ID, but I dont know which one ...
If you add the button with:
editor.addButton('customFullscreen', {
tooltip: 'Fullscreen',
shortcut: 'Ctrl+Alt+F',
onClick: toggleCustomFullscreen,
onPostRender: function() {
var self = this;
editor.on('CustomFullscreenStateChanged', function(e) {
if (e.state) {
self.name('Close fullscreen');
//self.active(e.state); // uncomment for "pressed" look
} else {
self.name('Fullscreen');
}
});
}
});
and handle the event with
var customFullscreenState = false;
function toggleFullscreen() {
customFullscreenState = !customFullscreenState;
if (customFullscreenState) {
// do something, we are active
} else {
// do something else, we're unactive
}
editor.fire('CustomFullscreenStateChanged', {state: fullscreenState});
}
You should be able to have it look like wo different button and do two different things depending on state, but it will still just be one button that changes action and text.

Ignore multiple button taps after first one on iPhone webapp using jQuery Mobile?

Assume button A in an HTML5 webapp built with jQuery Mobile.
If someone taps button A, we call foo(). Foo() should get called once even if the user double taps button A.
We tried using event.preventDefault(), but that didn't stop the second tap from invoking foo(). event.stopImmediatePropagation() might work, but it also stops other methods further up the stack and may not lead to clean code maintenance.
Other suggestions? Maintaining a tracking variable seems like an awfully ugly solution and is undesirable.
You can set a flag and check if it's OK to run the foo() function or unbind the event for the time you don't want the user to be able to use it and then re-bind the event handler after a delay (just a couple options).
Here's what I would do. I would use a timeout to exclude the subsequent events:
$(document).delegate('#my-page-id', 'pageinit', function () {
//setup a flag to determine if it's OK to run the event handler
var okFlag = true;
//bind event handler to the element in question for the `click` event
$('#my-button-id').bind('click', function () {
//check to see if the flag is set to `true`, do nothing if it's not
if (okFlag) {
//set the flag to `false` so the event handler will be disabled until the timeout resolves
okFlag = false;
//set a timeout to set the flag back to `true` which enables the event handler once again
//you can change the delay for the timeout to whatever you may need, note that units are in milliseconds
setTimeout(function () {
okFlag = true;
}, 300);
//and now, finally, run your original event handler
foo();
}
});
});
I've created a sample here http://jsfiddle.net/kiliman/kH924/
If you're using <a data-role="button"> type buttons, there is no 'disabled' status, but you can add the appropriate class to give it the disabled look.
In your event handler, check to see if the button has the ui-disabled class, and if so, you can return right away. If it doesn't, add the ui-disabled class, then call foo()
If you want to re-enable the button, simply remove the class.
$(function() {
$('#page').bind('pageinit', function(e, data) {
// initialize page
$('#dofoo').click(function() {
var $btn = $(this),
isDisabled = $btn.hasClass('ui-disabled');
if (isDisabled) {
e.preventDefault();
return;
}
$btn.addClass('ui-disabled');
foo();
});
});
function foo() {
alert('I did foo');
}
});