Mapping few columns in sap.ui.table.Table using ODataModel? - odata

I am binding all the columns of a table except one which is drop down. The table is tied to a model(ODataModel) and the contents of the drop downs in the last columns are all the coming from different model because user shall be selecting one item from the drop down later which is submitted on the click of a button 'Save' I have provided in the bottom.
I am making use of Paginator as Navigation mode. The problem is dropdown shows the contents of first page when user switches between the pages which is eventual as it is not tied to any of the fields in the model of the table. I want to show the respective changes to be reflected in the column of drop down though user switches between the pages.
Any suggestion over this? I know there is something called RowRepeater using which complex controls can be repeated but still what would be the way if I want to make use of sap.ui.table.Table?
Please find my code below:
createAssignResourcesTable: function(){
var model = new sap.ui.model.odata.ODataModel("/sap/opu/odata/sap/ZSECENTRAL_SRV", true);
var substituteRMCombo = sap.ui.getCore().byId("substituteRM");
var selectedRM = substituteRMCombo.getSelectedKey();
var jsonModel = new sap.ui.model.json.JSONModel();
var resourceData = null;
var readSuccess = function(responseData){
resourceData = responseData;
jsonModel.setData(resourceData);
};
var readError = function(){
//console.log('some error occurred while reading data');
sap.ui.commons.MessageBox.show("Some Error occurred while reading data",
sap.ui.commons.MessageBox.Icon.ERROR,"Error!",[sap.ui.commons.MessageBox.Action.OK],
function(){
//console.log('End Date should be grater than Start aDte!!!');
return;
});
};
model.read("/RMResourceSet",null, null, true,readSuccess,readError);
var template = new sap.ui.core.ListItem();
//console.log(template);
template.bindProperty("text","ChildbpName");
template.bindProperty("key","Childbp");
//console.log(template);
var that = this;
var table = new sap.ui.table.Table("assignResourcesTable",{
visibleRowCount: 6,
navigationMode: sap.ui.table.NavigationMode.Paginator,
columns:[
new sap.ui.table.Column("",{
label: new sap.ui.commons.Label({text:"Work Item"}),
template: new sap.ui.commons.Label().bindProperty("text", "DemoId"),
sortProperty: "DemoId",
filterProperty: "DemoId",
width: "auto"
}), new sap.ui.table.Column("",{
label: new sap.ui.commons.Label({text:"Requierd Date"}),
template: new sap.ui.commons.TextView().bindProperty("text", "ReqDate"),
sortProperty: "ReqDate",
filterProperty: "ReqDate",
width: "auto"
}),
new sap.ui.table.Column({
label: new sap.ui.commons.Label("",{
text: "Estimated Hours"
}),
template: new sap.ui.commons.TextField("",{
change:[{"name" : "DurEst"},that.onChangeAssignResourcesTable,that],
value: "00015"
}).bindProperty("value","DurEst")
}),
new sap.ui.table.Column({
label: new sap.ui.commons.Label({text:"Demo Engineer"}),
template: new sap.ui.commons.ComboBox("",{
change:[{"name" : "Childbp"},that.onChangeAssignResourcesTable,that]
}).setModel(jsonModel).bindItems("/results",template),
width: "auto"
})
]
});
table.setBusyIndicatorDelay(1);
var oModel = new sap.ui.model.odata.ODataModel("/sap/opu/odata/sap/ZSECENTRAL_SRV",true);
oModel.attachRequestSent(function (oEvent) {
//console.log('request sent');
table.setBusy(true);
});
oModel.attachRequestCompleted(function () {
//console.log('request completed');
table.setBusy(false);
});
oModel.attachRequestFailed(function () {
table.setBusy(false);
});
table.setModel(oModel);
var FilterOperator = sap.ui.model.FilterOperator;
var filter = new sap.ui.model.Filter("RmUser", FilterOperator.EQ, selectedRM);
table.bindRows("/RMNONSTAFFEDDBRSet",null,null,[filter]);
//table.bindRows("/RMNONSTAFFEDDBRSet",true);
return table;
}
Thanks in Advance!

Your ComboBox statically binds against jsonModel>results. Given the above code I would assume your ComboBox turns out to always contain the very same items.
I understood from your question that these items should be dynamic for each row or at least each page. Since the rows of a table can only be bound to one collection you have the following possibilities to tweak this:
Create a new JSONModel joining the data from your ODataModel with the data used for the ComboBox creation and bind your table against this new model.
Option 1 certainly has some weaknesses so here's another one: Bind your ComboBox column against any property of the ODataModel and use a formatter function to dynamically create the ComboBox items and return them from the formatter.

