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);
Related
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
});
}
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.
I am using MVC 4 and have an #HTML.DropdownlistFor() which loads the rest of the page based on it's selection. On change of the listbox, I want to reload the page so that it load the correct data. As well there are two other parameters that are needed to load the page correctly.
In Create.cshtml view
#Html.DropDownListFor(model => model.SelectedMissionID, Model.MissionsToDisplay, new { onchange = "ReloadPage();" })
function ReloadPage() {
window.location = '#Html.Raw(Url.Action("CreateEdit", "DailyLog", new { ID = 1, ID2 = 0, dailyLogDate = Model.LogDate }))';
}
Where it says ID = 1, I want the selected index of the DropdownlistFor(SelectedMissionID), how do I get this?
I'm not sure if this is the best way to go to the controller, or if I should use a JQUERY .ajax post, is there a better way?
I seems something ideal for an ajax post.
What you have done is OK, inside the ReloadPage() function, just get the selected value in the DropDown, do the Ajax call passing the parameters, and in the success callback put your returned HTML in some container.
The idea is that you replace a part of your view with the return of your Ajax call, not all the page.
To get the selected value, using jQuery:
var selectedValue = $("select[name='SelectedMissionID']").val();
And that can be placed in your ReloadPage() function.
$.post( "your action URL", { ID: selectedValue, OtherParam: "xxxxx" })
.done(function( data ) {
alert( "Data Loaded: " + data );
//here you need to get the HTML, and put in a container
});
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.
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);