Mootools class: call a class method from an event handler - class

is it possible to call a class method from within an event handler?
I mean, something like this:
initialize: function(options) {
/* initial options */
this.setOptions(options);
this.area = (this.options.status == 'out') ? $(this.options.loggedoutArea) : $(this.options.loggedinArea);
this.button = $(this.options.buttonArea);
this.button.addEvent('click', function(){
this.showHideBanner();
});
},
showHideBanner: function() {
this.area.setStyle('display', 'none');
},
see full example here http://jsfiddle.net/dvzj6/

I managed to find a solution using this code:
initialize: function(options) {
/* initial options */
this.setOptions(options);
this.area = (this.options.status == 'out') ? $(this.options.loggedoutArea) : $(this.options.loggedinArea);
this.button = $(this.options.buttonArea);
this.button.addEvent('click', function(){
this.showHideBanner();
}.bind(this));
},
see also: http://jsfiddle.net/uA3Ak/

Related

how can you use oncanplaythrough after a setimeout?

i assume this doesn't work because canplaythrough is fired too early?
function splasher() {
showDelay = setTimeout(vidCheck, 6000);
};
function vidCheck() {
vid.addEventListener("canplaythrough", showPage);
};

SailsJS Installable Hook not executing the beforeCreate override

I tried adding an installable hook sails-hook-myoverride that looks like this:
let carryOn = (values, proceed, previous) => _.isFunction(previous) ? previous(values, proceed) : proceed();
module.exports = function (sails) {
return {
initialize: function (cb) {
sails.after(['hook:orm:loaded'], function () {
_.each(sails.models, (model) => {
let previousBeforeUpdate = model.beforeUpdate;
model.beforeUpdate = function (values, proceed) {
console.log("myoverride::beforeUpdate", values);
return carryOn(values, proceed, previousBeforeUpdate);
};
let previousBeforeCreate = model.beforeCreate;
model.beforeCreate = function (values, proceed) {
console.log("myoverride::beforeCreate", values);
return carryOn(values, proceed, previousBeforeCreate);
};
});
cb();
});
}
}
};
Then in my Test model I added both beforeUpdate and beforeCreate methods:
beforeUpdate: function (values, cb) {
console.log('Test::beforeUpdate');
cb();
},
beforeCreate: function (values, cb) {
console.log('Test::beforeCreate');
cb();
}
And then I called POST on http://localhost:1337/test to test it.
Surprisingly, sails printed only Test::beforeCreate and not myoverride::beforeCreate as well, as I was hoping it would.
Google did not help and neither did Sails documentation :(
I'm completely lost at the moment...
OK, apparently, using sails.after(['hook:sockets:loaded'], function () { works for some reason...

Change props value in vuejs2

I am new in vuejs2 development. I am working in a modal development. I kept the modal body code in a component and displaying that modal in another component. I have below code in modal body component.
<script>
import SemanticModal from 'vue-ya-semantic-modal'
export default {
components: { SemanticModal: SemanticModal() },
name: 'ModalBody',
props: ['active1',],
data() {
return {
visible: false
}
},
methods: {
close() {
this.$emit('sendValue', false); //this is working
this.visible = false
},
open () {
this.visible = true
},
},
watch: {
active1 () {
if (this.active1 && !this.visible) this.open()
else if (!this.active1 && this.visible) this.close()
},
},
directives: {
'click-outside': {
bind: function(el, binding, vNode) {
el.onclick = function(e) {
var modal = document.getElementsByClassName("modal");
el.addEventListener('click', function (event) {
if (!modal[0].contains(event.target)) {
vNode.context.$emit('sendValue', false); //this is not working
this.visible = false
}
})
}
}
}
}
}
I am calling that model (child) component in parent component like below
<modal-body :active1="active1" #sendValue="active1 = $event"></modal-body>
I need to change the below props active1 value to false from child to parent component.
You are handling click event by using directives.
According to your requirement , clickoutside directive should emit sendValue event from child to parent. But i feel like your code has some complications.
The proper code to accomplish your scenario is below
directives: {
'clickoutside': {
bind: function(el, binding, vNode) {
el.onclick = function(e) {
console.log("binding clicked");
vNode.context.$emit('sendValue', false);
}
}
}
}
if your objective is to use click event you can use #click binding to accomplish the same

sapui5, MessageToast.show is not a function, although sap/m/MessageToast has already been imported

I would like to display a messager in sapui5 Application, when onSave is printed or at the init function ist started. but i have always a error in the console and the messageToast do not work.
Errormessage in console:
Uncaught (in promise) TypeError: MessageToast.show is not a function
this is my controller.js:
sap.ui.define(['sap/ui/core/mvc/Controller',
'timeTrackertimeTracker/controller/BaseController',
'sap/ui/model/json/JSONModel',
"sap/m/MessageToast",
"sap/ui/model/odata/ODataModel",
"sap/ui/core/routing/History"
],
function(Controller, BaseController, MessageToast, JSONModel, ODataModel, History) {
"use strict";
//Global variables
//var _oController, oModel, oView;
var Calendarcontroller = BaseController.extend("timeTrackertimeTracker.controller.Calendarform", {
/* =========================================================== */
/* lifecycle methods */
/* =========================================================== */
onInit: function() {
//Store controller reference to global variable
this.getRouter().getRoute("Calendarform").attachPatternMatched(this._onRouteMatched, this);
MessageToast.show("init");
},
/* =========================================================== */
/* event handlers */
/* =========================================================== */
_onRouteMatched: function() {
// register for metadata loaded events
var oModel = this.getModel("appointments");
oModel.metadataLoaded().then(this._onMetadataLoaded.bind(this));
},
_onMetadataLoaded: function () {
// create default properties
var oProperties = {
Id: "Id" + parseInt(Math.random() * 1000000000)
/* duration: "",
resttime: "",
title: "",
starttime: "",
endtime: "",
Description: ""*/
};
// create new entry in the model
this._oContext = this.getModel("appointments").createEntry("/appointments", {
properties: oProperties
,
success: this._onCreateSuccess.bind(this)
});
// bind the view to the new entry
this.getView().setBindingContext(this._oContext, "appointments");
},
onSave: function(oEvent) {
// bind the view to the new entry
//this.getView().setBindingContext(this._oContext);
this.getModel("appointments").submitChanges();
},
_onCreateSuccess: function (oEvent) {
// navigate to the new product's object view
this.getRouter().navTo("AppointmentsList", true);
// unbind the view to not show this object again
this.getView().unbindObject();
// show success messge
/* var sMessage = this.getResourceBundle().getText("newObjectCreated", [ oEvent.Id ]);
MessageToast.show(sMessage, {
closeOnBrowserNavigation : false
});*/
},
/* _onCreateSuccess: function (oAppointment) {
// show success messge
var sMessage = this.getResourceBundle().getText("newObjectCreated", [ oAppointment.Title ]);
MessageToast.show(sMessage, {
closeOnBrowserNavigation : false
});
},
*/
onCancel: function() {
this.onNavBack();
//this.getView().getModel("appointments").deleteCreatedEntry(this._oContext);
},
/**
* Event handler for navigating back.
* It checks if there is a history entry. If yes, history.go(-1) will happen.
* If not, it will replace the current entry of the browser history with the worklist route.
* #public
*/
onNavBack : function() {
/* var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("AppointmentsList");*/
var oHistory = History.getInstance(),
sPreviousHash = oHistory.getPreviousHash();
// discard new product from model.
this.getModel("appointments").deleteCreatedEntry(this._oContext);
if (sPreviousHash !== undefined) {
// The history contains a previous entry
history.go(-1);
} else {
// Otherwise we go backwards with a forward history
var bReplace = true;
this.getRouter().navTo("AppointmentsList", {}, bReplace);
}
}
});
return Calendarcontroller;
});
Exchange places of parameters MessageToast and JSONModel in function (line 9): in the dependency list sap/ui/model/json/JSONModel mentioned before sap/m/MessageToast

Pass a controller to $ionicModal

I am wondering if you can pass a controller to the $ionicModal service. Something like.
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope,
controller: 'MyModalCotroller'
})
A little context: I would like to have a modal that is distributed across the app and I dont want to repeat all the methods (hide, show, buttons inside the modal) in every controller and I would like to remove the methods from the 'Main Controller' to keep things clean. This would encapsulate the functionality of the modal.
Is there a way to do this.?
Thanks
Just add the controller you want to use in the body of the html of the modal. I created a fiddle to show you an example based off the one provided in the ionic docs: http://jsfiddle.net/g6pdkfL8/
But basically:
<-- template for the modal window -->
<ion-modal-view>
<ion-content ng-controller="ModalController">
...
</ion-content>
<ion-modal-view>
There's no direct way of doing so in ionic. However, if you really want to have some common code being segregated at one place,
You can use services to do so. Here' how.
In your modal declaration, pass scope as null, also the modal declaration should move in a service.
app.service('utilsService', function($ionicModal) {
this.showModal = function() {
var service = this;
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: null,
controller: 'MyModalCotroller'
}).then(function(modal) {
service.modal = modal;
service.modal.show();
});
};
this.hideModal = function() {
this.modal.hide();
};
});
All your common methods will also move down into the same service.
Add the reference to this service into your controller's scope.
app.controller('indexController', function($scope, utilsService) {
$scope.utilsService = utilsService;
});
Now, you can call all the common methods from the view directly using this service.
e.g. <button ng-click="utilsService.hideModal()">Hide modal</button>
Based on this question and other needs I create a service that can be useful.
Anyway use the CodePen code, this updated, improved and it makes available the parameter 'options' of $ionicModal.
See this post: Ionic modal service or see in operation: CodePen
(function () {
'use strict';
var serviceId = 'appModalService';
angular.module('app').factory(serviceId, [
'$ionicModal', '$rootScope', '$q', '$injector', '$controller', appModalService
]);
function appModalService($ionicModal, $rootScope, $q, $injector, $controller) {
return {
show: show
}
function show(templateUrl, controller, parameters) {
// Grab the injector and create a new scope
var deferred = $q.defer(),
ctrlInstance,
modalScope = $rootScope.$new(),
thisScopeId = modalScope.$id;
$ionicModal.fromTemplateUrl(templateUrl, {
scope: modalScope,
animation: 'slide-in-up'
}).then(function (modal) {
modalScope.modal = modal;
modalScope.openModal = function () {
modalScope.modal.show();
};
modalScope.closeModal = function (result) {
deferred.resolve(result);
modalScope.modal.hide();
};
modalScope.$on('modal.hidden', function (thisModal) {
if (thisModal.currentScope) {
var modalScopeId = thisModal.currentScope.$id;
if (thisScopeId === modalScopeId) {
deferred.resolve(null);
_cleanup(thisModal.currentScope);
}
}
});
// Invoke the controller
var locals = { '$scope': modalScope, 'parameters': parameters };
var ctrlEval = _evalController(controller);
ctrlInstance = $controller(controller, locals);
if (ctrlEval.isControllerAs) {
ctrlInstance.openModal = modalScope.openModal;
ctrlInstance.closeModal = modalScope.closeModal;
}
modalScope.modal.show();
}, function (err) {
deferred.reject(err);
});
return deferred.promise;
}
function _cleanup(scope) {
scope.$destroy();
if (scope.modal) {
scope.modal.remove();
}
}
function _evalController(ctrlName) {
var result = {
isControllerAs: false,
controllerName: '',
propName: ''
};
var fragments = (ctrlName || '').trim().split(/\s+/);
result.isControllerAs = fragments.length === 3 && (fragments[1] || '').toLowerCase() === 'as';
if (result.isControllerAs) {
result.controllerName = fragments[0];
result.propName = fragments[2];
} else {
result.controllerName = ctrlName;
}
return result;
}
} // end
})();
Usage:
appModalService
.show('<templateUrl>', '<controllerName> or <controllerName as ..>', <parameters obj>)
.then(function(result) {
// result from modal controller: $scope.closeModal(result) or <as name here>.closeModal(result) [Only on template]
}, function(err) {
// error
});
You can use another service to centralize the configuration of all modals:
angular.module('app')
.factory('myModals', ['appModalService', function (appModalService){
var service = {
showLogin: showLogin,
showEditUser: showEditUser
};
function showLogin(userInfo){
// return promise resolved by '$scope.closeModal(data)'
// Use:
// myModals.showLogin(userParameters) // get this inject 'parameters' on 'loginModalCtrl'
// .then(function (result) {
// // result from closeModal parameter
// });
return appModalService.show('templates/modals/login.html', 'loginModalCtrl as vm', userInfo)
// or not 'as controller'
// return appModalService.show('templates/modals/login.html', 'loginModalCtrl', userInfo)
}
function showEditUser(address){
// return appModalService....
}
}]);
Create a directive to be used inside the modal and inside the directive you can assign the modal it's own controller and scope. If someone wants some example code I can put something up.
I was looking for a simple way to attach a controller to a modal instance and manage all modals with a single service. Also, I wanted the modal to have it's own isolated child scope. I wasn't satisfied with using ng-controller and I found other answers to be overly complicated to the point where you could easily loose track of scope and end up with circular or unidentifiable dependencies. I created the following service for my purposes.
You can pass an optional parentScope parameter to explicitly assign a parent scope to the created modal scope.
You could easily modify the instantiateModal method to accept $ionicModal options as an argument - I just didn't have the need for it.
BTW - I'm using the Webpack babel-loader for transpilation and the html-loader to load the templates. But, in it's simplest form, it's just a basic service.
/**
* nvModals
* #description A modal manager. Attaches a specified controller to an $ionicModal instance.
*/
import myModalTemplate from '../common/modals/my-modal.html';
import otherModalTemplate from '../common/modals/other-modal.html';
let nvModals = function (
$rootScope,
$controller,
$ionicModal
) {
var _self = this;
_self.methods = {
/**
* Instantiate and show a modal
*/
showMyModal: (parentScope) => {
var parentScope = parentScope || null;
_self.methods.instantiateModal('MyModalController', myModalTemplate, parentScope)
.show();
},
/**
* Instantiate and show another modal
*/
showOtherModal: (parentScope) => {
var parentScope = parentScope || null;
_self.methods.instantiateModal('OtherModalController', otherModalTemplate, parentScope)
.show();
},
/**
* Instantiate a new modal instance
*
* #param {object} controller Controller for your modal
* #param {string} template Template string
* #param {object} parentScope Optional parent scope for the modal scope
* #return {object} Modal instance
*/
instantiateModal: (controller, template, parentScope) => {
var modalScope;
if(parentScope) {
modalScope = $rootScope.$new(false, parentScope);
} else {
modalScope = $rootScope.$new(false);
}
$controller(controller, {
'$scope': modalScope
});
modalScope.modal = $ionicModal.fromTemplate(template, {
scope: modalScope,
animation: 'slide-in-up'
});
modalScope.$on('modal.hidden', (evt) => {
evt.targetScope.$destroy();
if (evt.targetScope.modal) {
evt.targetScope.modal.remove();
}
});
modalScope.hideModal = function () {
modalScope.modal.hide();
};
return modalScope.modal;
}
};
return _self.methods;
};
nvModals.$inject = [
'$rootScope',
'$controller',
'$ionicModal'
];
export default nvModals;
In your controller...
$scope.modals = nvModals;
In the associated template
ng-click="modals.showMyModal()"
In the modal template
ng-click="hideModal()"
Ok, I have seen a lot of different solutions to better handling Ionic modals because of the lack of a controller option or something similar.
After playing with React for a while I came up with another option, more declarative in my opinion. Is in ES6 and just a prototype but you can have an idea:
(function() {
'use strict';
#Inject('$scope', '$ionicModal', '$transclude', '$rootScope')
class Modal {
constructor() {
let { animation, focusFirstInput, backdropClickToClose, hardwareBackButtonClose } = this;
$transclude((clone, scope) => {
let modal = this.createModalAndAppendClone({
scope,
animation,
focusFirstInput,
backdropClickToClose,
hardwareBackButtonClose
}, clone);
this.setupScopeListeners(modal.scope);
this.createIsOpenWatcher();
this.addOnDestroyListener();
this.emitOnSetupEvent(modal.scope);
});
}
setupScopeListeners(scope) {
scope.$on('modal.shown', this.onShown);
scope.$on('modal.hidden', this.onHidden);
scope.$on('modal.removed', this.onRemoved);
}
addOnDestroyListener() {
this.$scope.$on('$destroy', () => {
this.removeModal();
});
}
createIsOpenWatcher() {
this.isOpenWatcher = this.$scope.$watch(() => this.isOpen, () => {
if (this.isOpen) {
this.modal.show();
} else {
this.modal.hide();
}
});
}
emitOnSetupEvent(scope) {
this.onSetup({
$scope: scope,
$removeModal: this.removeModal.bind(this)
});
}
createModalAndAppendClone({
scope = this.$rootScope.$new(true),
animation = 'slide-in-up',
focusFirstInput = false,
backdropClickToClose = true,
hardwareBackButtonClose = true
}, clone) {
let options = {
scope,
animation,
focusFirstInput,
backdropClickToClose,
hardwareBackButtonClose
}
this.modal = this.$ionicModal.fromTemplate('<ion-modal-view></ion-modal-view>', options);
let $modalEl = angular.element(this.modal.modalEl);
$modalEl.append(clone);
return this.modal;
}
removeModal() {
this.modal.remove();
this.isOpenWatcher();
}
}
function modal() {
return {
restrict: 'E',
transclude: true,
scope: {
'onShown': '&',
'onHidden': '&',
'onRemoved': '&',
'onSetup': '&',
'isOpen': '=',
'animation': '#',
'focusFirstInput': '=',
'backdropClickToClose': '=',
'hardwareBackButtonClose': '='
},
controller: Modal,
bindToController: true,
controllerAs: 'vm'
}
}
angular
.module('flight')
.directive('modal', modal);
})();
And then you can use it like this:
<modal is-open="vm.isOpen" on-shown="vm.onShown()" on-hidden="vm.onHidden()" on-removed="vm.onRemoved()" on-setup="vm.onSetup($scope, $removeModal)">
<div class="bar bar-header bar-clear">
<div class="button-header">
<button class="button button-positive button-clear button-icon ion-close-round button-header icon" ng-click="vm.closeModal()"></button>
</div>
</div>
<ion-content class="has-header">
<create-flight-form on-submit="vm.submit()"></create-flight-form>
</ion-content>
</modal>
You open and close the modal with a boolean value bind to is-open and then register callbacks for the different events.