Related

Bind Element to controls SAPUI5

I'm trying to show some data retrieved by Odata Model on a XML View.
In Component.js, I create a model with service Url and it works as usual.
var oDataModel = new sap.ui.model.odata.v2.ODataModel("http://server:port/sap/opu/odata/SAP/ZWYMB_SRV", {
user:"abapleader",
password: "TH123456789a#",
headers: {
"sap-client": 300
},
useBatch:false
});
this.setModel(oDataModel, "oDataModel");
So far, I've managed to get data to master using model.read() function.
Now I need to show the detail view. My code for onInit event is below:
this.router.getRoute("zwm01detail").attachPatternMatched(this._onObjectMatched.bind(this));
},
_onObjectMatched: function(oEvent) {
var that = this;
var MaWorkDoc = oEvent.getParameter("arguments").MaWorkDoc;
this.getModel("oDataModel").metadataLoaded().then(function() {
var sPath = that.getModel("oDataModel").createKey("/WorkDocList", {
MaWorkDoc: MaWorkDoc,
Pernr: "0001"
});
console.log(sPath);
that.getView().bindElement({
path:sPath
});
});
The sPath as I printed out using console.log(sPath) : /WorkDocList(MaWorkDoc='1110000001',Pernr='0001'), which I think, is correct. I also implemented and tested the back-end using this path and basically things are fine. But I don't know why I cannot show data on the view.
Detail.view.xml:
<Text text="{/MaWorkDoc}" maxLines="0"/>
Any suggestions, please?
Because you have given your model a name you will need to use that name in the binding. i.e. <Text text="{oDataModel>/MaWorkDoc}" maxLines="0"/>
So I've been working around with the docs and figure out there is model parameter which helps.
To be more specific, I add declare model in view.bindElement as below:
that.getView().bindElement({
path:sPath,
//** oDataModel = name of the model
model: "oDataModel"
});
If there is any better solution, I'd very glad to know it. Thank you.!
I do not think the detail binding code should be inside the .metadataLoaded handler. Rather it should be directly inside _onObjectMatched.
I mean like this.
_onObjectMatched: function(oEvent) {
var that = this;
var MaWorkDoc = oEvent.getParameter("arguments").MaWorkDoc;
var sPath = that.getModel("oDataModel").createKey("/WorkDocList", {
MaWorkDoc: MaWorkDoc,
Pernr: "0001"
});
console.log(sPath);
that.getView().bindElement({
path:sPath
});
}

Updating list in view Asp.net mvc razor

I have 2 lists in a view. What I want to do is that pick elements from list1 and update list2 with selected elements everytime I pick one. I tried to use PartialView (I don't know if it's correct approach or not) but I failed. I have a function in controller that fills a list by selected items. What needs to be done is updating the view dynamically. Can you suggest me a roadmap for this?
Update
I forgot to say that I have done this with javascript. But I feel like it's the long way when it comes to some validations (checking duplications etc.)
$(document).ready(function (){
$("#allPlayersList a").on("click", function () {
var options = $(this).clone();
$("#thisWeekList").append(options);
});
});
Just create an html list. See if this link helps. https://codepen.io/alexander-holman/pen/QNQrvz. You can also populate the values from database
Then you can get the selected element by javascript like this
var input = document.getElementById('Something').value;
Update after edited question
You can try something like
var listSelection = document.getElementById('Something').value;
Now you can create an api in the backend which accepts this value and returns a list based on it. Call that Api like this
&.ajax({
url: //url of api
data: {exactNameOfApiParameter : listSelection },
success: function(data){
for (i = 0; i < data.length; i++) {
$('<li>', { text: data[i] }).appendTo($('#list2'));
}
}
})
Make sure that id of second list is list2.

OData Model not refreshing

I'm reading some OData on route matched.
This works fine fist time in, or when refreshed, but when I route to it from another view, the data has not update until I refresh the page again.
_onRouteMatched: function (oEvent) {
//initialise display
var view = this.getView();
view.setBusy(true);
var oModel = this.getModel("outstanding");
this.getModel().read("/CalendarSet", {
filters: [
new Filter("CategoryId", FilterOperator.EQ, "S"),
new Filter("ApprovalId", FilterOperator.EQ, "0"),
new Filter("EndDate", FilterOperator.EQ, "9999.12.31"),
new Filter("DayOfWeek", FilterOperator.EQ, "0"),
new Filter("SequenceNumber", FilterOperator.EQ, "00"),
],
success: function (oData) {
console.log(oData);
}
});
}
As your view or control is not binded to model, it will not auto update the UI.
Bind model on view or control and refresh the model, when you are routing, to get updated data.This will update the bindings of corresponding controls.
_onRouteMatched: function(){
oModel.refresh();
}
As your view or control is not binded to model, it will not auto update the UI. Bind model on view or control and refresh the model
oModel.refresh(true);

how to create dynamic url in collection and model using backbone

My collection and model like this:
detail_userid = 0;
detail_contactid = 0;
var ContactDetail = Backbone.Model.extend({
urlRoot: URL_CONTACTS1+detail_userid+"/"+detail_contactid
});
var ContactDetailCollection = Backbone.Collection.extend({
model: ContactDetail,
url: URL_CONTACTS1+detail_userid+"/"+detail_contactid
})
The entrance is:
ContactDetailManagePageModel.prototype.init = function(m,n){
detail_userid = m;
detail_contactid = n;
var myContactDetails = new ContactDetailCollection();
var contactDetailListView = new ContactDetailListView({
collection: myContactDetails
});
myContactDetails.fetch({reset:true});
}
But when it runs,the url is :http://localhost:8080/ws/users/contacts/0/0,it means that the assignment to detail_userid and detail_contactid is unsuccessful,I don't know why.
Hope for your help.Thanks.
I think you are statically definining the urlRoot and url properties before you are running the init of the PageModel (not quite sure where you are getting m and n from though...)
Both url and urlRoot can be a function, so you can pass in options during instantiation and have them dynamically set on the model.
Simple example covering defining the collection and then creating one
var ContactDetailCollection = Backbone.Collection.extend({
model: ContactDetail,
url: function(){
return URL_CONTACTS1 + this.options.detail_userid + "/" + this.options.detail_contactid;
}
});
var myContactDetails = new ContactDetailCollection({
detail_userid: foo,
detail_contactid: bar
});
As I mentioned, I'm not sure what your init function is doing, I'm guessing it's something custom from your app that I don't need to worry about.
I'm fairly sure the main thing to take away is to set url and urlRoot dynamically
I would fulfill the accepted answer with few remarks.
First parameter when initializing Backbone.Collection is array of models, then options. To create an empty collection with options you should do next
var c = new Backbone.Collection(null, {opt1: val1, opt2: val2});
Actually, you can't access this.options in url function, bec. there are no options like in a model. What you can do, is assign required properties from options upon initialization.
initialize: function (models, options) {
// `parseInt()` is used for consistency that `id` is numeric, just to be sure
this.detail_userid = parseInt(options.detail_userid);
this.detail_contactid = parseInt(options.detail_contactid);
}
Later you can access them like this:
url: function() {
return URL_CONTACTS1 + this.detail_userid + "/" + this.detail_contactid;
}
I wanted to use the HATEOAS href from one model to fetch data of another model. It worked to simply set the url on the newly created collection instead of defining it right away in the constructor.
var DailyMeasuresCollection = Backbone.Collection.extend({
//url : set dynamically with collection.url = url
model : DailyMeasuresModel,
parse : function(data) {
return data._embedded.dailyMeasures;
}
});
var DailyMeasuresTopicListItemView = Backbone.View.extend({
//...
events : {
'click .select-topic' : 'onClick'
},
onClick : function() {
var topicMeasures = new DailyMeasuresCollection()
topicMeasures.url = this.model.attributes._links.measures.href // <- here assign
var topicMeasuresView = new DailyMeasuresListView({
collection : topicMeasures
});
topicMeasures.fetch()
}
});

MonoTouch.Dialog - How to get values out of element UI

I have a RootElement declared and set up how I want on a DialogViewController, using the element-based API rather than the reflection API. Looks great.
However I'm struggling to work out how I can get the values out. Using the reflection-based API this is easy, but I don't see how I can use BindingContext.Fetch() with an explicitly declared RootElement.
I can't find an example in the samples, nor can I work out how to do this myself.
var root = new RootElement(null){
new Section(){
new StringElement("Title here"),
new FloatElement(null, null, 5f)
}
};
var dv = new DialogViewController(root, true);
dv.ViewDisappearing += delegate {
// what goes here to get at the value of the FloatElement?
};
NavigationController.PushViewController(dv, true);
Any help appreciated.
You can store it in a variable, that is scoped where your anonymous method can access it.
Like this:
var floatElement = new FloatElement(null, null, 5f);
var root = new RootElement(null){
new Section(){
new StringElement("Title here"),
floatElement,
}
};
var dv = new DialogViewController(root, true);
dv.ViewDisappearing += delegate {
//You can access floatElement here
Console.WriteLine(floatElement.Value);
};
NavigationController.PushViewController(dv, true);

Resources