SAPUI5 PlanningCalendar set startDate - sapui5

I'm not able to reset the PlanningCalendar back to the initial startDate.
So, after clicking on Today or the Navigate Back or Foreward arrows there is no way of getting back to the initial start date.
I'm not sure if I'm doing it right, but you can find a working example here
Here is the controller
sap.ui.define(
[
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel',
'sap/ui/model/resource/ResourceModel',
'sap/m/MessageToast'
],
function (Controller, JSONModel, ResourceModel, MessageToast) {
'use strict';
var PageController = Controller.extend('view.Main', {
onInit: function () {
var oModel = new JSONModel();
oModel.setData({...});
var oView = this.getView();
oView.setModel(oModel);
},
dateFormatter: function (sDate) {
return new Date(sDate);
},
resetStartDate: function () {
var oView = this.getView();
var oPlanningCalendar = oView.byId('PC1');
var startDate = oPlanningCalendar.getStartDate();
oPlanningCalendar.setStartDate(startDate);
MessageToast.show("'resetStartDate' event fired.");
},
handleStartDateChange: function (oEvent) {
var oView = this.getView();
var oPlanningCalendar = oView.byId('PC1');
var startDate = oPlanningCalendar.getStartDate();
MessageToast.show("'startDateChange' event fired.\n\nNew start date is " + startDate.toString());
}
});
return PageController;
}
);

the problem is the following two lines of code.
var startDate = oPlanningCalendar.getStartDate();
oPlanningCalendar.setStartDate(startDate);
You get the date from current Planning Calendar, and then set the date back to it.
That means you do nothing.
Maybe you need to get the start date on initial of Planning Calendar. Not at the time you want to do the reset.

Related

Suggestion popup doesnt appear for multi input control

