SAPUI5 - extend a sap.ui.controller implementation - sapui5

I would like to implement a new controller that would redefine some methods from an existing controller.
Let say I have:
MyForm.controller.js
sap.ui.controller("MyForm", {
showMyName: function() {
alert("MyForm.showMyName");
},
onSearch: function(oEvent) {
// Do something...
},
});
I would like a new MyNewForm controller that would override the method showMyName but would inherit the onSearch method.
Any ideas how this could achieved?
Thanks in advance.

it works like this:
code of the base controller:
sap.ui.core.mvc.Controller.extend("MyForm", {
showMyName: function() {
alert("MyForm.showMyName");
},
//Further functions ....
});
code of the MyNewForm controller using the MyForm as base:
//require the base first
jQuery.sap.require("MyForm");
//extent the base
MyNewForm.extend("MyForm", {
onInit : function() {
this.showMyName(); //alerts
}
})
In this demoapp you see it in action:
https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/m/demokit/tdg/index.html?responderOn=true
look for util/Controller.js as base class
and for view/Master.Controller.js as usage of the class.
Best Regards

I think it should be:
MyForm.extend("MyNewForm", {

By calling method sap.ui.controller("MyForm", {}),
the "MyForm" controller is not defined and is never available in execution scope.
Where
sap.ui.core.mvc.Controller.extend("MyForm", {}) defines function and referred by "MyForm", and has extend defined on it.

Related

What is the replacement of create() in tinymce 6?

create() function is used to add a class, subclass or static singleton.
Example :
tinymce.create('tinymce.somepackage.SomeClass', {
SomeClass: function() {
// Class constructor
},
method: function() {
// Some method
}
});
I have used this function to add custom utility functions on my tinymce object, but this is being removed in tinymce 6. I am planning to upgrade to latest version but I am not finding any alternative method to register my functions on tinymce object.

XML View Event Handler Helper

I am trying to use a helper class to invoke a method in xml view as detailed in documentation
https://sapui5.hana.ondemand.com/#/topic/b0fb4de7364f4bcbb053a99aa645affe
<Button text="Press Me" press="ZUI5.ZTESTAPP.TestClass.handlePress.call($controller, 'Hello World')"/>
However the object does not get resolved in jQuery.sap.getObject (returns undefined).
Here is the helper class code
sap.ui.define(["sap/ui/base/Object"],
function (Object) {
"use strict";
var o = Object.extend("ZUI5.ZTESTAPP.TestClass", {
constructor: function(){
},
initalize: function(oView){
this._view = oView;
},
handlePress: function(oEvent){
debugger;
//alert('Message Set');
}
});
return o;
});
This feature is not available in version 1.44.x
Based on the documentation it seems to be introduced in version 1.56 only.
Compare the following documentations
1.56.x - Handling Events in XML Views
1.54.x - Handling Events in XML Views

BusyIndicator for navigating between pages

I am quite new to SAPUI5 and still learning a lot.
Actually I am trying to set up a busydialog while navigating between two different views.
I already defined the busydialog and set it up on a press-Event after one hits the navigation button. The dialog is showing up, but Iam not really sure about the handling regarding the close event. I thought that onMatchedRoute could help me, but the dialog is not closing. My controller for the first page looks like:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/format/NumberFormat",
"sap/m/BusyDialog"
], function(Controller, NumberFormat) {
"use strict";
var BusyDialogGlobal;
return Controller.extend("sap.turbo.ma.mc.controller.region.americas.AmFinance", {
onInit: function() {
BusyDialogGlobal = new sap.m.BusyDialog("GlobalBusyDialog",{title:"Please wait. . . "});
onHomePress: function() {
var oRouter = this.getOwnerComponent().getRouter();
oRouter.navTo("home");
var getDialog = sap.ui.getCore().byId("GlobalBusyDialog");
getDialog.open();
This part is working. I am not sure about further process handling part to close the busydialog after the second page/view is loaded. Maybe someone has a small snippet or example that could help me out here?
You are not defining your 'BusyDialogGlobal' in a global scope. It is defined in the controller scope for this view. Therefore in your second view probably you cant access it.
Two approaches you can do here (in the order I think are better):
Option 1
Build all your controllers extending a custom 'Base Controller', this way you will have access to its functions from all the children controllers. To do so, create a normal controller, extending from sap/ui/core/mvc/Controller as you have done. Call it 'BaseController' for example and save it in your controllers folder. Then create all your view controllers extending from the BaseController. Something like this:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("mynamespace.controller.BaseController", {
onInit: function(){
this.BusyDialogGlobal = new sap.m.BusyDialog("GlobalBusyDialog",{title:"Please wait. . . "});
},
presentBusyDialog(){
this.BusyDialogGlobal.open()
}
dismissBusyDialog(){
this.BusyDialogGlobal.close()
}
}
});
Then in your view1.controller.js:
sap.ui.define([
"mynamespace/controller/BaseController"
], function (BaseController) {
"use strict";
return BaseController.extend("mynamespace.controller.View1", {
onNavigate: function(){
//Do your navigation logic here
//...
this.presentBusyDialog();
}
}
});
And in your View2.controller.js
sap.ui.define([
"mynamespace/controller/BaseController"
], function (BaseController) {
"use strict";
return BaseController.extend("mynamespace.controller.View2", {
onInit: function(){
this.dismissBusyDialog();
}
}
});
Option 2
Easier but less elegant, just instantiate the busyDialog in your Component scope and retrieve it from that scope when needed.
To instantiate it from a view controller:
this.getOwnerComponent().BusyDialogGlobal = new sap.m.BusyDialog("GlobalBusyDialog",{title:"Please wait. . . "});
To open it from whatever view controller when needed:
this.getOwnerComponent().BusyDialogGlobal.open()
To close it from whatever view controller when needed:
this.getOwnerComponent().BusyDialogGlobal.close()

Calling one controller's method in another controller?

I am totally confused with all the buzzwords you all are using modules, eventbus.
I will try to rephrase my question in more simple words because I am new to this framework and I like to understand it in simple way. So here is what I am trying to achieve:
I have a Questionnaire controller which is binded to Questionnaire view. Now I need to fetch some data from my backend with my xsjs and bind to this view. I need to fetch this data before the page renders so I am using my ajax call in Before Rendering and in the complete property of my ajax call I need to perform some vaildations. As my function in complete property is too long I was thinking of creating a separate controller and then defining my method which makes ajax call and necessary validations here. This new controller just holds this method definition hence it is not binded to any view.
Now How should I call this controller in the Questionnaire controller and use its method that makes the ajax call and performs the validations in controller method?
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox"], function(Controller, JSONModel, MessageBox) {
var questionnaireResponseId;
var password;
var backendJSON;
Controller.extend("OnlineQuestionnaire.controller.Questionnaire", {
onInit: function() {
jQuery.sap.require("jquery.sap.storage");
},
onBeforeRendering: function() {
questionnaireResponseId = jQuery.sap.storage.get("QuestionnaireResponseId");
password = jQuery.sap.storage.get("Password");
backendJSON = loadStack(questionnaireResponseId); //This is not correct way to call
}
This method is defined in QuestionStack.controller.js
loadStack(questionnaireResponseId) {
jQuery.ajax({
url: "",
method: "GET",
dataType: "json",
complete: this.onSuccess,
error: this.onErrorCall
});
return output;
}
extend your QuestionStack.controller.js with Questionnare.controller.js:
sap.ui.define([
".." // path to your QuestionStack.controller.js, e.g. "myapp/controller/QuestionStack"
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox"], function(Controller, JSONModel, MessageBox) {
var questionnaireResponseId;
var password;
var backendJSON;
QuestionStack.extend("OnlineQuestionnaire.controller.Questionnaire", { // extend
..
}
call the method with this.loadStack(..);

Select in ember not loading data - is there working example?

I'm new to Ember JS and I am trying to figure out how to create Ember.Select which would allow to create new job for user.
This is part of the code from my form.handlebars:
{{view Ember.Select viewName="job-user"
contentBinding="users"
optionLabelPath="content.name"
optionValuePath="content.id"
}}
I am inside JobsNewController:
JP.JobsNewController = Ember.ObjectController.extend({
needs: ['users'],
users: [],
usersBinding: "controllers.users"
});
This is how my UsersController looks like:
JP.UsersController = Ember.ArrayController.extend();
It's working when I go to newJob screen from screen where I have UserController populated, but when I go directly to jobs/new it fails to populate select with data. How can I force Ember to load data for this select?
EDIT:
I had to setup routes correctly:
JP.JobsNewRoute = Ember.Route.extend( JP.JobsFormable, {
model: function() {
return JP.Job.createRecord();
},
setupController:function(controller,model) {
this._super(controller,model);
controller.set('usersForSelect', JP.User.find());
}
});
And I have also modified form:
{{view Ember.Select viewName="job-user"
contentBinding="usersForSelect"
optionLabelPath="content.name"
optionValuePath="content.id"
}}
Thanks #mavilein for hint
When you access the JobsNewRoute from the URL, the UsersController is not populated. So binding users in JobsNewController to UsersController content would be useless since UsersController is empty and was not populated.
You can solve this in two ways, both are in the JobsNewRoute.
First way, update your JobsNewRoute to fill the UsersController:
JP.JobsNewRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor('users').set('content', JP.User.find());
}
});
Another way would be to remove the binding between JobsNewController.users and UsersController, and simply fill JobsNewController.users in the JobsNewRoute:
JP.JobsNewController = Ember.ObjectController.extend({
users: []
});
JP.JobsNewRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('users', JP.User.find());
}
});