SAPUI5 this.getView in attachRequestCompleted - sapui5

I am loading data to my model and have a attachRequestCompleted attached. In there I want to set a value to one field, but it returns this.getView is not a function. This whole thing is inside a an interval:
My code looks like this:
var intervalId = setInterval(this.readRfid.bind(this), 3000);
readRfid: function() {
var oRfidModel = new sap.ui.model.xml.XMLModel();
oRfidModel.loadData("http://localhost/xxxxxxx");
oRfidModel.attachRequestCompleted(function() {
var reader = oRfidModel.oData.children["0"].children["0"].innerHTML;
this.getView().byId("objHdr_det_id1").setNumberUnit(reader);
});
Can I not use this.getView in the function? How can I make it work?
Thanks,
Tim

The this instance is not pointing to the Controller.
You probably need to bind a context to the callback function you've passed to the attachRequestCompleted.
As you can see here you can pass an oListener to this method.
I guess that something like:
var oRfidModel = new sap.ui.model.xml.XMLModel();
oRfidModel.loadData("http://localhost/xxxxxxx");
oRfidModel.attachRequestCompleted(function() {
var reader = oRfidModel.oData.children["0"].children["0"].innerHTML;
this.getView().byId("objHdr_det_id1").setNumberUnit(reader);
}, this);
Would work.
If this does not help you you can bind a context to the callback.

Related

sapui5 how can i get selected item from value help into table cell?

I have a table.a column consists of input fields. How can I get value from searchHelpDialog to table item?
Below is a sample table:
And the value help dialog:
You can add the id of the field as custom data to your value help dialog.
You can get the id from the oEvent.
openValueHelpDialog: function(oEvent) {
var oDialog = sap.ui.xmlfragment();
var oField = new sap.ui.core.CustomData();
oField.setKey("field");
oField.setValue(oEvent.getParameter("id"));
oDialog.addCustomData(oField);
oDialog.open();
}`
In the handleConfirm function you can then set value into the field with the id from the custom data:
handleConfirm: function(oEvent) {
var sFieldId = oEvent.getSource().data("field");
var oField = this.getView().byId(sFieldId);
var sSelectedValue = oEvent.getParameter("selectedItem");
oField.setValue(sSelectedValue);
}
you could use a datamodel, in which the value is written when selected.
this would need to happen in the controller of the fragment you use to build the searchHelpDialog.
also the model needs to be generated, since the rows of your list probably aren't static.
Thanks friends.
Problem solved.Code;
_handleValueHelp: function(oEvent) {
this.selectedValueHelp = oEvent.getSource();
}
_handleValueHelpClose: function(oEvent) {
var oSelectedItem = oEvent.getParameter("selectedItem");
if (oSelectedItem) {
this.selectedValueHelp.setValue(oSelectedItem.getTitle());
var productInput = this.getView().byId("helpvalue");
productInput.setValue(oSelectedItem.getTitle());
}
}

How can we pass multiple filters to OData read

I have come across with situation where more than 10 input values has to be passed to back end as filters. Is there any other option to create and pass filters instead of creating it in controller for each input filed?
If you want to have more sophisticated way of controlling the filter stuff declaratively via the XML view, for example, you can go with the following approach:
Assign to all the affected inputs a "customData" property, defining the "filterProperty" and "filterOperation"
Assign to all affected inputs the same "fieldGroupId"
On the filter button trigger, grab all the input via the "getControlsByFieldGroupId" method and construct the filters using the custom data form each input via the "data" function call
for using custom data include the namespace to the view:
xmlns:data="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"
customData doc
in XML:
<Input fieldGroupIds="InputGroup" data:filterName="Id" data:filterOperation="EQ" />
<Input fieldGroupIds="InputGroup" data:filterName="Name" data:filterOperation="Constains" />
<Input fieldGroupIds="InputGroup" data:filterName="Color" data:filterOperation="LT" />
in JS:
var aInputs = oView.getControlsByFieldGroupId("InputGroup");
var aFilters = aInputs.map(function(oInput) {
var sFilterName = oInput.data("filterName");
var sFilterOperation = oInput.data("filterOperation");
return new Filter(sFilterName, sFilterOperation, oInput.getValue());
});
See example
You can create filter for every input and push it to the array of filters which you will use as you need.
E.g.:
var oFilter1 = new sap.ui.model.Filter("Input1", sap.ui.model.FilterOperator.Contains, value1);
var oFilter2 = new sap.ui.model.Filter("Input2", sap.ui.model.FilterOperator.Contains, value2);
var oFilter3 = new sap.ui.model.Filter("Input3", sap.ui.model.FilterOperator.Contains, value3);
var oFilter4 = new sap.ui.model.Filter("Input4", sap.ui.model.FilterOperator.Contains, value4);
var allFilters = new sap.ui.model.Filter([oFilter1, oFilter2, oFilter3, oFilter4], false);
For more info look here.
//Create an array
var aFilters = [];
if (yourVal1) {
aFilters.push(new sap.ui.model.Filter("Dimension", sap.ui.model.FilterOperator.EQ, yourVal1));
}
if (yourVal2) {
aFilters.push(new sap.ui.model.Filter("Language", sap.ui.model.FilterOperator.EQ, yourVal1));
}
this.getModel().read("/YourEntitySet", {
filters: aFilters,
success: function(oData) {
// use the response as required.
},
error: function() {
}
});

Cannot call method 'id' of undefined

My world.js looks like this:
var protractor = require('protractor');
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().usingServer('xxxxx').
withCapabilities(webdriver.Capabilities.firefox()).build();
driver.manage().timeouts().setScriptTimeout(100000);
module.exports.World = function World(callback) {
this.browser = protractor.wrapDriver(driver);
this.by = protractor.by;
callback();
};
then in steps.js:
{
element(by.id('username')).sendKeys("admin");
}
When I ran it using cucumber.js, the error is:
TypeError: Cannot call method 'id' of undefined
but if I remove world.js and run it using protractor, it works.
How can I fix this?
It looks like you're not exporting by globally. I'm not sure why you're able to use the element function at all - but in any case, you should probably be doing something like:
module.exports.World = function World(callback) {
global.browser = protractor.wrapDriver(driver);
global.by = protractor.by;
};

jQuery: how can i pass parameters to event listeners' callback?

function myClass(myobject){
var myclass = {};
myclass.registerEvent = function(){
$('#'+myobject.id).live('someEventThatTriggersRightAway', runMe);
};
runMe = function(){
$('#'+myobject.id).die('someEventThatTriggersRightAway', runMe);
console.log("Hello "+myobject.name);
};
return myclass;
}
var instance1 = new myClass({id:'button1',name:'MATO'});
var instance2 = new myClass({id:'button2',name:'YAMA'});
when i run this code
instance1.registerEvent();
the result is
Hello YAMA
it is as if the first instance had been overwritten by the 2nd one. I can solve this if only i can pass the 'myobject' in the event's callback, but i dont know how to do it. and also i cant kill it if it has parameters. how can i do this?
Thank you!
You have missed the var from runMe, so runMe is leaking to the global execution context. Therefore, each time you call myClass, the reference to myobject in runMe is going to change.
var runMe = function(){
$('#'+myobject.id).die('someEventThatTriggersRightAway', runMe);
console.log("Hello "+myobject.name);
};
Here's a working example.
Side note: are you aware that the jQuery .live() and .die() methods are deprecated? You should be using .on() (jQuery 1.7+) or .delegate() instead.
The answer below is purely theoretical, since .live() and .die() are deprecated, and therefore should not be used anymore. To get your code up to date, substitue the .live()/.die() calls given below with the following:
// for .live()
$(document).on('click', '#'+myobject.id, myobject, runMe);
// for .die()
$(document).off('click', '#'+e.data.id, runMe);
Here, you can and should replace document with the nearest static parent element of the buttons. New code demo
According to the documentation, data is an optional second parameter to the .live() method, which you access through the event object. Use as follows:
function myClass(myobject){
var myclass = {};
myclass.registerEvent = function(){
$('#'+myobject.id).live('click', myobject, runMe);
};
var runMe = function(e){
$('#'+e.data.id).die('click', runMe);
console.log("Hello "+e.data.name);
};
return myclass;
}
var instance1 = new myClass({id:'button1',name:'MATO'});
var instance2 = new myClass({id:'button2',name:'YAMA'});
instance1.registerEvent();
instance2.registerEvent();
Old code working demo

Using DynamicActivityProperty as OutArgument in ActivityBuilder

Greetings,
I'm trying to create a workflow using a ActivityBuilder, and then get the XAML.
This flow use a custom activity (WaitForInput) to handle bookmarks. This class inherits from NativeActivity.
I'm having a hard time finding a way to set 'Result' property of my WaitForInput activity, which expects a OutArgument.
Creating this same workflow by the VS designer, I could associate the boolean property 'MyResult' InOutArgument called 'wrapper'. Like this : [Wrapper.MyResult]
I would do this by code, and according to my research, I have to use DynamicActivityProperty.
The problem is that I don't know how to use my DynamicActivityProperty as OutArgument in this case.
This is an simplified version of the code:
var wrapper = new DynamicActivityProperty
{
Name = "Wrapper",
Type = typeof(InOutArgument<CommunicationWrapper>),
};
var activityBuilder = new ActivityBuilder();
activityBuilder.Properties.Add(wrapper);
var step1 = new FlowStep
{
//here's my problem
Action = new WaitForInput<bool> { BookmarkName = "step1", Result = ??? }
};
var flow = new Flowchart
{
StartNode = step1,
Nodes = { step1 }
};
I have founded a solution to my own problem
Result = new OutArgument<bool>(new VisualBasicReference<bool>
{ ExpressionText = "Wrapper.MyResult" }); }