I have dynamically attached live search event for my Multi Input control (please refer the below code). Even after attaching the .bindAggregation function for suggestionItems, the suggestion popup doesn't appear.
onAfterRendering: function(oEvent){
var that = this;
var oFacetFilters = sap.ui.getCore().byId
("xyzID").getContent()[0].getContent();
var oCapTreeFilter = oFacetFilters[6].getContent()[1];
oCapTreeFilter.attachLiveChange(function(oEvt){
//build filter array
var aFilter = [];
var sQuery = oEvt.getParameter("value");
if (sQuery) {
aFilter.push(new sap.ui.model.Filter("RootID",
sap.ui.model.FilterOperator.Contains, sQuery));
}
that.oModel.read("/RootName", {
async : false,
filters : aFilter,
success : function(oData, response){
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setData(oData);
oCapTreeFilter.setModel(oJSONModel);
oCapTreeFilter.bindAggregation("suggestionItems",{
path: "/results",
template: new sap.ui.core.Item({text: "{RootID}"})
});
},
error : function(response){
sap.m.MessageBox.show("Error occurred");
}
});
});

SAPUI5 SmartTable pressItem event is triggered twice

I have the issue that the pressItem event is triggered twice at smarttable ( sapui5).
The smarttable has type ResponsiveTable.
onAfterRendering : function(){
var tTable = this.byId("LineItemsSmartTable");
var oTable = this.byId("LineItemsSmartTable").getTable();
oTable.setMode(sap.m.ListMode.SingleSelectMaster);
oTable.onAfterRendering = function(){
this.attachItemPress(function(oEvent){ alert( "Pressed" ); });
};
// var fnItemPress = function(){ alert("press2") };
tTable.attachDataReceived(function(){
var aItems = oTable.getItems();
if(aItems.length === 0 ) return;
$.each(aItems, function(oIndex, oItem) {
//oItem.detachPress(fnItemPress);
oItem.setType("Active");
// oItem.attachPress(fnItemPress);
});
});
}
If onAfterRendering is not being called already onInit then reconsider renaming the function oTable.onAfterRendering.
onAfterRendering is already called in the controller lifecycle, you could try creating a new function and then calling that in onAfterRendering.
See this answer
onAfterRendering: function() {
this.tableItems();
},
tableItems: function() {
var tTable = this.byId("LineItemsSmartTable");
var oTable = this.byId("LineItemsSmartTable").getTable();
oTable.setMode(sap.m.ListMode.SingleSelectMaster);
oTable.attachItemPress(function(oEvent) {
alert("Pressed");
});
tTable.attachDataReceived(function() {
var aItems = oTable.getItems();
if (aItems.length === 0) return;
$.each(aItems, function(oIndex, oItem) {
oItem.setType("Active");
});
});
}

Unable to use page objects in my spec file in protractor

//This is my AngularPage.cs page object file
var AngularPage= function()
{
var nameInput= element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get=function()
{
browser.get('http://www.angularjs.org');
};
this.setName= function(name)
{
nameInput.sendKeys(name);
};
this.getGreeting= function()
{
return greeting.getText();`
};
};
module.exports = new AngularPage();
//This is my AngularHome_spec.js file
var angularPage = require('./AngularPage.js');
describe('angularjs homepage',function()
{
var angular_page;
beforeEach(function()
{
angular_page= new AngularPage();
});
it('greetings for new user', function()
{
// var angular_page= new AngularPage();
angular_page.get();
angular_page.setName('Rahul');
expect(angular_page.getGreeting()).toEqual('Hello Rahul!');
}
);
}
);
//I am unable to use page objects in my spec file as it is throwing an error
:AngularPage is not defined
In your code, object has been created twice. First time on page "AngularPage.js" and second time on spec "AngularHome_spec.js" level.
Do following on page "AngularHome_spec.js"
module.exports = AngularPage;
Change the
var AngularPage = require('./AngularPage.js');//Capital the 'A'

Use Protractor browser.driver as a variable

I'm using page object model and I'm stuck at how to put the browser.driver elements as a variable.
Here is an example of using it with Protractor's element:
var Messages = function() {};
var messagesLink = element(by.css('a[href*="/Messages"]'));
Messages.prototype.visitPage = function() {
messagesLink.click();
};
exports.Messages = new Messages();
Then I can use Messages.visitPage(); throughout my test. The problem is when I try to do the same thing with browser.driver:
var Login = function() {};
var usernameField = browser.driver.findElement(by.id('UserName'));
var passwordField = browser.driver.findElement(by.id('Password'));
var signOnButton = browser.driver.findElement(by.css('input[value="Sign On"]'));
var registeredUserName = 'user';
var registeredUserPass = 'pass';
Login.prototype.loginAsRegisteredUser = function() {
loginAs(registeredUserName, registeredUserPass);
};
var loginAs = function(userName, pass) {
usernameField.sendKeys(userName);
passwordField.sendKeys(pass);
signOnButton.click();
};
exports.Login = new Login();
The test instantly fails before even starting, throwing this error NoSuchElementError: Unable to locate element: *[id="UserName"]. The reason why I'm using browser.driver is because I'm accessing elements on a non-angular page. I want to try and keep angular and non-angular references separate from each other.
I'm not sure how Protractor handles this but in Selenium I can use the variable like so, static By cancelButton = By.id("cphMain_btnCancel");.
So, is there anyway that this can be done using Protractor?
Spec File:
var home = require('../../pages/home/Home.js').Home;
var headerHome = require('../../pages/home/HeaderHome.js').HeaderHome;
var login = require('../../pages/Login.js').Login;
describe('Registered User | DEV_Smoke |--- Home page: ', function() {
it('Navigates to the Home page', function() {
home.visitPage();
});
it('Prints the current URL (see build.log)', function() {
home.verifyHomeUrl();
});
it('Clicks Sign On link and signs in as a registered user', function() {
headerHome.clickSignOnLink();
login.loginAsRegisteredUser();
});
});
Easiest way would be to just wrap the findElement in functions and call them as needed
var Login = function() {};
var usernameField = function() {
return browser.driver.findElement(by.id('UserName')); //returns promise
}
var passwordField = function() {
return browser.driver.findElement(by.id('Password'));
}
var signOnButton = function() {
return browser.driver.findElement(by.css('input[value="Sign On"]'));
}
var registeredUserName = 'user';
var registeredUserPass = 'pass';
Login.prototype.loginAsRegisteredUser = function() {
loginAs(registeredUserName, registeredUserPass);
};
var loginAs = function(userName, pass) {
usernameField().sendKeys(userName);
passwordField().sendKeys(pass);
signOnButton().click();
};
exports.Login = new Login();
browser.driver is of type Webdriver and when calling findElement, selenium-webdriver will try to evaluate wherever it is stated in your code. So prior to your login method and possibly navigation to the login page, you are automatically looking for the WebElements for UserName, Password, and input[value="SignOn"].
In your code snippet, it looks like you should use element. When using element, at runtime, the findElement will be evaluated. This allows for more reusable code.
For non-angular pages, you might have to provide your own syncing or some arbitrary sleep. This usually occurs with animations, long load screens, etc.
Also make sure you return your promises so the jasmine wrapper evaluates your function properly.
var usernameField = element(by.id('UserName'));
var passwordField = element(by.id('Password'));
var signOnButton = element(by.css('input[value="Sign On"]'));
// make sure you return your promises so the jasmine wrapper
// evaluates your function properly.
var loginAs = function(userName, pass) {
return usernameField.sendKeys(userName).then(() => {
return passwordField.sendKeys(pass).then(() => {
return signOnButton.click();
});
});
};

How to change model data of a view from another view?

viewtest is bound to a JSONModel. View2 is bound to the same JSONModel by creating a reference to viewtest and setting the model to viewtest.getModel().
What I'm trying to do is modify the shared model data in View3 by clicking a button so that the texts in textfield and textview will change automatically. However, the texts in textfield and textview remain "This is a text". What's the problem?
The index.html file:
and the viewtest.view.js file:
sap.ui.jsview("viewtest.viewtest", {
getControllerName : function() {
return "viewtest.viewtest";
},
createContent : function(oController) {
this.setModel(new sap.ui.model.json.JSONModel());
var oData = {
text: "this is a text"
};
this.getModel().setData(oData);
var oTextField = new sap.ui.commons.TextField({value: "{/text}"});
return [oTextField];
}
});
View2.view.js file:
sap.ui.jsview("viewtest.View2", {
getControllerName : function() {
return "viewtest.View2";
},
createContent : function(oController) {
var viewtest = sap.ui.view({viewName: "viewtest.viewtest", type:sap.ui.core.mvc.ViewType.JS});
this.setModel(viewtest.getModel());
this.getModel().setData(viewtest.getModel().getData());
var oTextView = new sap.ui.commons.TextView({text: "{/text}"});
return [oTextView];
}
});
View3.view.js file:
sap.ui.jsview("viewtest.View3", {
getControllerName : function() {
return "viewtest.View3";
},
createContent : function(oController) {
var oButton = new sap.ui.commons.Button({text:"click", press: func});
function func() {
var oView = new sap.ui.view({viewName:"viewtest.viewtest", type:sap.ui.core.mvc.ViewType.JS});
oView.getModel().setData({text:"hello world"}, true);
}
return [oButton];
}
});
Just a suggestion. Maybe it is worth to give in your .html file id to every view, and then in view3 update and set model to each one of the views by calling them by id?
Like,
in index.html:
var view1 = new sap.ui.view({id:"view1", viewName:"viewtest.View1", type:sap.ui.core.mvc.ViewType.JS});
and then in view3:
function func() {
var oView = sap.ui.getCore().byId("view1");
oView.getModel().setData({text:"hello world"}, true);
oView.getModel().refresh(); //if setting new model won't update the views
}
Or, if you use the same model in all your views, set model not to each view separately, but to the core:
viewtest.view.js file:
sap.ui.getCore().setModel(new sap.ui.model.json.JSONModel());
thus, you don't need to set model in view2.